rpc_pipe: set dentry operations at d_alloc time
Currently the way these get set is a little convoluted. If the dentry is allocated via lookup from userland, then it gets set by simple_lookup. If it gets allocated when the kernel is populating the directory, then it gets set via __rpc_lookup_create_exclusive, which has to check whether they might already be set. Between both of these, this ensures that all dentries have their d_op pointer set. Instead of doing that, just have them set at d_alloc time by pointing sb->s_d_op at them. With that change, we no longer want the lookup op to set them, so we must move to using our own lookup routine. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
committed by
Trond Myklebust
parent
cda57a1ef6
commit
76fa666579
@@ -480,6 +480,23 @@ static const struct dentry_operations rpc_dentry_operations = {
|
|||||||
.d_delete = rpc_delete_dentry,
|
.d_delete = rpc_delete_dentry,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lookup the data. This is trivial - if the dentry didn't already
|
||||||
|
* exist, we know it is negative.
|
||||||
|
*/
|
||||||
|
static struct dentry *
|
||||||
|
rpc_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||||
|
{
|
||||||
|
if (dentry->d_name.len > NAME_MAX)
|
||||||
|
return ERR_PTR(-ENAMETOOLONG);
|
||||||
|
d_add(dentry, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct inode_operations rpc_dir_inode_operations = {
|
||||||
|
.lookup = rpc_lookup,
|
||||||
|
};
|
||||||
|
|
||||||
static struct inode *
|
static struct inode *
|
||||||
rpc_get_inode(struct super_block *sb, umode_t mode)
|
rpc_get_inode(struct super_block *sb, umode_t mode)
|
||||||
{
|
{
|
||||||
@@ -492,7 +509,7 @@ rpc_get_inode(struct super_block *sb, umode_t mode)
|
|||||||
switch (mode & S_IFMT) {
|
switch (mode & S_IFMT) {
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
inode->i_fop = &simple_dir_operations;
|
inode->i_fop = &simple_dir_operations;
|
||||||
inode->i_op = &simple_dir_inode_operations;
|
inode->i_op = &rpc_dir_inode_operations;
|
||||||
inc_nlink(inode);
|
inc_nlink(inode);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -666,11 +683,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
|
|||||||
if (!dentry)
|
if (!dentry)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
if (dentry->d_inode == NULL) {
|
if (dentry->d_inode == NULL)
|
||||||
if (!dentry->d_op)
|
|
||||||
d_set_d_op(dentry, &rpc_dentry_operations);
|
|
||||||
return dentry;
|
return dentry;
|
||||||
}
|
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
return ERR_PTR(-EEXIST);
|
return ERR_PTR(-EEXIST);
|
||||||
}
|
}
|
||||||
@@ -1117,6 +1131,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
|
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
|
||||||
sb->s_magic = RPCAUTH_GSSMAGIC;
|
sb->s_magic = RPCAUTH_GSSMAGIC;
|
||||||
sb->s_op = &s_ops;
|
sb->s_op = &s_ops;
|
||||||
|
sb->s_d_op = &rpc_dentry_operations;
|
||||||
sb->s_time_gran = 1;
|
sb->s_time_gran = 1;
|
||||||
|
|
||||||
inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO);
|
inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO);
|
||||||
|
Reference in New Issue
Block a user