diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-05-14 05:46:55 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-05-14 05:46:55 -0700 |
| commit | 90b163a4b5dd909f8a6f9c61c5bdce17130350a0 (patch) | |
| tree | c1acb644b3cd9fecd1cf9d97f2e04c65ee395674 /include/linux | |
| parent | fd2d876083bf90ce4f569542d78166387937e0bf (diff) | |
[PATCH] dentry qstr consolidation
When dentries are given an external name we currently allocate an entire qstr
for the external name.
This isn't needed. We can use the internal qstr and kmalloc only the string
itself. This saves 12 bytes from externally-allocated names and 4 bytes from
the dentry itself.
The saving of 4 bytes from the dentry doesn't actually decrease the dentry's
storage requirements, but it makes four more bytes available for internal
names, taking the internal/external ratio from 89% up to 93% on my 1.5M files.
Fix:
The qstr consolidation wasn't quite right, because it can cause qstr->len to
be unstable during lookup lockless traverasl.
Fix that up by taking d_lock earlier in lookup. This serialises against
d_move.
Take the lock after comparing the parent and hash to preserve the
mostly-lockless behaviour.
This obsoletes d_movecount, which is removed.
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/dcache.h | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 7b612005423b..7c812cd06eae 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -29,10 +29,9 @@ struct vfsmount; * saves "metadata" about the string (ie length and the hash). */ struct qstr { - const unsigned char * name; + const unsigned char *name; unsigned int len; unsigned int hash; - char name_str[0]; }; struct dentry_stat_t { @@ -93,8 +92,6 @@ struct dentry { void * d_fsdata; /* fs-specific data */ struct rcu_head d_rcu; struct dcookie_struct * d_cookie; /* cookie, if any */ - unsigned long d_move_count; /* to indicated moved dentry while lockless lookup */ - struct qstr * d_qstr; /* quick str ptr used in lockless lookup and concurrent d_move */ struct dentry * d_parent; /* parent directory */ struct qstr d_name; struct hlist_node d_hash; /* lookup hash list */ @@ -120,13 +117,13 @@ struct dentry_operations { /* locking rules: - big lock dcache_lock may block -d_revalidate: no no yes -d_hash no no yes -d_compare: no yes no -d_delete: no yes no -d_release: no no yes -d_iput: no no yes + big lock dcache_lock d_lock may block +d_revalidate: no no no yes +d_hash no no no yes +d_compare: no yes yes no +d_delete: no yes no no +d_release: no no no yes +d_iput: no no no yes */ /* d_flags entries */ @@ -184,9 +181,9 @@ static inline void d_drop(struct dentry *dentry) spin_unlock(&dcache_lock); } -static inline int dname_external(struct dentry *d) +static inline int dname_external(struct dentry *dentry) { - return d->d_name.name != d->d_iname; + return dentry->d_name.name != dentry->d_iname; } /* |
