diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-06-06 22:31:14 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-08-09 16:48:13 -0400 |
commit | c103135c14e03fc9a9e5f0adc01df9ad272cf2a1 (patch) | |
tree | 0c75bd6a56385697cd0e79fb695a833c5225e45e /fs/dcache.c | |
parent | d0352d3ed722b134dacc21836c1763e7e3523662 (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>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 27 |
1 files changed, 22 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, /* * 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); |