Commit 3188b295 authored by NeilBrown's avatar NeilBrown Committed by Al Viro
Browse files

ovl: rearrange ovl_follow_link to it doesn't need to call ->put_link



ovl_follow_link current calls ->put_link on an error path.
However ->put_link is about to change in a way that it will be
impossible to call it from ovl_follow_link.

So rearrange the code to avoid the need for that error path.
Specifically: move the kmalloc() call before the ->follow_link()
call to the subordinate filesystem.

Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 90e4fc88
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
	void *ret;
	struct dentry *realdentry;
	struct inode *realinode;
	struct ovl_link_data *data = NULL;

	realdentry = ovl_dentry_real(dentry);
	realinode = realdentry->d_inode;
@@ -152,25 +153,23 @@ static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
	if (WARN_ON(!realinode->i_op->follow_link))
		return ERR_PTR(-EPERM);

	ret = realinode->i_op->follow_link(realdentry, nd);
	if (IS_ERR(ret))
		return ret;

	if (realinode->i_op->put_link) {
		struct ovl_link_data *data;

		data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL);
		if (!data) {
			realinode->i_op->put_link(realdentry, nd, ret);
		if (!data)
			return ERR_PTR(-ENOMEM);
		}
		data->realdentry = realdentry;
	}

	ret = realinode->i_op->follow_link(realdentry, nd);
	if (IS_ERR(ret)) {
		kfree(data);
		return ret;
	}

	if (data)
		data->cookie = ret;

	return data;
	} else {
		return NULL;
	}
}

static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c)