diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 17:49:33 +1100 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 17:50:21 +1100 |
commit | da5029563a0a026c64821b09e8e7b4fd81d3fe1b (patch) | |
tree | 5d5618e0cb382390073377b1be7d0aa76879ac54 /fs/autofs4/expire.c | |
parent | b7ab39f631f505edc2bbdb86620d5493f995c9da (diff) |
fs: dcache scale d_unhashed
Protect d_unhashed(dentry) condition with d_lock. This means keeping
DCACHE_UNHASHED bit in synch with hash manipulations.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'fs/autofs4/expire.c')
-rw-r--r-- | fs/autofs4/expire.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 413b5642e6c..ee6402050f1 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -160,14 +160,18 @@ static int autofs4_tree_busy(struct vfsmount *mnt, spin_lock(&dcache_lock); for (p = top; p; p = next_dentry(p, top)) { + spin_lock(&p->d_lock); /* Negative dentry - give up */ - if (!simple_positive(p)) + if (!simple_positive(p)) { + spin_unlock(&p->d_lock); continue; + } DPRINTK("dentry %p %.*s", p, (int) p->d_name.len, p->d_name.name); - p = dget(p); + p = dget_dlock(p); + spin_unlock(&p->d_lock); spin_unlock(&dcache_lock); /* @@ -228,14 +232,18 @@ static struct dentry *autofs4_check_leaves(struct vfsmount *mnt, spin_lock(&dcache_lock); for (p = parent; p; p = next_dentry(p, parent)) { + spin_lock(&p->d_lock); /* Negative dentry - give up */ - if (!simple_positive(p)) + if (!simple_positive(p)) { + spin_unlock(&p->d_lock); continue; + } DPRINTK("dentry %p %.*s", p, (int) p->d_name.len, p->d_name.name); - p = dget(p); + p = dget_dlock(p); + spin_unlock(&p->d_lock); spin_unlock(&dcache_lock); if (d_mountpoint(p)) { @@ -324,12 +332,15 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child); /* Negative dentry - give up */ + spin_lock(&dentry->d_lock); if (!simple_positive(dentry)) { next = next->next; + spin_unlock(&dentry->d_lock); continue; } - dentry = dget(dentry); + dentry = dget_dlock(dentry); + spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); spin_lock(&sbi->fs_lock); |