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

pick_link(): take reserving space on stack into a new helper



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent aef9404d
Loading
Loading
Loading
Loading
+25 −21
Original line number Diff line number Diff line
@@ -1580,22 +1580,15 @@ static inline int may_lookup(struct nameidata *nd)
	return inode_permission(nd->inode, MAY_EXEC);
}

enum {WALK_TRAILING = 1, WALK_MORE = 2, WALK_NOFOLLOW = 4};

static const char *pick_link(struct nameidata *nd, struct path *link,
		     struct inode *inode, unsigned seq, int flags)
static int reserve_stack(struct nameidata *nd, struct path *link, unsigned seq)
{
	struct saved *last;
	const char *res;
	int error;

	if (unlikely(nd->total_link_count++ >= MAXSYMLINKS)) {
		if (!(nd->flags & LOOKUP_RCU))
			path_put(link);
		return ERR_PTR(-ELOOP);
	}
	if (unlikely(nd->total_link_count++ >= MAXSYMLINKS))
		return -ELOOP;
	error = nd_alloc_stack(nd);
	if (unlikely(error)) {
	if (likely(!error))
		return 0;
	if (error == -ECHILD) {
		// we must grab link first
		bool grabbed_link = legitimize_path(nd, link, seq);
@@ -1606,12 +1599,23 @@ static const char *pick_link(struct nameidata *nd, struct path *link,
		if (!error)
			error = nd_alloc_stack(nd);
	}
		if (error) {
	return error;
}

enum {WALK_TRAILING = 1, WALK_MORE = 2, WALK_NOFOLLOW = 4};

static const char *pick_link(struct nameidata *nd, struct path *link,
		     struct inode *inode, unsigned seq, int flags)
{
	struct saved *last;
	const char *res;
	int error = reserve_stack(nd, link, seq);

	if (unlikely(error)) {
		if (!(nd->flags & LOOKUP_RCU))
			path_put(link);
		return ERR_PTR(error);
	}
	}

	last = nd->stack + nd->depth++;
	last->link = *link;
	clear_delayed_call(&last->done);