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

fuse_ctl_add_conn(): fix nlink breakage in case of early failure



fuse_ctl_remove_conn() used to decrement the link count of root
manually; that got subsumed by simple_recursive_removal(), but
in case when subdirectory creation has failed the latter won't
get called.

Just move the modification of parent's link count into
fuse_ctl_add_dentry() to keep the things simple.  Allows to
get rid of the nlink argument as well...

Fixes: fcaac5b4 "fuse_ctl: use simple_recursive_removal()"
Acked-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent e9a6fb0b
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -205,8 +205,7 @@ static const struct file_operations fuse_conn_congestion_threshold_ops = {

static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
					  struct fuse_conn *fc,
					  const char *name,
					  int mode, int nlink,
					  const char *name, int mode,
					  const struct inode_operations *iop,
					  const struct file_operations *fop)
{
@@ -232,7 +231,10 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
	if (iop)
		inode->i_op = iop;
	inode->i_fop = fop;
	set_nlink(inode, nlink);
	if (S_ISDIR(mode)) {
		inc_nlink(d_inode(parent));
		inc_nlink(inode);
	}
	inode->i_private = fc;
	d_add(dentry, inode);

@@ -252,22 +254,21 @@ int fuse_ctl_add_conn(struct fuse_conn *fc)
		return 0;

	parent = fuse_control_sb->s_root;
	inc_nlink(d_inode(parent));
	sprintf(name, "%u", fc->dev);
	parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2,
	parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500,
				     &simple_dir_inode_operations,
				     &simple_dir_operations);
	if (!parent)
		goto err;

	if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, 1,
	if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400,
				 NULL, &fuse_ctl_waiting_ops) ||
	    !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, 1,
	    !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200,
				 NULL, &fuse_ctl_abort_ops) ||
	    !fuse_ctl_add_dentry(parent, fc, "max_background", S_IFREG | 0600,
				 1, NULL, &fuse_conn_max_background_ops) ||
				 NULL, &fuse_conn_max_background_ops) ||
	    !fuse_ctl_add_dentry(parent, fc, "congestion_threshold",
				 S_IFREG | 0600, 1, NULL,
				 S_IFREG | 0600, NULL,
				 &fuse_conn_congestion_threshold_ops))
		goto err;