diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dcache.c | 31 | ||||
-rw-r--r-- | fs/pipe.c | 18 |
2 files changed, 43 insertions, 6 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 268da2e2bc09..2135ab8bb103 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1853,6 +1853,16 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, struct vfsmount *rootmnt; struct dentry *root; + /* + * We have various synthetic filesystems that never get mounted. On + * these filesystems dentries are never used for lookup purposes, and + * thus don't need to be hashed. They also don't need a name until a + * user wants to identify the object in /proc/pid/fd/. The little hack + * below allows us to generate a name for these objects on demand: + */ + if (dentry->d_op && dentry->d_op->d_dname) + return dentry->d_op->d_dname(dentry, buf, buflen); + read_lock(¤t->fs->lock); rootmnt = mntget(current->fs->rootmnt); root = dget(current->fs->root); @@ -1866,6 +1876,27 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, } /* + * Helper function for dentry_operations.d_dname() members + */ +char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen, + const char *fmt, ...) +{ + va_list args; + char temp[64]; + int sz; + + va_start(args, fmt); + sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1; + va_end(args); + + if (sz > sizeof(temp) || sz > buflen) + return ERR_PTR(-ENAMETOOLONG); + + buffer += buflen - sz; + return memcpy(buffer, temp, sz); +} + +/* * NOTE! The user-level library version returns a * character pointer. The kernel system call just * returns the length of the buffer filled (which diff --git a/fs/pipe.c b/fs/pipe.c index ebafde7d6aba..3a89592bdf57 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -841,8 +841,18 @@ static int pipefs_delete_dentry(struct dentry *dentry) return 0; } +/* + * pipefs_dname() is called from d_path(). + */ +static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen) +{ + return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]", + dentry->d_inode->i_ino); +} + static struct dentry_operations pipefs_dentry_operations = { .d_delete = pipefs_delete_dentry, + .d_dname = pipefs_dname, }; static struct inode * get_pipe_inode(void) @@ -888,8 +898,7 @@ struct file *create_write_pipe(void) struct inode *inode; struct file *f; struct dentry *dentry; - char name[32]; - struct qstr this; + struct qstr name = { .name = "" }; f = get_empty_filp(); if (!f) @@ -899,11 +908,8 @@ struct file *create_write_pipe(void) if (!inode) goto err_file; - this.len = sprintf(name, "[%lu]", inode->i_ino); - this.name = name; - this.hash = 0; err = -ENOMEM; - dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); + dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); if (!dentry) goto err_inode; |