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

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

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: default avatarNick Piggin <npiggin@kernel.dk>
parent b7ab39f6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ static void spufs_prune_dir(struct dentry *dir)
			__d_drop(dentry);
			spin_unlock(&dentry->d_lock);
			simple_unlink(dir->d_inode, dentry);
			/* XXX: what is dcache_lock protecting here? Other
			 * filesystems (IB, configfs) release dcache_lock
			 * before unlink */
			spin_unlock(&dcache_lock);
			dput(dentry);
		} else {
+3 −0
Original line number Diff line number Diff line
@@ -347,10 +347,13 @@ static int usbfs_empty (struct dentry *dentry)

	list_for_each(list, &dentry->d_subdirs) {
		struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
		spin_lock(&de->d_lock);
		if (usbfs_positive(de)) {
			spin_unlock(&de->d_lock);
			spin_unlock(&dcache_lock);
			return 0;
		}
		spin_unlock(&de->d_lock);
	}

	spin_unlock(&dcache_lock);
+0 −13
Original line number Diff line number Diff line
@@ -254,19 +254,6 @@ static inline int simple_positive(struct dentry *dentry)
	return dentry->d_inode && !d_unhashed(dentry);
}

static inline int __simple_empty(struct dentry *dentry)
{
	struct dentry *child;
	int ret = 0;

	list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
		if (simple_positive(child))
			goto out;
	ret = 1;
out:
	return ret;
}

static inline void autofs4_add_expiring(struct dentry *dentry)
{
	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
+16 −5
Original line number Diff line number Diff line
@@ -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);
+3 −2
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ more:
			fi->at_end = 1;
			goto out_unlock;
		}
		spin_lock(&dentry->d_lock);
		if (!d_unhashed(dentry) && dentry->d_inode &&
		    ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
		    ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
@@ -145,13 +146,13 @@ more:
		     dentry->d_name.len, dentry->d_name.name, di->offset,
		     filp->f_pos, d_unhashed(dentry) ? " unhashed" : "",
		     !dentry->d_inode ? " null" : "");
		spin_unlock(&dentry->d_lock);
		p = p->prev;
		dentry = list_entry(p, struct dentry, d_u.d_child);
		di = ceph_dentry(dentry);
	}

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

Loading