diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2007-05-08 03:26:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:03 -0400 |
commit | c23fbb6bcb3eb9cdf39a103edadf57bde8ce309c (patch) | |
tree | d79ab2278774de2c1a8061aa948ed068902e87b4 /net | |
parent | 2793274298c4423d79701e9a8190f2940bf3c785 (diff) |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/socket.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/net/socket.c b/net/socket.c index 759825b7ca26..98a8f67abbfc 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -313,8 +313,19 @@ static int sockfs_delete_dentry(struct dentry *dentry) | |||
313 | dentry->d_flags |= DCACHE_UNHASHED; | 313 | dentry->d_flags |= DCACHE_UNHASHED; |
314 | return 0; | 314 | return 0; |
315 | } | 315 | } |
316 | |||
317 | /* | ||
318 | * sockfs_dname() is called from d_path(). | ||
319 | */ | ||
320 | static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen) | ||
321 | { | ||
322 | return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]", | ||
323 | dentry->d_inode->i_ino); | ||
324 | } | ||
325 | |||
316 | static struct dentry_operations sockfs_dentry_operations = { | 326 | static struct dentry_operations sockfs_dentry_operations = { |
317 | .d_delete = sockfs_delete_dentry, | 327 | .d_delete = sockfs_delete_dentry, |
328 | .d_dname = sockfs_dname, | ||
318 | }; | 329 | }; |
319 | 330 | ||
320 | /* | 331 | /* |
@@ -354,14 +365,9 @@ static int sock_alloc_fd(struct file **filep) | |||
354 | 365 | ||
355 | static int sock_attach_fd(struct socket *sock, struct file *file) | 366 | static int sock_attach_fd(struct socket *sock, struct file *file) |
356 | { | 367 | { |
357 | struct qstr this; | 368 | struct qstr name = { .name = "" }; |
358 | char name[32]; | ||
359 | |||
360 | this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); | ||
361 | this.name = name; | ||
362 | this.hash = 0; | ||
363 | 369 | ||
364 | file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); | 370 | file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); |
365 | if (unlikely(!file->f_path.dentry)) | 371 | if (unlikely(!file->f_path.dentry)) |
366 | return -ENOMEM; | 372 | return -ENOMEM; |
367 | 373 | ||