new helper: __dentry_path()
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 7 Jun 2010 02:31:14 +0000 (22:31 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 9 Aug 2010 20:48:13 +0000 (16:48 -0400)
builds path relative to fs root, called under dcache_lock,
doesn't append any nonsense to unlinked ones.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/dcache.c
include/linux/dcache.h

index 86d4db1..caf0857 100644 (file)
@@ -2049,16 +2049,12 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
 /*
  * Write full pathname from the root of the filesystem into the buffer.
  */
-char *dentry_path(struct dentry *dentry, char *buf, int buflen)
+char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
 {
        char *end = buf + buflen;
        char *retval;
 
-       spin_lock(&dcache_lock);
        prepend(&end, &buflen, "\0", 1);
-       if (d_unlinked(dentry) &&
-               (prepend(&end, &buflen, "//deleted", 9) != 0))
-                       goto Elong;
        if (buflen < 1)
                goto Elong;
        /* Get '/' right */
@@ -2076,7 +2072,28 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
                retval = end;
                dentry = parent;
        }
+       return retval;
+Elong:
+       return ERR_PTR(-ENAMETOOLONG);
+}
+EXPORT_SYMBOL(__dentry_path);
+
+char *dentry_path(struct dentry *dentry, char *buf, int buflen)
+{
+       char *p = NULL;
+       char *retval;
+
+       spin_lock(&dcache_lock);
+       if (d_unlinked(dentry)) {
+               p = buf + buflen;
+               if (prepend(&p, &buflen, "//deleted", 10) != 0)
+                       goto Elong;
+               buflen++;
+       }
+       retval = __dentry_path(dentry, buf, buflen);
        spin_unlock(&dcache_lock);
+       if (!IS_ERR(retval) && p)
+               *p = '/';       /* restore '/' overriden with '\0' */
        return retval;
 Elong:
        spin_unlock(&dcache_lock);
index eebb617..d23be03 100644 (file)
@@ -315,6 +315,7 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
 
 extern char *__d_path(const struct path *path, struct path *root, char *, int);
 extern char *d_path(const struct path *, char *, int);
+extern char *__dentry_path(struct dentry *, char *, int);
 extern char *dentry_path(struct dentry *, char *, int);
 
 /* Allocation counts.. */