diff options
author | Ram Pai <linuxram@us.ibm.com> | 2008-03-27 13:06:20 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-23 00:04:32 -0400 |
commit | 6092d048183b76bfa3f84b32f8158dd8d10bd811 (patch) | |
tree | 2d38af32961eb52b36daca2f29ce69e80f6e7283 /fs/seq_file.c | |
parent | 934b25c597c0e98304a7eaec198a87e4633a42bb (diff) | |
download | lwn-6092d048183b76bfa3f84b32f8158dd8d10bd811.tar.gz lwn-6092d048183b76bfa3f84b32f8158dd8d10bd811.zip |
[patch 1/7] vfs: mountinfo: add dentry_path()
[mszeredi@suse.cz] split big patch into managable chunks
Add the following functions:
dentry_path()
seq_dentry()
These are similar to d_path() and seq_path(). But instead of
calculating the path within a mount namespace, they calculate the path
from the root of the filesystem to a given dentry, ignoring mounts
completely.
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/seq_file.c')
-rw-r--r-- | fs/seq_file.c | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/fs/seq_file.c b/fs/seq_file.c index cdfd996ca6ef..ae59f5a6c5c1 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -350,28 +350,40 @@ int seq_printf(struct seq_file *m, const char *f, ...) } EXPORT_SYMBOL(seq_printf); +static char *mangle_path(char *s, char *p, char *esc) +{ + while (s <= p) { + char c = *p++; + if (!c) { + return s; + } else if (!strchr(esc, c)) { + *s++ = c; + } else if (s + 4 > p) { + break; + } else { + *s++ = '\\'; + *s++ = '0' + ((c & 0300) >> 6); + *s++ = '0' + ((c & 070) >> 3); + *s++ = '0' + (c & 07); + } + } + return NULL; +} + +/* + * return the absolute path of 'dentry' residing in mount 'mnt'. + */ int seq_path(struct seq_file *m, struct path *path, char *esc) { if (m->count < m->size) { char *s = m->buf + m->count; char *p = d_path(path, s, m->size - m->count); if (!IS_ERR(p)) { - while (s <= p) { - char c = *p++; - if (!c) { - p = m->buf + m->count; - m->count = s - m->buf; - return s - p; - } else if (!strchr(esc, c)) { - *s++ = c; - } else if (s + 4 > p) { - break; - } else { - *s++ = '\\'; - *s++ = '0' + ((c & 0300) >> 6); - *s++ = '0' + ((c & 070) >> 3); - *s++ = '0' + (c & 07); - } + s = mangle_path(s, p, esc); + if (s) { + p = m->buf + m->count; + m->count = s - m->buf; + return s - p; } } } @@ -380,6 +392,27 @@ int seq_path(struct seq_file *m, struct path *path, char *esc) } EXPORT_SYMBOL(seq_path); +/* + * returns the path of the 'dentry' from the root of its filesystem. + */ +int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc) +{ + if (m->count < m->size) { + char *s = m->buf + m->count; + char *p = dentry_path(dentry, s, m->size - m->count); + if (!IS_ERR(p)) { + s = mangle_path(s, p, esc); + if (s) { + p = m->buf + m->count; + m->count = s - m->buf; + return s - p; + } + } + } + m->count = m->size; + return -1; +} + static void *single_start(struct seq_file *p, loff_t *pos) { return NULL + (*pos == 0); |