[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