diff options
author | Jeff Layton <jlayton@redhat.com> | 2013-07-02 13:00:52 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-07-09 17:16:39 -0400 |
commit | 76fa66657900071016f2bae61de28f059f3f2abf (patch) | |
tree | 79fa6e7b03a149acaa1c6ac1ca29b5c6b6c05685 /net/sunrpc/rpc_pipe.c | |
parent | cda57a1ef6f0da7e24f392ffdf00538ec0480310 (diff) |
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>
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 4679df5a6d50..c5f6812ca06a 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -480,6 +480,23 @@ static const struct dentry_operations rpc_dentry_operations = { | |||
480 | .d_delete = rpc_delete_dentry, | 480 | .d_delete = rpc_delete_dentry, |
481 | }; | 481 | }; |
482 | 482 | ||
483 | /* | ||
484 | * Lookup the data. This is trivial - if the dentry didn't already | ||
485 | * exist, we know it is negative. | ||
486 | */ | ||
487 | static struct dentry * | ||
488 | rpc_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) | ||
489 | { | ||
490 | if (dentry->d_name.len > NAME_MAX) | ||
491 | return ERR_PTR(-ENAMETOOLONG); | ||
492 | d_add(dentry, NULL); | ||
493 | return NULL; | ||
494 | } | ||
495 | |||
496 | const struct inode_operations rpc_dir_inode_operations = { | ||
497 | .lookup = rpc_lookup, | ||
498 | }; | ||
499 | |||
483 | static struct inode * | 500 | static struct inode * |
484 | rpc_get_inode(struct super_block *sb, umode_t mode) | 501 | rpc_get_inode(struct super_block *sb, umode_t mode) |
485 | { | 502 | { |
@@ -492,7 +509,7 @@ rpc_get_inode(struct super_block *sb, umode_t mode) | |||
492 | switch (mode & S_IFMT) { | 509 | switch (mode & S_IFMT) { |
493 | case S_IFDIR: | 510 | case S_IFDIR: |
494 | inode->i_fop = &simple_dir_operations; | 511 | inode->i_fop = &simple_dir_operations; |
495 | inode->i_op = &simple_dir_inode_operations; | 512 | inode->i_op = &rpc_dir_inode_operations; |
496 | inc_nlink(inode); | 513 | inc_nlink(inode); |
497 | default: | 514 | default: |
498 | break; | 515 | break; |
@@ -666,11 +683,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent, | |||
666 | if (!dentry) | 683 | if (!dentry) |
667 | return ERR_PTR(-ENOMEM); | 684 | return ERR_PTR(-ENOMEM); |
668 | } | 685 | } |
669 | if (dentry->d_inode == NULL) { | 686 | if (dentry->d_inode == NULL) |
670 | if (!dentry->d_op) | ||
671 | d_set_d_op(dentry, &rpc_dentry_operations); | ||
672 | return dentry; | 687 | return dentry; |
673 | } | ||
674 | dput(dentry); | 688 | dput(dentry); |
675 | return ERR_PTR(-EEXIST); | 689 | return ERR_PTR(-EEXIST); |
676 | } | 690 | } |
@@ -1117,6 +1131,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) | |||
1117 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 1131 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
1118 | sb->s_magic = RPCAUTH_GSSMAGIC; | 1132 | sb->s_magic = RPCAUTH_GSSMAGIC; |
1119 | sb->s_op = &s_ops; | 1133 | sb->s_op = &s_ops; |
1134 | sb->s_d_op = &rpc_dentry_operations; | ||
1120 | sb->s_time_gran = 1; | 1135 | sb->s_time_gran = 1; |
1121 | 1136 | ||
1122 | inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); | 1137 | inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); |