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@xxxxxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html