diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-18 17:20:12 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-18 17:20:12 -0400 |
commit | 9512135df14f8293b9bc5e8fb22d4279dee5ff66 (patch) | |
tree | 83fb778ed53ba10c46734968f538aa0a57d376a1 /fs/nfs/nfs4xdr.c | |
parent | cee54fc944422c44e476736c045a9e8053cb0644 (diff) |
NFSv4: Fix a potential CLOSE race
Once the state_owner and lock_owner semaphores get removed, it will be
possible for other OPEN requests to reopen the same file if they have
lower sequence ids than our CLOSE call.
This patch ensures that we recheck the file state once
nfs_wait_on_sequence() has completed waiting.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 14 |
1 files changed, 4 insertions, 10 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index fcd28a29a2f8..934ec50ea6bf 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -602,10 +602,10 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg) | |||
602 | { | 602 | { |
603 | uint32_t *p; | 603 | uint32_t *p; |
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->sequence->counter); | 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; |
611 | } | 611 | } |
@@ -950,9 +950,9 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea | |||
950 | { | 950 | { |
951 | uint32_t *p; | 951 | uint32_t *p; |
952 | 952 | ||
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->sequence->counter); | 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; |
@@ -1416,9 +1416,6 @@ 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; | ||
1422 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1419 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1423 | encode_compound_hdr(&xdr, &hdr); | 1420 | encode_compound_hdr(&xdr, &hdr); |
1424 | status = encode_putfh(&xdr, args->fh); | 1421 | status = encode_putfh(&xdr, args->fh); |
@@ -1518,9 +1515,6 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct | |||
1518 | }; | 1515 | }; |
1519 | int status; | 1516 | int status; |
1520 | 1517 | ||
1521 | status = nfs_wait_on_sequence(args->seqid, req->rq_task); | ||
1522 | if (status != 0) | ||
1523 | goto out; | ||
1524 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1518 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1525 | encode_compound_hdr(&xdr, &hdr); | 1519 | encode_compound_hdr(&xdr, &hdr); |
1526 | status = encode_putfh(&xdr, args->fh); | 1520 | status = encode_putfh(&xdr, args->fh); |