Commit f9c34674 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Miklos Szeredi

vfs: factor out helpers d_instantiate_anon() and d_alloc_anon()

Those helpers are going to be used by overlayfs to implement
NFS export decode.
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent c62520a8
...@@ -1699,9 +1699,15 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) ...@@ -1699,9 +1699,15 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
} }
EXPORT_SYMBOL(d_alloc); 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 *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) { if (dentry) {
dentry->d_flags |= DCACHE_RCUACCESS | DCACHE_DENTRY_CURSOR; dentry->d_flags |= DCACHE_RCUACCESS | DCACHE_DENTRY_CURSOR;
dentry->d_parent = dget(parent); dentry->d_parent = dget(parent);
...@@ -1887,7 +1893,7 @@ struct dentry *d_make_root(struct inode *root_inode) ...@@ -1887,7 +1893,7 @@ struct dentry *d_make_root(struct inode *root_inode)
struct dentry *res = NULL; struct dentry *res = NULL;
if (root_inode) { if (root_inode) {
res = __d_alloc(root_inode->i_sb, NULL); res = d_alloc_anon(root_inode->i_sb);
if (res) if (res)
d_instantiate(res, root_inode); d_instantiate(res, root_inode);
else else
...@@ -1926,33 +1932,19 @@ struct dentry *d_find_any_alias(struct inode *inode) ...@@ -1926,33 +1932,19 @@ struct dentry *d_find_any_alias(struct inode *inode)
} }
EXPORT_SYMBOL(d_find_any_alias); 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; struct dentry *res;
unsigned add_flags; unsigned add_flags;
if (!inode) security_d_instantiate(dentry, 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);
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
res = __d_find_any_alias(inode); res = __d_find_any_alias(inode);
if (res) { if (res) {
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
dput(tmp); dput(dentry);
goto out_iput; goto out_iput;
} }
...@@ -1962,22 +1954,55 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected) ...@@ -1962,22 +1954,55 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
if (disconnected) if (disconnected)
add_flags |= DCACHE_DISCONNECTED; add_flags |= DCACHE_DISCONNECTED;
spin_lock(&tmp->d_lock); spin_lock(&dentry->d_lock);
__d_set_inode_and_type(tmp, inode, add_flags); __d_set_inode_and_type(dentry, inode, add_flags);
hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry); hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
hlist_bl_lock(&tmp->d_sb->s_anon); hlist_bl_lock(&dentry->d_sb->s_anon);
hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); hlist_bl_add_head(&dentry->d_hash, &dentry->d_sb->s_anon);
hlist_bl_unlock(&tmp->d_sb->s_anon); hlist_bl_unlock(&dentry->d_sb->s_anon);
spin_unlock(&tmp->d_lock); spin_unlock(&dentry->d_lock);
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
return tmp; return dentry;
out_iput: out_iput:
iput(inode); iput(inode);
return res; 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 * d_obtain_alias - find or allocate a DISCONNECTED dentry for a given inode
* @inode: inode to allocate the dentry for * @inode: inode to allocate the dentry for
...@@ -1998,7 +2023,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected) ...@@ -1998,7 +2023,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
*/ */
struct dentry *d_obtain_alias(struct inode *inode) 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); EXPORT_SYMBOL(d_obtain_alias);
...@@ -2019,7 +2044,7 @@ EXPORT_SYMBOL(d_obtain_alias); ...@@ -2019,7 +2044,7 @@ EXPORT_SYMBOL(d_obtain_alias);
*/ */
struct dentry *d_obtain_root(struct inode *inode) 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); EXPORT_SYMBOL(d_obtain_root);
......
...@@ -227,6 +227,7 @@ extern seqlock_t rename_lock; ...@@ -227,6 +227,7 @@ extern seqlock_t rename_lock;
*/ */
extern void d_instantiate(struct dentry *, struct inode *); extern void d_instantiate(struct dentry *, struct inode *);
extern struct dentry * d_instantiate_unique(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 int d_instantiate_no_diralias(struct dentry *, struct inode *);
extern void __d_drop(struct dentry *dentry); extern void __d_drop(struct dentry *dentry);
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 ...@@ -235,6 +236,7 @@ extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op
/* allocate/de-allocate */ /* allocate/de-allocate */
extern struct dentry * d_alloc(struct dentry *, const struct qstr *); 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_pseudo(struct super_block *, const struct qstr *);
extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *, extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *,
wait_queue_head_t *); wait_queue_head_t *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment