mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 13:38:01 +00:00
linux26-vcache-reclaim-cleanup-20050119
"ok, if you ever drop dcache_lock you need to go to restart (i think that's pretty clear). shrink_dcache_parent() _might_ reduce a dentry count to 0. in the previous version, it seemed to make the assumption that this would always happen. if shrink_dcache_parent() is unsuccessful and the dentry is a directory, we cant restart. we would just find the the dentry again and do the same thing over (we could always d_drop but you shouldnt do this to active directories -- see d_invalidate). if we find a busy dentry, we abort all processing for this inode. going back to restart would find the same busy inode. (i suppose we could use a d_flag to keep track of which dentry has been shrunk. this has other trouble, like who resets the flag and when?) since we only do this for directories and d_alias typically only grows due to soft/hard links (as far as i can tell) this scheme seems reasonable."
This commit is contained in:
parent
8ccd2d91d8
commit
73437ee7d4
@ -844,20 +844,44 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
|
||||
struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry;
|
||||
AFS_FAST_HOLD(tvc);
|
||||
AFS_GUNLOCK();
|
||||
shrink_restart:
|
||||
DLOCK();
|
||||
cur=head;
|
||||
|
||||
restart:
|
||||
spin_lock(&dcache_lock);
|
||||
cur = head;
|
||||
while ((cur = cur->next) != head) {
|
||||
dentry = list_entry(cur, struct dentry, d_alias);
|
||||
if (!d_unhashed(dentry) &&
|
||||
!list_empty(&dentry->d_subdirs)) {
|
||||
|
||||
if (d_unhashed(dentry))
|
||||
continue;
|
||||
|
||||
dget_locked(dentry);
|
||||
|
||||
if (!list_empty(&dentry->d_subdirs)) {
|
||||
DUNLOCK();
|
||||
shrink_dcache_parent(dentry);
|
||||
goto shrink_restart;
|
||||
DLOCK();
|
||||
}
|
||||
|
||||
spin_lock(&dentry->d_lock);
|
||||
if (atomic_read(&dentry->d_count) > 1) {
|
||||
if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
|
||||
spin_unlock(&dentry->d_lock);
|
||||
spin_unlock(&dcache_lock);
|
||||
dput(dentry);
|
||||
goto inuse;
|
||||
}
|
||||
}
|
||||
|
||||
__d_drop(dentry);
|
||||
spin_unlock(&dentry->d_lock);
|
||||
spin_unlock(&dcache_lock);
|
||||
dput(dentry);
|
||||
goto restart;
|
||||
|
||||
}
|
||||
DUNLOCK();
|
||||
d_prune_aliases(AFSTOI(tvc));
|
||||
inuse:
|
||||
|
||||
AFS_GLOCK();
|
||||
AFS_FAST_RELE(tvc);
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user