Skip to content

Commit

Permalink
fs: dcache scale dentry refcount
Browse files Browse the repository at this point in the history
Make d_count non-atomic and protect it with d_lock. This allows us to ensure a
0 refcount dentry remains 0 without dcache_lock. It is also fairly natural when
we start protecting many other dentry members with d_lock.

Signed-off-by: Nick Piggin <npiggin@kernel.dk>
  • Loading branch information
Nick Piggin committed Jan 7, 2011
1 parent 2304450 commit b7ab39f
Show file tree
Hide file tree
Showing 21 changed files with 126 additions and 69 deletions.
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/cell/spufs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ static void spufs_prune_dir(struct dentry *dir)
spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock);
if (!(d_unhashed(dentry)) && dentry->d_inode) {
dget_locked(dentry);
dget_locked_dlock(dentry);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
simple_unlink(dir->d_inode, dentry);
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/ipath/ipath_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ static int remove_file(struct dentry *parent, char *name)
spin_lock(&dcache_lock);
spin_lock(&tmp->d_lock);
if (!(d_unhashed(tmp) && tmp->d_inode)) {
dget_locked(tmp);
dget_locked_dlock(tmp);
__d_drop(tmp);
spin_unlock(&tmp->d_lock);
spin_unlock(&dcache_lock);
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/qib/qib_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ static int remove_file(struct dentry *parent, char *name)
spin_lock(&dcache_lock);
spin_lock(&tmp->d_lock);
if (!(d_unhashed(tmp) && tmp->d_inode)) {
dget_locked(tmp);
dget_locked_dlock(tmp);
__d_drop(tmp);
spin_unlock(&tmp->d_lock);
spin_unlock(&dcache_lock);
Expand Down
8 changes: 4 additions & 4 deletions fs/autofs4/expire.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
else
ino_count++;

if (atomic_read(&p->d_count) > ino_count) {
if (p->d_count > ino_count) {
top_ino->last_used = jiffies;
dput(p);
return 1;
Expand Down Expand Up @@ -347,7 +347,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,

/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 2;
if (atomic_read(&dentry->d_count) > ino_count)
if (dentry->d_count > ino_count)
goto next;

/* Can we umount this guy */
Expand All @@ -369,7 +369,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
if (!exp_leaves) {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
if (atomic_read(&dentry->d_count) > ino_count)
if (dentry->d_count > ino_count)
goto next;

if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
Expand All @@ -383,7 +383,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
} else {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
if (atomic_read(&dentry->d_count) > ino_count)
if (dentry->d_count > ino_count)
goto next;

expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
Expand Down
6 changes: 3 additions & 3 deletions fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
spin_lock(&active->d_lock);

/* Already gone? */
if (atomic_read(&active->d_count) == 0)
if (active->d_count == 0)
goto next;

qstr = &active->d_name;
Expand All @@ -452,7 +452,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
goto next;

if (d_unhashed(active)) {
dget(active);
dget_dlock(active);
spin_unlock(&active->d_lock);
spin_unlock(&sbi->lookup_lock);
spin_unlock(&dcache_lock);
Expand Down Expand Up @@ -507,7 +507,7 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)
goto next;

if (d_unhashed(expiring)) {
dget(expiring);
dget_dlock(expiring);
spin_unlock(&expiring->d_lock);
spin_unlock(&sbi->lookup_lock);
spin_unlock(&dcache_lock);
Expand Down
4 changes: 3 additions & 1 deletion fs/ceph/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ static int __dcache_readdir(struct file *filp,
di = ceph_dentry(dentry);
}

atomic_inc(&dentry->d_count);
spin_lock(&dentry->d_lock);
dentry->d_count++;
spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock);

dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos,
Expand Down
4 changes: 2 additions & 2 deletions fs/ceph/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -879,8 +879,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
} else if (realdn) {
dout("dn %p (%d) spliced with %p (%d) "
"inode %p ino %llx.%llx\n",
dn, atomic_read(&dn->d_count),
realdn, atomic_read(&realdn->d_count),
dn, dn->d_count,
realdn, realdn->d_count,
realdn->d_inode, ceph_vinop(realdn->d_inode));
dput(dn);
dn = realdn;
Expand Down
2 changes: 1 addition & 1 deletion fs/ceph/mds_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1486,7 +1486,7 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
*base = ceph_ino(temp->d_inode);
*plen = len;
dout("build_path on %p %d built %llx '%.*s'\n",
dentry, atomic_read(&dentry->d_count), *base, len, path);
dentry, dentry->d_count, *base, len, path);
return path;
}

Expand Down
2 changes: 1 addition & 1 deletion fs/coda/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
if (cii->c_flags & C_FLUSH)
coda_flag_inode_children(inode, C_FLUSH);

if (atomic_read(&de->d_count) > 1)
if (de->d_count > 1)
/* pretend it's valid, but don't change the flags */
goto out;

Expand Down
3 changes: 1 addition & 2 deletions fs/configfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,7 @@ static void remove_dir(struct dentry * d)
if (d->d_inode)
simple_rmdir(parent->d_inode,d);

pr_debug(" o %s removing done (%d)\n",d->d_name.name,
atomic_read(&d->d_count));
pr_debug(" o %s removing done (%d)\n",d->d_name.name, d->d_count);

dput(parent);
}
Expand Down
2 changes: 1 addition & 1 deletion fs/configfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock);
if (!(d_unhashed(dentry) && dentry->d_inode)) {
dget_locked(dentry);
dget_locked_dlock(dentry);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock);
Expand Down
Loading

0 comments on commit b7ab39f

Please sign in to comment.