aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-06-22 09:55:08 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-06-22 09:55:08 -0400
commit1372a3130a3e0bfd38d82d476f0a907cc72ba816 (patch)
treec9ca766000cd37914bf68e0d466cf4ab922498bf /fs
parent775f06ab49f5f9e2f6bca9292ef57efa868a0f67 (diff)
parentc70701131f7a8edea91fc49d11796d342cff7c62 (diff)
Merge branch 'bugfixes'
* bugfixes: NFS: Ensure we set NFS_CONTEXT_RESEND_WRITES when requeuing writes pNFS: Fix a memory leak when attempted pnfs fails NFS: Ensure that we update the sequence id under the slot table lock nfs: Initialize cb_sequenceres information before validate_seqid() nfs: Only update callback sequnce id when CB_SEQUENCE success NFSv4: nfs4_handle_delegation_recall_error should ignore EAGAIN
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/callback_proc.c38
-rw-r--r--fs/nfs/nfs4proc.c1
-rw-r--r--fs/nfs/pnfs.c3
-rw-r--r--fs/nfs/write.c1
4 files changed, 28 insertions, 15 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 197806fb87ff..29e3c1b011b7 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -327,10 +327,8 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
327 dprintk("%s slot table seqid: %u\n", __func__, slot->seq_nr); 327 dprintk("%s slot table seqid: %u\n", __func__, slot->seq_nr);
328 328
329 /* Normal */ 329 /* Normal */
330 if (likely(args->csa_sequenceid == slot->seq_nr + 1)) { 330 if (likely(args->csa_sequenceid == slot->seq_nr + 1))
331 slot->seq_nr++;
332 goto out_ok; 331 goto out_ok;
333 }
334 332
335 /* Replay */ 333 /* Replay */
336 if (args->csa_sequenceid == slot->seq_nr) { 334 if (args->csa_sequenceid == slot->seq_nr) {
@@ -418,6 +416,7 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
418 struct cb_process_state *cps) 416 struct cb_process_state *cps)
419{ 417{
420 struct nfs4_slot_table *tbl; 418 struct nfs4_slot_table *tbl;
419 struct nfs4_slot *slot;
421 struct nfs_client *clp; 420 struct nfs_client *clp;
422 int i; 421 int i;
423 __be32 status = htonl(NFS4ERR_BADSESSION); 422 __be32 status = htonl(NFS4ERR_BADSESSION);
@@ -429,25 +428,32 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
429 428
430 if (!(clp->cl_session->flags & SESSION4_BACK_CHAN)) 429 if (!(clp->cl_session->flags & SESSION4_BACK_CHAN))
431 goto out; 430 goto out;
431
432 tbl = &clp->cl_session->bc_slot_table; 432 tbl = &clp->cl_session->bc_slot_table;
433 slot = tbl->slots + args->csa_slotid;
433 434
434 spin_lock(&tbl->slot_tbl_lock); 435 spin_lock(&tbl->slot_tbl_lock);
435 /* state manager is resetting the session */ 436 /* state manager is resetting the session */
436 if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) { 437 if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) {
437 spin_unlock(&tbl->slot_tbl_lock);
438 status = htonl(NFS4ERR_DELAY); 438 status = htonl(NFS4ERR_DELAY);
439 /* Return NFS4ERR_BADSESSION if we're draining the session 439 /* Return NFS4ERR_BADSESSION if we're draining the session
440 * in order to reset it. 440 * in order to reset it.
441 */ 441 */
442 if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) 442 if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
443 status = htonl(NFS4ERR_BADSESSION); 443 status = htonl(NFS4ERR_BADSESSION);
444 goto out; 444 goto out_unlock;
445 } 445 }
446 446
447 status = validate_seqid(&clp->cl_session->bc_slot_table, args); 447 memcpy(&res->csr_sessionid, &args->csa_sessionid,
448 spin_unlock(&tbl->slot_tbl_lock); 448 sizeof(res->csr_sessionid));
449 res->csr_sequenceid = args->csa_sequenceid;
450 res->csr_slotid = args->csa_slotid;
451 res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
452 res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
453
454 status = validate_seqid(tbl, args);
449 if (status) 455 if (status)
450 goto out; 456 goto out_unlock;
451 457
452 cps->slotid = args->csa_slotid; 458 cps->slotid = args->csa_slotid;
453 459
@@ -458,15 +464,17 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
458 */ 464 */
459 if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) { 465 if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) {
460 status = htonl(NFS4ERR_DELAY); 466 status = htonl(NFS4ERR_DELAY);
461 goto out; 467 goto out_unlock;
462 } 468 }
463 469
464 memcpy(&res->csr_sessionid, &args->csa_sessionid, 470 /*
465 sizeof(res->csr_sessionid)); 471 * RFC5661 20.9.3
466 res->csr_sequenceid = args->csa_sequenceid; 472 * If CB_SEQUENCE returns an error, then the state of the slot
467 res->csr_slotid = args->csa_slotid; 473 * (sequence ID, cached reply) MUST NOT change.
468 res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; 474 */
469 res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; 475 slot->seq_nr++;
476out_unlock:
477 spin_unlock(&tbl->slot_tbl_lock);
470 478
471out: 479out:
472 cps->clp = clp; /* put in nfs4_callback_compound */ 480 cps->clp = clp; /* put in nfs4_callback_compound */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0fc1b0cdda98..e9cd45f1d60f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1678,6 +1678,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
1678 "%d.\n", __func__, err); 1678 "%d.\n", __func__, err);
1679 case 0: 1679 case 0:
1680 case -ENOENT: 1680 case -ENOENT:
1681 case -EAGAIN:
1681 case -ESTALE: 1682 case -ESTALE:
1682 break; 1683 break;
1683 case -NFS4ERR_BADSESSION: 1684 case -NFS4ERR_BADSESSION:
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 230606243be6..d47c188682b1 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1821,6 +1821,7 @@ int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *hdr)
1821 /* Resend all requests through the MDS */ 1821 /* Resend all requests through the MDS */
1822 nfs_pageio_init_write(&pgio, hdr->inode, FLUSH_STABLE, true, 1822 nfs_pageio_init_write(&pgio, hdr->inode, FLUSH_STABLE, true,
1823 hdr->completion_ops); 1823 hdr->completion_ops);
1824 set_bit(NFS_CONTEXT_RESEND_WRITES, &hdr->args.context->flags);
1824 return nfs_pageio_resend(&pgio, hdr); 1825 return nfs_pageio_resend(&pgio, hdr);
1825} 1826}
1826EXPORT_SYMBOL_GPL(pnfs_write_done_resend_to_mds); 1827EXPORT_SYMBOL_GPL(pnfs_write_done_resend_to_mds);
@@ -1865,6 +1866,7 @@ pnfs_write_through_mds(struct nfs_pageio_descriptor *desc,
1865 mirror->pg_recoalesce = 1; 1866 mirror->pg_recoalesce = 1;
1866 } 1867 }
1867 nfs_pgio_data_destroy(hdr); 1868 nfs_pgio_data_destroy(hdr);
1869 hdr->release(hdr);
1868} 1870}
1869 1871
1870static enum pnfs_try_status 1872static enum pnfs_try_status
@@ -1979,6 +1981,7 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc,
1979 mirror->pg_recoalesce = 1; 1981 mirror->pg_recoalesce = 1;
1980 } 1982 }
1981 nfs_pgio_data_destroy(hdr); 1983 nfs_pgio_data_destroy(hdr);
1984 hdr->release(hdr);
1982} 1985}
1983 1986
1984/* 1987/*
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index d0f1f210342e..84ba7268833d 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1289,6 +1289,7 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr,
1289static void nfs_redirty_request(struct nfs_page *req) 1289static void nfs_redirty_request(struct nfs_page *req)
1290{ 1290{
1291 nfs_mark_request_dirty(req); 1291 nfs_mark_request_dirty(req);
1292 set_bit(NFS_CONTEXT_RESEND_WRITES, &req->wb_context->flags);
1292 nfs_unlock_request(req); 1293 nfs_unlock_request(req);
1293 nfs_end_page_writeback(req); 1294 nfs_end_page_writeback(req);
1294 nfs_release_request(req); 1295 nfs_release_request(req);