vfs: factor out helpers d_instantiate_anon() and d_alloc_anon()
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 19 Jan 2018 10:39:52 +0000 (11:39 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 24 Jan 2018 10:25:59 +0000 (11:25 +0100)
Those helpers are going to be used by overlayfs to implement
NFS export decode.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/dcache.c
include/linux/dcache.h

index b5d5ea9..99bce0e 100644 (file)
@@ -1699,9 +1699,15 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
 }
 EXPORT_SYMBOL(d_alloc);
 
+struct dentry *d_alloc_anon(struct super_block *sb)
+{
+       return __d_alloc(sb, NULL);
+}
+EXPORT_SYMBOL(d_alloc_anon);
+
 struct dentry *d_alloc_cursor(struct dentry * parent)
 {
-       struct dentry *dentry = __d_alloc(parent->d_sb, NULL);
+       struct dentry *dentry = d_alloc_anon(parent->d_sb);
        if (dentry) {
                dentry->d_flags |= DCACHE_RCUACCESS | DCACHE_DENTRY_CURSOR;
                dentry->d_parent = dget(parent);
@@ -1887,7 +1893,7 @@ struct dentry *d_make_root(struct inode *root_inode)
        struct dentry *res = NULL;
 
        if (root_inode) {
-               res = __d_alloc(root_inode->i_sb, NULL);
+               res = d_alloc_anon(root_inode->i_sb);
                if (res)
                        d_instantiate(res, root_inode);
                else
@@ -1926,33 +1932,19 @@ struct dentry *d_find_any_alias(struct inode *inode)
 }
 EXPORT_SYMBOL(d_find_any_alias);
 
-static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
+static struct dentry *__d_instantiate_anon(struct dentry *dentry,
+                                          struct inode *inode,
+                                          bool disconnected)
 {
-       struct dentry *tmp;
        struct dentry *res;
        unsigned add_flags;
 
-       if (!inode)
-               return ERR_PTR(-ESTALE);
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-
-       res = d_find_any_alias(inode);
-       if (res)
-               goto out_iput;
-
-       tmp = __d_alloc(inode->i_sb, NULL);
-       if (!tmp) {
-               res = ERR_PTR(-ENOMEM);
-               goto out_iput;
-       }
-
-       security_d_instantiate(tmp, inode);
+       security_d_instantiate(dentry, inode);
        spin_lock(&inode->i_lock);
        res = __d_find_any_alias(inode);
        if (res) {
                spin_unlock(&inode->i_lock);
-               dput(tmp);
+               dput(dentry);
                goto out_iput;
        }
 
@@ -1962,22 +1954,55 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
        if (disconnected)
                add_flags |= DCACHE_DISCONNECTED;
 
-       spin_lock(&tmp->d_lock);
-       __d_set_inode_and_type(tmp, inode, add_flags);
-       hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry);
-       hlist_bl_lock(&tmp->d_sb->s_anon);
-       hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
-       hlist_bl_unlock(&tmp->d_sb->s_anon);
-       spin_unlock(&tmp->d_lock);
+       spin_lock(&dentry->d_lock);
+       __d_set_inode_and_type(dentry, inode, add_flags);
+       hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
+       hlist_bl_lock(&dentry->d_sb->s_anon);
+       hlist_bl_add_head(&dentry->d_hash, &dentry->d_sb->s_anon);
+       hlist_bl_unlock(&dentry->d_sb->s_anon);
+       spin_unlock(&dentry->d_lock);
        spin_unlock(&inode->i_lock);
 
-       return tmp;
+       return dentry;
 
  out_iput:
        iput(inode);
        return res;
 }
 
+struct dentry *d_instantiate_anon(struct dentry *dentry, struct inode *inode)
+{
+       return __d_instantiate_anon(dentry, inode, true);
+}
+EXPORT_SYMBOL(d_instantiate_anon);
+
+static struct dentry *__d_obtain_alias(struct inode *inode, bool disconnected)
+{
+       struct dentry *tmp;
+       struct dentry *res;
+
+       if (!inode)
+               return ERR_PTR(-ESTALE);
+       if (IS_ERR(inode))
+               return ERR_CAST(inode);
+
+       res = d_find_any_alias(inode);
+       if (res)
+               goto out_iput;
+
+       tmp = d_alloc_anon(inode->i_sb);
+       if (!tmp) {
+               res = ERR_PTR(-ENOMEM);
+               goto out_iput;
+       }
+
+       return __d_instantiate_anon(tmp, inode, disconnected);
+
+out_iput:
+       iput(inode);
+       return res;
+}
+
 /**
  * d_obtain_alias - find or allocate a DISCONNECTED dentry for a given inode
  * @inode: inode to allocate the dentry for
@@ -1998,7 +2023,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
  */
 struct dentry *d_obtain_alias(struct inode *inode)
 {
-       return __d_obtain_alias(inode, 1);
+       return __d_obtain_alias(inode, true);
 }
 EXPORT_SYMBOL(d_obtain_alias);
 
@@ -2019,7 +2044,7 @@ EXPORT_SYMBOL(d_obtain_alias);
  */
 struct dentry *d_obtain_root(struct inode *inode)
 {
-       return __d_obtain_alias(inode, 0);
+       return __d_obtain_alias(inode, false);
 }
 EXPORT_SYMBOL(d_obtain_root);
 
index 65cd8ab..82a99d3 100644 (file)
@@ -227,6 +227,7 @@ extern seqlock_t rename_lock;
  */
 extern void d_instantiate(struct dentry *, struct inode *);
 extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
+extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *);
 extern int d_instantiate_no_diralias(struct dentry *, struct inode *);
 extern void __d_drop(struct dentry *dentry);
 extern void d_drop(struct dentry *dentry);
@@ -235,6 +236,7 @@ extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op
 
 /* allocate/de-allocate */
 extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
+extern struct dentry * d_alloc_anon(struct super_block *);
 extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *);
 extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *,
                                        wait_queue_head_t *);