aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 15:11:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 15:11:35 -0400
commit1466b77a7be75144dee1cb09839be3435854dd0b (patch)
tree977a0b6c1cd69ff98e5027359bb7de7b8897276a /net
parent19d2f8e0fb7bba99cc585d2467e9fa54a84c8557 (diff)
parenteeee245268c951262b861bc1be4e9dc812352499 (diff)
Merge tag 'nfs-for-3.11-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull second set of NFS client updates from Trond Myklebust: "This mainly contains some small readdir optimisations that had dependencies on Al Viro's readdir rewrite. There is also a fix for a nasty deadlock which surfaced earlier in this merge window. Highlights include: - Fix an_rpc pipefs regression that causes a deadlock on mount - Readdir optimisations by Scott Mayhew and Jeff Layton - clean up the rpc_pipefs dentry operation setup" * tag 'nfs-for-3.11-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: SUNRPC: Fix a deadlock in rpc_client_register() rpc_pipe: rpc_dir_inode_operations can be static NFS: Allow nfs_updatepage to extend a write under additional circumstances NFS: Make nfs_readdir revalidate less often NFS: Make nfs_attribute_cache_expired() non-static rpc_pipe: set dentry operations at d_alloc time nfs: set verifier on existing dentries in nfs_prime_dcache
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/clnt.c16
-rw-r--r--net/sunrpc/rpc_pipe.c25
2 files changed, 29 insertions, 12 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index f0339ae9bf37..aa401560777b 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -290,7 +290,7 @@ static int rpc_client_register(const struct rpc_create_args *args,
290 struct rpc_auth *auth; 290 struct rpc_auth *auth;
291 struct net *net = rpc_net_ns(clnt); 291 struct net *net = rpc_net_ns(clnt);
292 struct super_block *pipefs_sb; 292 struct super_block *pipefs_sb;
293 int err = 0; 293 int err;
294 294
295 pipefs_sb = rpc_get_sb_net(net); 295 pipefs_sb = rpc_get_sb_net(net);
296 if (pipefs_sb) { 296 if (pipefs_sb) {
@@ -299,6 +299,10 @@ static int rpc_client_register(const struct rpc_create_args *args,
299 goto out; 299 goto out;
300 } 300 }
301 301
302 rpc_register_client(clnt);
303 if (pipefs_sb)
304 rpc_put_sb_net(net);
305
302 auth = rpcauth_create(args->authflavor, clnt); 306 auth = rpcauth_create(args->authflavor, clnt);
303 if (IS_ERR(auth)) { 307 if (IS_ERR(auth)) {
304 dprintk("RPC: Couldn't create auth handle (flavor %u)\n", 308 dprintk("RPC: Couldn't create auth handle (flavor %u)\n",
@@ -306,16 +310,14 @@ static int rpc_client_register(const struct rpc_create_args *args,
306 err = PTR_ERR(auth); 310 err = PTR_ERR(auth);
307 goto err_auth; 311 goto err_auth;
308 } 312 }
309 313 return 0;
310 rpc_register_client(clnt); 314err_auth:
315 pipefs_sb = rpc_get_sb_net(net);
316 __rpc_clnt_remove_pipedir(clnt);
311out: 317out:
312 if (pipefs_sb) 318 if (pipefs_sb)
313 rpc_put_sb_net(net); 319 rpc_put_sb_net(net);
314 return err; 320 return err;
315
316err_auth:
317 __rpc_clnt_remove_pipedir(clnt);
318 goto out;
319} 321}
320 322
321static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) 323static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 4679df5a6d50..61239a2cb786 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 */
487static struct dentry *
488rpc_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
496static const struct inode_operations rpc_dir_inode_operations = {
497 .lookup = rpc_lookup,
498};
499
483static struct inode * 500static struct inode *
484rpc_get_inode(struct super_block *sb, umode_t mode) 501rpc_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);