Commit fcaac5b4 authored by Al Viro's avatar Al Viro
Browse files

fuse_ctl: use simple_recursive_removal()



easier that way - no need to keep that array of dentry references, etc.

Reviewed-by: default avatarChristian Brauner <brauner@kernel.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 7b7a8ca4
Loading
Loading
Loading
Loading
+13 −17
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs_context.h>
#include <linux/namei.h>

#define FUSE_CTL_SUPER_MAGIC 0x65735543

@@ -212,7 +213,6 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
	struct dentry *dentry;
	struct inode *inode;

	BUG_ON(fc->ctl_ndents >= FUSE_CTL_NUM_DENTRIES);
	dentry = d_alloc_name(parent, name);
	if (!dentry)
		return NULL;
@@ -236,8 +236,6 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
	inode->i_private = fc;
	d_add(dentry, inode);

	fc->ctl_dentry[fc->ctl_ndents++] = dentry;

	return dentry;
}

@@ -280,27 +278,29 @@ int fuse_ctl_add_conn(struct fuse_conn *fc)
	return -ENOMEM;
}

static void remove_one(struct dentry *dentry)
{
	d_inode(dentry)->i_private = NULL;
}

/*
 * Remove a connection from the control filesystem (if it exists).
 * Caller must hold fuse_mutex
 */
void fuse_ctl_remove_conn(struct fuse_conn *fc)
{
	int i;
	struct dentry *dentry;
	char name[32];

	if (!fuse_control_sb || fc->no_control)
		return;

	for (i = fc->ctl_ndents - 1; i >= 0; i--) {
		struct dentry *dentry = fc->ctl_dentry[i];
		d_inode(dentry)->i_private = NULL;
		if (!i) {
			/* Get rid of submounts: */
			d_invalidate(dentry);
		}
		dput(dentry);
	sprintf(name, "%u", fc->dev);
	dentry = lookup_noperm_positive_unlocked(&QSTR(name), fuse_control_sb->s_root);
	if (!IS_ERR(dentry)) {
		simple_recursive_removal(dentry, remove_one);
		dput(dentry);	// paired with lookup_noperm_positive_unlocked()
	}
	drop_nlink(d_inode(fuse_control_sb->s_root));
}

static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fsc)
@@ -346,12 +346,8 @@ static int fuse_ctl_init_fs_context(struct fs_context *fsc)

static void fuse_ctl_kill_sb(struct super_block *sb)
{
	struct fuse_conn *fc;

	mutex_lock(&fuse_mutex);
	fuse_control_sb = NULL;
	list_for_each_entry(fc, &fuse_conn_list, entry)
		fc->ctl_ndents = 0;
	mutex_unlock(&fuse_mutex);

	kill_litter_super(sb);
+0 −6
Original line number Diff line number Diff line
@@ -913,12 +913,6 @@ struct fuse_conn {
	/** Device ID from the root super block */
	dev_t dev;

	/** Dentries in the control filesystem */
	struct dentry *ctl_dentry[FUSE_CTL_NUM_DENTRIES];

	/** number of dentries used in the above array */
	int ctl_ndents;

	/** Key for lock owner ID scrambling */
	u32 scramble_key[4];