aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-06-06 22:31:14 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-09 16:48:13 -0400
commitc103135c14e03fc9a9e5f0adc01df9ad272cf2a1 (patch)
tree0c75bd6a56385697cd0e79fb695a833c5225e45e
parentd0352d3ed722b134dacc21836c1763e7e3523662 (diff)
new helper: __dentry_path()
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>
-rw-r--r--fs/dcache.c27
-rw-r--r--include/linux/dcache.h1
2 files changed, 23 insertions, 5 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 86d4db15473e..caf08574982f 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2049,16 +2049,12 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
2049/* 2049/*
2050 * Write full pathname from the root of the filesystem into the buffer. 2050 * Write full pathname from the root of the filesystem into the buffer.
2051 */ 2051 */
2052char *dentry_path(struct dentry *dentry, char *buf, int buflen) 2052char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
2053{ 2053{
2054 char *end = buf + buflen; 2054 char *end = buf + buflen;
2055 char *retval; 2055 char *retval;
2056 2056
2057 spin_lock(&dcache_lock);
2058 prepend(&end, &buflen, "\0", 1); 2057 prepend(&end, &buflen, "\0", 1);
2059 if (d_unlinked(dentry) &&
2060 (prepend(&end, &buflen, "//deleted", 9) != 0))
2061 goto Elong;
2062 if (buflen < 1) 2058 if (buflen < 1)
2063 goto Elong; 2059 goto Elong;
2064 /* Get '/' right */ 2060 /* Get '/' right */
@@ -2076,7 +2072,28 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
2076 retval = end; 2072 retval = end;
2077 dentry = parent; 2073 dentry = parent;
2078 } 2074 }
2075 return retval;
2076Elong:
2077 return ERR_PTR(-ENAMETOOLONG);
2078}
2079EXPORT_SYMBOL(__dentry_path);
2080
2081char *dentry_path(struct dentry *dentry, char *buf, int buflen)
2082{
2083 char *p = NULL;
2084 char *retval;
2085
2086 spin_lock(&dcache_lock);
2087 if (d_unlinked(dentry)) {
2088 p = buf + buflen;
2089 if (prepend(&p, &buflen, "//deleted", 10) != 0)
2090 goto Elong;
2091 buflen++;
2092 }
2093 retval = __dentry_path(dentry, buf, buflen);
2079 spin_unlock(&dcache_lock); 2094 spin_unlock(&dcache_lock);
2095 if (!IS_ERR(retval) && p)
2096 *p = '/'; /* restore '/' overriden with '\0' */
2080 return retval; 2097 return retval;
2081Elong: 2098Elong:
2082 spin_unlock(&dcache_lock); 2099 spin_unlock(&dcache_lock);
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index eebb617c17d8..d23be0386e2d 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -315,6 +315,7 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
315 315
316extern char *__d_path(const struct path *path, struct path *root, char *, int); 316extern char *__d_path(const struct path *path, struct path *root, char *, int);
317extern char *d_path(const struct path *, char *, int); 317extern char *d_path(const struct path *, char *, int);
318extern char *__dentry_path(struct dentry *, char *, int);
318extern char *dentry_path(struct dentry *, char *, int); 319extern char *dentry_path(struct dentry *, char *, int);
319 320
320/* Allocation counts.. */ 321/* Allocation counts.. */