diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-08 19:50:54 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-08 19:50:54 +0200 |
commit | b8d4c1f9f48e344fe1d6e6ffae01d4b31bf0aac0 (patch) | |
tree | 24685a7b0ebf8af0ff55f1384e0be125aa29da47 /fs/dcache.c | |
parent | Merge branch 'for-spi' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs (diff) | |
parent | dentry name snapshots (diff) | |
download | linux-b8d4c1f9f48e344fe1d6e6ffae01d4b31bf0aac0.tar.xz linux-b8d4c1f9f48e344fe1d6e6ffae01d4b31bf0aac0.zip |
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc filesystem updates from Al Viro:
"Assorted normal VFS / filesystems stuff..."
* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
dentry name snapshots
Make statfs properly return read-only state after emergency remount
fs/dcache: init in_lookup_hashtable
minix: Deinline get_block, save 2691 bytes
fs: Reorder inode_owner_or_capable() to avoid needless
fs: warn in case userspace lied about modprobe return
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index a140fe1dbb1a..7ece68d0d4db 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -277,6 +277,33 @@ static inline int dname_external(const struct dentry *dentry) return dentry->d_name.name != dentry->d_iname; } +void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry) +{ + spin_lock(&dentry->d_lock); + if (unlikely(dname_external(dentry))) { + struct external_name *p = external_name(dentry); + atomic_inc(&p->u.count); + spin_unlock(&dentry->d_lock); + name->name = p->name; + } else { + memcpy(name->inline_name, dentry->d_iname, DNAME_INLINE_LEN); + spin_unlock(&dentry->d_lock); + name->name = name->inline_name; + } +} +EXPORT_SYMBOL(take_dentry_name_snapshot); + +void release_dentry_name_snapshot(struct name_snapshot *name) +{ + if (unlikely(name->name != name->inline_name)) { + struct external_name *p; + p = container_of(name->name, struct external_name, name[0]); + if (unlikely(atomic_dec_and_test(&p->u.count))) + kfree_rcu(p, u.head); + } +} +EXPORT_SYMBOL(release_dentry_name_snapshot); + static inline void __d_set_inode_and_type(struct dentry *dentry, struct inode *inode, unsigned type_flags) @@ -3598,6 +3625,11 @@ EXPORT_SYMBOL(d_genocide); void __init vfs_caches_init_early(void) { + int i; + + for (i = 0; i < ARRAY_SIZE(in_lookup_hashtable); i++) + INIT_HLIST_BL_HEAD(&in_lookup_hashtable[i]); + dcache_init_early(); inode_init_early(); } |