VFS: delay the dentry name generation on sockets and pipes

1) Introduces a new method in 'struct dentry_operations'.  This method
   called d_dname() might be called from d_path() to build a pathname for
   special filesystems.  It is called without locks.

   Future patches (if we succeed in having one common dentry for all
   pipes/sockets) may need to change prototype of this method, but we now
   use : char *d_dname(struct dentry *dentry, char *buffer, int buflen);

2) Adds a dynamic_dname() helper function that eases d_dname() implementations

3) Defines d_dname method for sockets : No more sprintf() at socket
   creation.  This is delayed up to the moment someone does an access to
   /proc/pid/fd/...

4) Defines d_dname method for pipes : No more sprintf() at pipe
   creation.  This is delayed up to the moment someone does an access to
   /proc/pid/fd/...

A benchmark consisting of 1.000.000 calls to pipe()/close()/close() gives a
*nice* speedup on my Pentium(M) 1.6 Ghz :

3.090 s instead of 3.450 s

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Acked-by: Christoph Hellwig <hch@infradead.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Eric Dumazet 2007-05-08 00:26:18 -07:00 committed by Linus Torvalds
parent 2793274298
commit c23fbb6bcb
6 changed files with 86 additions and 14 deletions

View file

@ -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;