aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:12 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:12 -0400
commitcee54fc944422c44e476736c045a9e8053cb0644 (patch)
tree95f4728b3ffa8a2456727b10cd3a68f2a3065415 /fs/nfs/nfs4xdr.c
parent5e5ce5be6f0161d2a069a4f8a1154fe639c5c02f (diff)
NFSv4: Add functions to order RPC calls
NFSv4 file state-changing functions such as OPEN, CLOSE, LOCK,... are all labelled with "sequence identifiers" in order to prevent the server from reordering RPC requests, as this could cause its file state to become out of sync with the client. Currently the NFS client code enforces this ordering locally using semaphores to restrict access to structures until the RPC call is done. This, of course, only works with synchronous RPC calls, since the user process must first grab the semaphore. By dropping semaphores, and instead teaching the RPC engine to hold the RPC calls until they are ready to be sent, we can extend this process to work nicely with asynchronous RPC calls too. This patch adds a new list called "rpc_sequence" that defines the order of the RPC calls to be sent. We add one such list for each state_owner. When an RPC call is ready to be sent, it checks if it is top of the rpc_sequence list. If so, it proceeds. If not, it goes back to sleep, and loops until it hits top of the list. Once the RPC call has completed, it can then bump the sequence id counter, and remove itself from the rpc_sequence list, and then wake up the next sleeper. Note that the state_owner sequence ids and lock_owner sequence ids are all indexed to the same rpc_sequence list, so OPEN, LOCK,... requests are all ordered w.r.t. each other. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 6c564ef9489e..fcd28a29a2f8 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -604,7 +604,7 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
604 604
605 RESERVE_SPACE(8+sizeof(arg->stateid.data)); 605 RESERVE_SPACE(8+sizeof(arg->stateid.data));
606 WRITE32(OP_CLOSE); 606 WRITE32(OP_CLOSE);
607 WRITE32(arg->seqid); 607 WRITE32(arg->seqid->sequence->counter);
608 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); 608 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
609 609
610 return 0; 610 return 0;
@@ -732,9 +732,9 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
732 struct nfs_open_to_lock *ol = opargs->u.open_lock; 732 struct nfs_open_to_lock *ol = opargs->u.open_lock;
733 733
734 RESERVE_SPACE(40); 734 RESERVE_SPACE(40);
735 WRITE32(ol->open_seqid); 735 WRITE32(ol->open_seqid->sequence->counter);
736 WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid)); 736 WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid));
737 WRITE32(ol->lock_seqid); 737 WRITE32(ol->lock_seqid->sequence->counter);
738 WRITE64(ol->lock_owner.clientid); 738 WRITE64(ol->lock_owner.clientid);
739 WRITE32(4); 739 WRITE32(4);
740 WRITE32(ol->lock_owner.id); 740 WRITE32(ol->lock_owner.id);
@@ -744,7 +744,7 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
744 744
745 RESERVE_SPACE(20); 745 RESERVE_SPACE(20);
746 WRITEMEM(&el->stateid, sizeof(el->stateid)); 746 WRITEMEM(&el->stateid, sizeof(el->stateid));
747 WRITE32(el->seqid); 747 WRITE32(el->seqid->sequence->counter);
748 } 748 }
749 749
750 return 0; 750 return 0;
@@ -775,7 +775,7 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
775 RESERVE_SPACE(44); 775 RESERVE_SPACE(44);
776 WRITE32(OP_LOCKU); 776 WRITE32(OP_LOCKU);
777 WRITE32(arg->type); 777 WRITE32(arg->type);
778 WRITE32(opargs->seqid); 778 WRITE32(opargs->seqid->sequence->counter);
779 WRITEMEM(&opargs->stateid, sizeof(opargs->stateid)); 779 WRITEMEM(&opargs->stateid, sizeof(opargs->stateid));
780 WRITE64(arg->offset); 780 WRITE64(arg->offset);
781 WRITE64(arg->length); 781 WRITE64(arg->length);
@@ -826,7 +826,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
826 */ 826 */
827 RESERVE_SPACE(8); 827 RESERVE_SPACE(8);
828 WRITE32(OP_OPEN); 828 WRITE32(OP_OPEN);
829 WRITE32(arg->seqid); 829 WRITE32(arg->seqid->sequence->counter);
830 encode_share_access(xdr, arg->open_flags); 830 encode_share_access(xdr, arg->open_flags);
831 RESERVE_SPACE(16); 831 RESERVE_SPACE(16);
832 WRITE64(arg->clientid); 832 WRITE64(arg->clientid);
@@ -941,7 +941,7 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con
941 RESERVE_SPACE(8+sizeof(arg->stateid.data)); 941 RESERVE_SPACE(8+sizeof(arg->stateid.data));
942 WRITE32(OP_OPEN_CONFIRM); 942 WRITE32(OP_OPEN_CONFIRM);
943 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); 943 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
944 WRITE32(arg->seqid); 944 WRITE32(arg->seqid->sequence->counter);
945 945
946 return 0; 946 return 0;
947} 947}
@@ -953,7 +953,7 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea
953 RESERVE_SPACE(8+sizeof(arg->stateid.data)); 953 RESERVE_SPACE(8+sizeof(arg->stateid.data));
954 WRITE32(OP_OPEN_DOWNGRADE); 954 WRITE32(OP_OPEN_DOWNGRADE);
955 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); 955 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
956 WRITE32(arg->seqid); 956 WRITE32(arg->seqid->sequence->counter);
957 encode_share_access(xdr, arg->open_flags); 957 encode_share_access(xdr, arg->open_flags);
958 return 0; 958 return 0;
959} 959}
@@ -1416,6 +1416,9 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos
1416 }; 1416 };
1417 int status; 1417 int status;
1418 1418
1419 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1420 if (status != 0)
1421 goto out;
1419 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1422 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1420 encode_compound_hdr(&xdr, &hdr); 1423 encode_compound_hdr(&xdr, &hdr);
1421 status = encode_putfh(&xdr, args->fh); 1424 status = encode_putfh(&xdr, args->fh);
@@ -1437,6 +1440,9 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
1437 }; 1440 };
1438 int status; 1441 int status;
1439 1442
1443 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1444 if (status != 0)
1445 goto out;
1440 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1446 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1441 encode_compound_hdr(&xdr, &hdr); 1447 encode_compound_hdr(&xdr, &hdr);
1442 status = encode_putfh(&xdr, args->fh); 1448 status = encode_putfh(&xdr, args->fh);
@@ -1464,6 +1470,9 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n
1464 }; 1470 };
1465 int status; 1471 int status;
1466 1472
1473 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1474 if (status != 0)
1475 goto out;
1467 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1476 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1468 encode_compound_hdr(&xdr, &hdr); 1477 encode_compound_hdr(&xdr, &hdr);
1469 status = encode_putfh(&xdr, args->fh); 1478 status = encode_putfh(&xdr, args->fh);
@@ -1485,6 +1494,9 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nf
1485 }; 1494 };
1486 int status; 1495 int status;
1487 1496
1497 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1498 if (status != 0)
1499 goto out;
1488 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1500 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1489 encode_compound_hdr(&xdr, &hdr); 1501 encode_compound_hdr(&xdr, &hdr);
1490 status = encode_putfh(&xdr, args->fh); 1502 status = encode_putfh(&xdr, args->fh);
@@ -1506,6 +1518,9 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
1506 }; 1518 };
1507 int status; 1519 int status;
1508 1520
1521 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1522 if (status != 0)
1523 goto out;
1509 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1524 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1510 encode_compound_hdr(&xdr, &hdr); 1525 encode_compound_hdr(&xdr, &hdr);
1511 status = encode_putfh(&xdr, args->fh); 1526 status = encode_putfh(&xdr, args->fh);
@@ -1525,8 +1540,17 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka
1525 struct compound_hdr hdr = { 1540 struct compound_hdr hdr = {
1526 .nops = 2, 1541 .nops = 2,
1527 }; 1542 };
1543 struct nfs_lock_opargs *opargs = args->u.lock;
1544 struct nfs_seqid *seqid;
1528 int status; 1545 int status;
1529 1546
1547 if (opargs->new_lock_owner)
1548 seqid = opargs->u.open_lock->lock_seqid;
1549 else
1550 seqid = opargs->u.exist_lock->seqid;
1551 status = nfs_wait_on_sequence(seqid, req->rq_task);
1552 if (status != 0)
1553 goto out;
1530 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1554 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1531 encode_compound_hdr(&xdr, &hdr); 1555 encode_compound_hdr(&xdr, &hdr);
1532 status = encode_putfh(&xdr, args->fh); 1556 status = encode_putfh(&xdr, args->fh);
@@ -1569,6 +1593,9 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lock
1569 }; 1593 };
1570 int status; 1594 int status;
1571 1595
1596 status = nfs_wait_on_sequence(args->u.locku->seqid, req->rq_task);
1597 if (status != 0)
1598 goto out;
1572 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1599 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1573 encode_compound_hdr(&xdr, &hdr); 1600 encode_compound_hdr(&xdr, &hdr);
1574 status = encode_putfh(&xdr, args->fh); 1601 status = encode_putfh(&xdr, args->fh);