Commit 01a4428e authored by Al Viro's avatar Al Viro
Browse files

d_path: lift -ENAMETOOLONG handling into callers of prepend_path()



The only negative value ever returned by prepend_path() is -ENAMETOOLONG
and callers can recognize that situation (overflow) by looking at the
sign of buflen.  Lift that into the callers; we already have the
same logics (buf if buflen is non-negative, ERR_PTR(-ENAMETOOLONG) otherwise)
in several places and that'll become a new primitive several commits down
the road.

Make prepend_path() return 0 instead of -ENAMETOOLONG.  That makes for
saner calling conventions (0/1/2/3/-ENAMETOOLONG is obnoxious) and
callers actually get simpler, especially once the aforementioned
primitive gets added.

In prepend_path() itself we switch prepending the / (in case of
empty path) to use of prepend() - no need to open-code that, compiler
will do the right thing.  It's exactly the same logics as in
__dentry_path().

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent d8548232
Loading
Loading
Loading
Loading
+11 −28
Original line number Diff line number Diff line
@@ -127,8 +127,7 @@ static int prepend_path(const struct path *path,
		}
		parent = dentry->d_parent;
		prefetch(parent);
		error = prepend_name(&bptr, &blen, &dentry->d_name);
		if (error)
		if (unlikely(prepend_name(&bptr, &blen, &dentry->d_name) < 0))
			break;

		dentry = parent;
@@ -149,12 +148,9 @@ static int prepend_path(const struct path *path,
	}
	done_seqretry(&mount_lock, m_seq);

	if (error >= 0 && bptr == *buffer) {
		if (--blen < 0)
			error = -ENAMETOOLONG;
		else
			*--bptr = '/';
	}
	if (blen == *buflen)
		prepend(&bptr, &blen, "/", 1);

	*buffer = bptr;
	*buflen = blen;
	return error;
@@ -181,16 +177,11 @@ char *__d_path(const struct path *path,
	       char *buf, int buflen)
{
	char *res = buf + buflen;
	int error;

	prepend(&res, &buflen, "", 1);
	error = prepend_path(path, root, &res, &buflen);

	if (error < 0)
		return ERR_PTR(error);
	if (error > 0)
	if (prepend_path(path, root, &res, &buflen) > 0)
		return NULL;
	return res;
	return buflen >= 0 ? res : ERR_PTR(-ENAMETOOLONG);
}

char *d_absolute_path(const struct path *path,
@@ -198,16 +189,11 @@ char *d_absolute_path(const struct path *path,
{
	struct path root = {};
	char *res = buf + buflen;
	int error;

	prepend(&res, &buflen, "", 1);
	error = prepend_path(path, &root, &res, &buflen);

	if (error > 1)
		error = -EINVAL;
	if (error < 0)
		return ERR_PTR(error);
	return res;
	if (prepend_path(path, &root, &res, &buflen) > 1)
		return ERR_PTR(-EINVAL);
	return buflen >= 0 ? res : ERR_PTR(-ENAMETOOLONG);
}

static void get_fs_root_rcu(struct fs_struct *fs, struct path *root)
@@ -240,7 +226,6 @@ char *d_path(const struct path *path, char *buf, int buflen)
{
	char *res = buf + buflen;
	struct path root;
	int error;

	/*
	 * We have various synthetic filesystems that never get mounted.  On
@@ -263,12 +248,10 @@ char *d_path(const struct path *path, char *buf, int buflen)
		prepend(&res, &buflen, " (deleted)", 11);
	else
		prepend(&res, &buflen, "", 1);
	error = prepend_path(path, &root, &res, &buflen);
	prepend_path(path, &root, &res, &buflen);
	rcu_read_unlock();

	if (error < 0)
		res = ERR_PTR(error);
	return res;
	return buflen >= 0 ? res : ERR_PTR(-ENAMETOOLONG);
}
EXPORT_SYMBOL(d_path);