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 /fs/dcache.c | |
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 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 31 |
1 files changed, 31 insertions, 0 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, | |||
1853 | struct vfsmount *rootmnt; | 1853 | struct vfsmount *rootmnt; |
1854 | struct dentry *root; | 1854 | struct dentry *root; |
1855 | 1855 | ||
1856 | /* | ||
1857 | * We have various synthetic filesystems that never get mounted. On | ||
1858 | * these filesystems dentries are never used for lookup purposes, and | ||
1859 | * thus don't need to be hashed. They also don't need a name until a | ||
1860 | * user wants to identify the object in /proc/pid/fd/. The little hack | ||
1861 | * below allows us to generate a name for these objects on demand: | ||
1862 | */ | ||
1863 | if (dentry->d_op && dentry->d_op->d_dname) | ||
1864 | return dentry->d_op->d_dname(dentry, buf, buflen); | ||
1865 | |||
1856 | read_lock(¤t->fs->lock); | 1866 | read_lock(¤t->fs->lock); |
1857 | rootmnt = mntget(current->fs->rootmnt); | 1867 | rootmnt = mntget(current->fs->rootmnt); |
1858 | root = dget(current->fs->root); | 1868 | root = dget(current->fs->root); |
@@ -1866,6 +1876,27 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, | |||
1866 | } | 1876 | } |
1867 | 1877 | ||
1868 | /* | 1878 | /* |
1879 | * Helper function for dentry_operations.d_dname() members | ||
1880 | */ | ||
1881 | char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen, | ||
1882 | const char *fmt, ...) | ||
1883 | { | ||
1884 | va_list args; | ||
1885 | char temp[64]; | ||
1886 | int sz; | ||
1887 | |||
1888 | va_start(args, fmt); | ||
1889 | sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1; | ||
1890 | va_end(args); | ||
1891 | |||
1892 | if (sz > sizeof(temp) || sz > buflen) | ||
1893 | return ERR_PTR(-ENAMETOOLONG); | ||
1894 | |||
1895 | buffer += buflen - sz; | ||
1896 | return memcpy(buffer, temp, sz); | ||
1897 | } | ||
1898 | |||
1899 | /* | ||
1869 | * NOTE! The user-level library version returns a | 1900 | * NOTE! The user-level library version returns a |
1870 | * character pointer. The kernel system call just | 1901 | * character pointer. The kernel system call just |
1871 | * returns the length of the buffer filled (which | 1902 | * returns the length of the buffer filled (which |