[PATCH 3/4] vfs: Move the call of d_op->d_dname from d_path to prepend_path

Eric W. Biederman ebiederm at xmission.com
Fri Feb 7 02:24:27 UTC 2014


For clarity move the call of d_dname from d_path into prepend_path.
There are only 4 callers of prepend_path and this change does not
affect the results returned by any of them.  d_absolute_path
and __d_path return an error and ignore the output of prepend_path
error == 2. getcwd only operates on directories and all of the
implementations of d_dname are on files.

For d_path the argument of no changes in output is a little trickier.
path_with_deleted does not trigger because pseudo dentries are match
IS_ROOT so is_unlinked is false.  All of current implementations of
d_dname are files so they are not currently anyone's d_parent, which
means today that either the first iteration of prepend_path will call
d_dname or none of the iterations of prepend_path will call d_dname.

d_dname is called from the while loop in prepend_path so that if it
happens in the future that any of the implementors of d_dname are a
directory instead of a file then prepend_path will work properly on them.

Signed-off-by: "Eric W. Biederman" <ebiederm at xmission.com>
---
 fs/dcache.c |   32 +++++++++++++++++++++-----------
 1 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/fs/dcache.c b/fs/dcache.c
index c250d97befe4..c5c7847ff84b 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2892,6 +2892,27 @@ restart:
 	while (dentry != root->dentry || vfsmnt != root->mnt) {
 		struct dentry * parent;
 
+		/*
+		 * We have various synthetic files allocated with
+		 * d_alloc_pseudo that are not available through
+		 * ordinary path lookup and don't need a name until
+		 * a user wants to identify the object in
+		 * /proc/pid/fd/ or similiar.
+		 */
+		if (IS_ROOT(dentry) && dentry != vfsmnt->mnt_root &&
+		    dentry->d_op && dentry->d_op->d_dname) {
+			char *buf  = bptr - blen;
+			char *name = dentry->d_op->d_dname(dentry, buf, blen);
+			if (IS_ERR(name)) {
+				error = PTR_ERR(name);
+				break;
+			}
+			blen = name - buf;
+			bptr = name;
+			error = 2; /* unmounted by definition */
+			break;
+		}
+
 		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
 			struct mount *parent = ACCESS_ONCE(mnt->mnt_parent);
 			/* Global root? */
@@ -3055,17 +3076,6 @@ char *d_path(const struct path *path, char *buf, int buflen)
 	struct path root;
 	int error;
 
-	/*
-	 * We have various synthetic files allocated with
-	 * d_alloc_pseudo that are not available through
-	 * ordinary path lookup and don't need a name until
-	 * a user wants to identify the object in
-	 * /proc/pid/fd/ or similiar.
-	 */
-	if (path->dentry->d_op && path->dentry->d_op->d_dname &&
-	    IS_ROOT(path->dentry) && path->dentry != path->mnt->mnt_root)
-		return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
-
 	rcu_read_lock();
 	get_fs_root_rcu(current->fs, &root);
 	error = path_with_deleted(path, &root, &res, &buflen);
-- 
1.7.5.4



More information about the Containers mailing list