aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2014-09-30 17:21:41 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-09-30 17:21:41 -0400
commit72c23f0819977d37924af92a42a9b7fbfd1c95d8 (patch)
treea0c10114d96c40f8e38887c346ec593a51321781 /fs/nfs
parent3fc3edf141fd78f624194eb89d7b37ff86138422 (diff)
parentd1f456b0b9545f1606a54cd17c20775f159bd2ce (diff)
Merge branch 'bugfixes' into linux-next
* bugfixes: NFSv4.1: Fix an NFSv4.1 state renewal regression NFSv4: fix open/lock state recovery error handling NFSv4: Fix lock recovery when CREATE_SESSION/SETCLIENTID_CONFIRM fails NFS: Fabricate fscache server index key correctly SUNRPC: Add missing support for RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT nfs: fix duplicate proc entries
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/fscache-index.c3
-rw-r--r--fs/nfs/nfs4client.c38
-rw-r--r--fs/nfs/nfs4proc.c42
-rw-r--r--fs/nfs/nfs4renewd.c12
-rw-r--r--fs/nfs/nfs4state.c17
6 files changed, 61 insertions, 53 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 8052020a0d0d..f9f4845db989 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1320,7 +1320,7 @@ static int nfs_server_list_show(struct seq_file *m, void *v)
1320 */ 1320 */
1321static int nfs_volume_list_open(struct inode *inode, struct file *file) 1321static int nfs_volume_list_open(struct inode *inode, struct file *file)
1322{ 1322{
1323 return seq_open_net(inode, file, &nfs_server_list_ops, 1323 return seq_open_net(inode, file, &nfs_volume_list_ops,
1324 sizeof(struct seq_net_private)); 1324 sizeof(struct seq_net_private));
1325} 1325}
1326 1326
diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
index 7cf2c4699b08..777b055063f6 100644
--- a/fs/nfs/fscache-index.c
+++ b/fs/nfs/fscache-index.c
@@ -74,11 +74,10 @@ static uint16_t nfs_server_get_key(const void *cookie_netfs_data,
74 struct nfs_server_key *key = buffer; 74 struct nfs_server_key *key = buffer;
75 uint16_t len = sizeof(struct nfs_server_key); 75 uint16_t len = sizeof(struct nfs_server_key);
76 76
77 memset(key, 0, len);
77 key->nfsversion = clp->rpc_ops->version; 78 key->nfsversion = clp->rpc_ops->version;
78 key->family = clp->cl_addr.ss_family; 79 key->family = clp->cl_addr.ss_family;
79 80
80 memset(key, 0, len);
81
82 switch (clp->cl_addr.ss_family) { 81 switch (clp->cl_addr.ss_family) {
83 case AF_INET: 82 case AF_INET:
84 key->port = sin->sin_port; 83 key->port = sin->sin_port;
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 53e435a95260..ffdb28d86cf8 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -482,6 +482,16 @@ int nfs40_walk_client_list(struct nfs_client *new,
482 482
483 spin_lock(&nn->nfs_client_lock); 483 spin_lock(&nn->nfs_client_lock);
484 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { 484 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
485
486 if (pos->rpc_ops != new->rpc_ops)
487 continue;
488
489 if (pos->cl_proto != new->cl_proto)
490 continue;
491
492 if (pos->cl_minorversion != new->cl_minorversion)
493 continue;
494
485 /* If "pos" isn't marked ready, we can't trust the 495 /* If "pos" isn't marked ready, we can't trust the
486 * remaining fields in "pos" */ 496 * remaining fields in "pos" */
487 if (pos->cl_cons_state > NFS_CS_READY) { 497 if (pos->cl_cons_state > NFS_CS_READY) {
@@ -501,15 +511,6 @@ int nfs40_walk_client_list(struct nfs_client *new,
501 if (pos->cl_cons_state != NFS_CS_READY) 511 if (pos->cl_cons_state != NFS_CS_READY)
502 continue; 512 continue;
503 513
504 if (pos->rpc_ops != new->rpc_ops)
505 continue;
506
507 if (pos->cl_proto != new->cl_proto)
508 continue;
509
510 if (pos->cl_minorversion != new->cl_minorversion)
511 continue;
512
513 if (pos->cl_clientid != new->cl_clientid) 514 if (pos->cl_clientid != new->cl_clientid)
514 continue; 515 continue;
515 516
@@ -622,6 +623,16 @@ int nfs41_walk_client_list(struct nfs_client *new,
622 623
623 spin_lock(&nn->nfs_client_lock); 624 spin_lock(&nn->nfs_client_lock);
624 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { 625 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
626
627 if (pos->rpc_ops != new->rpc_ops)
628 continue;
629
630 if (pos->cl_proto != new->cl_proto)
631 continue;
632
633 if (pos->cl_minorversion != new->cl_minorversion)
634 continue;
635
625 /* If "pos" isn't marked ready, we can't trust the 636 /* If "pos" isn't marked ready, we can't trust the
626 * remaining fields in "pos", especially the client 637 * remaining fields in "pos", especially the client
627 * ID and serverowner fields. Wait for CREATE_SESSION 638 * ID and serverowner fields. Wait for CREATE_SESSION
@@ -647,15 +658,6 @@ int nfs41_walk_client_list(struct nfs_client *new,
647 if (pos->cl_cons_state != NFS_CS_READY) 658 if (pos->cl_cons_state != NFS_CS_READY)
648 continue; 659 continue;
649 660
650 if (pos->rpc_ops != new->rpc_ops)
651 continue;
652
653 if (pos->cl_proto != new->cl_proto)
654 continue;
655
656 if (pos->cl_minorversion != new->cl_minorversion)
657 continue;
658
659 if (!nfs4_match_clientids(pos, new)) 661 if (!nfs4_match_clientids(pos, new))
660 continue; 662 continue;
661 663
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 45bce9ed6791..5aa55c132aa2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2234,9 +2234,13 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
2234 ret = _nfs4_proc_open(opendata); 2234 ret = _nfs4_proc_open(opendata);
2235 if (ret != 0) { 2235 if (ret != 0) {
2236 if (ret == -ENOENT) { 2236 if (ret == -ENOENT) {
2237 d_drop(opendata->dentry); 2237 dentry = opendata->dentry;
2238 d_add(opendata->dentry, NULL); 2238 if (dentry->d_inode)
2239 nfs_set_verifier(opendata->dentry, 2239 d_delete(dentry);
2240 else if (d_unhashed(dentry))
2241 d_add(dentry, NULL);
2242
2243 nfs_set_verifier(dentry,
2240 nfs_save_change_attribute(opendata->dir->d_inode)); 2244 nfs_save_change_attribute(opendata->dir->d_inode));
2241 } 2245 }
2242 goto out; 2246 goto out;
@@ -2622,23 +2626,23 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
2622 is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags); 2626 is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags);
2623 is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags); 2627 is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags);
2624 is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags); 2628 is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags);
2625 /* Calculate the current open share mode */
2626 calldata->arg.fmode = 0;
2627 if (is_rdonly || is_rdwr)
2628 calldata->arg.fmode |= FMODE_READ;
2629 if (is_wronly || is_rdwr)
2630 calldata->arg.fmode |= FMODE_WRITE;
2631 /* Calculate the change in open mode */ 2629 /* Calculate the change in open mode */
2630 calldata->arg.fmode = 0;
2632 if (state->n_rdwr == 0) { 2631 if (state->n_rdwr == 0) {
2633 if (state->n_rdonly == 0) { 2632 if (state->n_rdonly == 0)
2634 call_close |= is_rdonly || is_rdwr; 2633 call_close |= is_rdonly;
2635 calldata->arg.fmode &= ~FMODE_READ; 2634 else if (is_rdonly)
2636 } 2635 calldata->arg.fmode |= FMODE_READ;
2637 if (state->n_wronly == 0) { 2636 if (state->n_wronly == 0)
2638 call_close |= is_wronly || is_rdwr; 2637 call_close |= is_wronly;
2639 calldata->arg.fmode &= ~FMODE_WRITE; 2638 else if (is_wronly)
2640 } 2639 calldata->arg.fmode |= FMODE_WRITE;
2641 } 2640 } else if (is_rdwr)
2641 calldata->arg.fmode |= FMODE_READ|FMODE_WRITE;
2642
2643 if (calldata->arg.fmode == 0)
2644 call_close |= is_rdwr;
2645
2642 if (!nfs4_valid_open_stateid(state)) 2646 if (!nfs4_valid_open_stateid(state))
2643 call_close = 0; 2647 call_close = 0;
2644 spin_unlock(&state->owner->so_lock); 2648 spin_unlock(&state->owner->so_lock);
@@ -7368,7 +7372,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr
7368 int ret = 0; 7372 int ret = 0;
7369 7373
7370 if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0) 7374 if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
7371 return 0; 7375 return -EAGAIN;
7372 task = _nfs41_proc_sequence(clp, cred, false); 7376 task = _nfs41_proc_sequence(clp, cred, false);
7373 if (IS_ERR(task)) 7377 if (IS_ERR(task))
7374 ret = PTR_ERR(task); 7378 ret = PTR_ERR(task);
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 1720d32ffa54..e1ba58c3d1ad 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -88,10 +88,18 @@ nfs4_renew_state(struct work_struct *work)
88 } 88 }
89 nfs_expire_all_delegations(clp); 89 nfs_expire_all_delegations(clp);
90 } else { 90 } else {
91 int ret;
92
91 /* Queue an asynchronous RENEW. */ 93 /* Queue an asynchronous RENEW. */
92 ops->sched_state_renewal(clp, cred, renew_flags); 94 ret = ops->sched_state_renewal(clp, cred, renew_flags);
93 put_rpccred(cred); 95 put_rpccred(cred);
94 goto out_exp; 96 switch (ret) {
97 default:
98 goto out_exp;
99 case -EAGAIN:
100 case -ENOMEM:
101 break;
102 }
95 } 103 }
96 } else { 104 } else {
97 dprintk("%s: failed to call renewd. Reason: lease not expired \n", 105 dprintk("%s: failed to call renewd. Reason: lease not expired \n",
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 6678769e1a54..5194933ed419 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1705,7 +1705,8 @@ restart:
1705 if (status < 0) { 1705 if (status < 0) {
1706 set_bit(ops->owner_flag_bit, &sp->so_flags); 1706 set_bit(ops->owner_flag_bit, &sp->so_flags);
1707 nfs4_put_state_owner(sp); 1707 nfs4_put_state_owner(sp);
1708 return nfs4_recovery_handle_error(clp, status); 1708 status = nfs4_recovery_handle_error(clp, status);
1709 return (status != 0) ? status : -EAGAIN;
1709 } 1710 }
1710 1711
1711 nfs4_put_state_owner(sp); 1712 nfs4_put_state_owner(sp);
@@ -1714,7 +1715,7 @@ restart:
1714 spin_unlock(&clp->cl_lock); 1715 spin_unlock(&clp->cl_lock);
1715 } 1716 }
1716 rcu_read_unlock(); 1717 rcu_read_unlock();
1717 return status; 1718 return 0;
1718} 1719}
1719 1720
1720static int nfs4_check_lease(struct nfs_client *clp) 1721static int nfs4_check_lease(struct nfs_client *clp)
@@ -1761,7 +1762,6 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
1761 break; 1762 break;
1762 case -NFS4ERR_STALE_CLIENTID: 1763 case -NFS4ERR_STALE_CLIENTID:
1763 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 1764 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
1764 nfs4_state_clear_reclaim_reboot(clp);
1765 nfs4_state_start_reclaim_reboot(clp); 1765 nfs4_state_start_reclaim_reboot(clp);
1766 break; 1766 break;
1767 case -NFS4ERR_CLID_INUSE: 1767 case -NFS4ERR_CLID_INUSE:
@@ -2367,14 +2367,11 @@ static void nfs4_state_manager(struct nfs_client *clp)
2367 section = "reclaim reboot"; 2367 section = "reclaim reboot";
2368 status = nfs4_do_reclaim(clp, 2368 status = nfs4_do_reclaim(clp,
2369 clp->cl_mvops->reboot_recovery_ops); 2369 clp->cl_mvops->reboot_recovery_ops);
2370 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) || 2370 if (status == -EAGAIN)
2371 test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
2372 continue;
2373 nfs4_state_end_reclaim_reboot(clp);
2374 if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state))
2375 continue; 2371 continue;
2376 if (status < 0) 2372 if (status < 0)
2377 goto out_error; 2373 goto out_error;
2374 nfs4_state_end_reclaim_reboot(clp);
2378 } 2375 }
2379 2376
2380 /* Now recover expired state... */ 2377 /* Now recover expired state... */
@@ -2382,9 +2379,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
2382 section = "reclaim nograce"; 2379 section = "reclaim nograce";
2383 status = nfs4_do_reclaim(clp, 2380 status = nfs4_do_reclaim(clp,
2384 clp->cl_mvops->nograce_recovery_ops); 2381 clp->cl_mvops->nograce_recovery_ops);
2385 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) || 2382 if (status == -EAGAIN)
2386 test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) ||
2387 test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
2388 continue; 2383 continue;
2389 if (status < 0) 2384 if (status < 0)
2390 goto out_error; 2385 goto out_error;