Hi Al, Could you please consider these patches for 2.6.36? Thanks, Miklos On Fri, 04 Jun 2010, Miklos Szeredi wrote: > From: Miklos Szeredi <mszeredi@xxxxxxx> > > Prepend "(unreachable)" to path strings if the path is not reachable > from the current root. > > Two places updated are > - the return string from getcwd() > - and symlinks under /proc/$PID. > > Other uses of d_path() are left unchanged (we know that some old > software crashes if /proc/mounts is changed). > > Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxx> > --- > fs/dcache.c | 82 +++++++++++++++++++++++++++++++++++++++++-------- > fs/proc/base.c | 2 - > include/linux/dcache.h | 1 > 3 files changed, 72 insertions(+), 13 deletions(-) > > Index: linux-2.6/fs/dcache.c > =================================================================== > --- linux-2.6.orig/fs/dcache.c 2010-05-27 12:22:21.000000000 +0200 > +++ linux-2.6/fs/dcache.c 2010-05-27 12:22:24.000000000 +0200 > @@ -1957,6 +1957,33 @@ int __d_path(const struct path *path, st > return error; > } > > +static void current_root(struct path *root) > +{ > + read_lock(¤t->fs->lock); > + *root = current->fs->root; > + path_get(root); > + read_unlock(¤t->fs->lock); > +} > + > +static int __d_path_with_deleted(const struct path *path, struct path *root, > + char **buffer, int *buflen) > +{ > + int error; > + > + prepend(buffer, buflen, "\0", 1); > + if (d_unlinked(path->dentry)) { > + error = prepend(buffer, buflen, " (deleted)", 10); > + if (error) > + return error; > + } > + return __d_path(path, root, buffer, buflen); > +} > + > +static int prepend_unreachable(char **buffer, int *buflen) > +{ > + return prepend(buffer, buflen, "(unreachable)", 13); > +} > + > /** > * d_path - return the path of a dentry > * @path: path to report > @@ -1990,27 +2017,51 @@ char *d_path(const struct path *path, ch > if (path->dentry->d_op && path->dentry->d_op->d_dname) > return path->dentry->d_op->d_dname(path->dentry, buf, buflen); > > - read_lock(¤t->fs->lock); > - root = current->fs->root; > - path_get(&root); > - read_unlock(¤t->fs->lock); > + current_root(&root); > spin_lock(&dcache_lock); > ptr = buf + buflen; > - prepend(&ptr, &buflen, "\0", 1); > - if (d_unlinked(path->dentry)) { > - error = prepend(&ptr, &buflen, " (deleted)", 10); > - if (error) > - goto out; > - } > tmp = root; > - error = __d_path(path, &tmp, &ptr, &buflen); > -out: > + error = __d_path_with_deleted(path, &tmp, &ptr, &buflen); > spin_unlock(&dcache_lock); > path_put(&root); > return error ? ERR_PTR(error) : ptr; > } > EXPORT_SYMBOL(d_path); > > +/** > + * d_path_with_unreachable - return the path of a dentry > + * @path: path to report > + * @buf: buffer to return value in > + * @buflen: buffer length > + * > + * The difference from d_path() is that this prepends "(unreachable)" > + * to paths which are unreachable from the current process' root. > + */ > +char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) > +{ > + char *ptr; > + struct path root; > + struct path tmp; > + int error; > + > + if (path->dentry->d_op && path->dentry->d_op->d_dname) > + return path->dentry->d_op->d_dname(path->dentry, buf, buflen); > + > + current_root(&root); > + spin_lock(&dcache_lock); > + ptr = buf + buflen; > + tmp = root; > + error = __d_path_with_deleted(path, &tmp, &ptr, &buflen); > + if (!error) { > + if (tmp.dentry != root.dentry || tmp.mnt != root.mnt) > + error = prepend_unreachable(&ptr, &buflen); > + } > + > + spin_unlock(&dcache_lock); > + path_put(&root); > + return error ? ERR_PTR(error) : ptr; > +} > + > /* > * Helper function for dentry_operations.d_dname() members > */ > @@ -2118,6 +2169,13 @@ SYSCALL_DEFINE2(getcwd, char __user *, b > if (error) > goto out; > > + /* Unreachable from current root */ > + if (tmp.dentry != root.dentry || tmp.mnt != root.mnt) { > + error = prepend_unreachable(&cwd, &buflen); > + if (error) > + goto out; > + } > + > error = -ERANGE; > len = PAGE_SIZE + page - cwd; > if (len <= size) { > Index: linux-2.6/include/linux/dcache.h > =================================================================== > --- linux-2.6.orig/include/linux/dcache.h 2010-05-27 12:13:48.000000000 +0200 > +++ linux-2.6/include/linux/dcache.h 2010-05-27 12:22:24.000000000 +0200 > @@ -315,6 +315,7 @@ extern char *dynamic_dname(struct dentry > > extern int __d_path(const struct path *path, struct path *root, char **, int *); > extern char *d_path(const struct path *, char *, int); > +extern char *d_path_with_unreachable(const struct path *, char *, int); > extern char *dentry_path(struct dentry *, char *, int); > > /* Allocation counts.. */ > Index: linux-2.6/fs/proc/base.c > =================================================================== > --- linux-2.6.orig/fs/proc/base.c 2010-05-27 11:53:55.000000000 +0200 > +++ linux-2.6/fs/proc/base.c 2010-05-27 12:22:24.000000000 +0200 > @@ -1438,7 +1438,7 @@ static int do_proc_readlink(struct path > if (!tmp) > return -ENOMEM; > > - pathname = d_path(path, tmp, PAGE_SIZE); > + pathname = d_path_with_unreachable(path, tmp, PAGE_SIZE); > len = PTR_ERR(pathname); > if (IS_ERR(pathname)) > goto out; > -- 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