Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7ab39f6 authored by Nick Piggin's avatar Nick Piggin
Browse files

fs: dcache scale dentry refcount



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: default avatarNick Piggin <npiggin@kernel.dk>
parent 23044507
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -162,7 +162,7 @@ static void spufs_prune_dir(struct dentry *dir)
		spin_lock(&dcache_lock);
		spin_lock(&dcache_lock);
		spin_lock(&dentry->d_lock);
		spin_lock(&dentry->d_lock);
		if (!(d_unhashed(dentry)) && dentry->d_inode) {
		if (!(d_unhashed(dentry)) && dentry->d_inode) {
			dget_locked(dentry);
			dget_locked_dlock(dentry);
			__d_drop(dentry);
			__d_drop(dentry);
			spin_unlock(&dentry->d_lock);
			spin_unlock(&dentry->d_lock);
			simple_unlink(dir->d_inode, dentry);
			simple_unlink(dir->d_inode, dentry);
+1 −1
Original line number Original line Diff line number Diff line
@@ -280,7 +280,7 @@ static int remove_file(struct dentry *parent, char *name)
	spin_lock(&dcache_lock);
	spin_lock(&dcache_lock);
	spin_lock(&tmp->d_lock);
	spin_lock(&tmp->d_lock);
	if (!(d_unhashed(tmp) && tmp->d_inode)) {
	if (!(d_unhashed(tmp) && tmp->d_inode)) {
		dget_locked(tmp);
		dget_locked_dlock(tmp);
		__d_drop(tmp);
		__d_drop(tmp);
		spin_unlock(&tmp->d_lock);
		spin_unlock(&tmp->d_lock);
		spin_unlock(&dcache_lock);
		spin_unlock(&dcache_lock);
+1 −1
Original line number Original line Diff line number Diff line
@@ -456,7 +456,7 @@ static int remove_file(struct dentry *parent, char *name)
	spin_lock(&dcache_lock);
	spin_lock(&dcache_lock);
	spin_lock(&tmp->d_lock);
	spin_lock(&tmp->d_lock);
	if (!(d_unhashed(tmp) && tmp->d_inode)) {
	if (!(d_unhashed(tmp) && tmp->d_inode)) {
		dget_locked(tmp);
		dget_locked_dlock(tmp);
		__d_drop(tmp);
		__d_drop(tmp);
		spin_unlock(&tmp->d_lock);
		spin_unlock(&tmp->d_lock);
		spin_unlock(&dcache_lock);
		spin_unlock(&dcache_lock);
+4 −4
Original line number Original line Diff line number Diff line
@@ -198,7 +198,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
			else
			else
				ino_count++;
				ino_count++;


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


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


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


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


			expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
			expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
+3 −3
Original line number Original line Diff line number Diff line
@@ -436,7 +436,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
		spin_lock(&active->d_lock);
		spin_lock(&active->d_lock);


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


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


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


		if (d_unhashed(expiring)) {
		if (d_unhashed(expiring)) {
			dget(expiring);
			dget_dlock(expiring);
			spin_unlock(&expiring->d_lock);
			spin_unlock(&expiring->d_lock);
			spin_unlock(&sbi->lookup_lock);
			spin_unlock(&sbi->lookup_lock);
			spin_unlock(&dcache_lock);
			spin_unlock(&dcache_lock);
Loading