diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index acb13b77027b..444e9e488046 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3331,3 +3331,31 @@ void __init vfs_caches_init(unsigned long mempages) bdev_cache_init(); chrdev_init(); } + +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); |