NFSv4: Fix up handling of open_to_lock sequence ids
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 18 Oct 2005 21:20:15 +0000 (14:20 -0700)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 18 Oct 2005 21:20:15 +0000 (14:20 -0700)
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
include/linux/nfs_xdr.h

index 612a9a1..35da153 100644 (file)
@@ -2889,11 +2889,23 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
        struct inode *inode = state->inode;
        struct nfs_server *server = NFS_SERVER(inode);
        struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
+       struct nfs_lock_opargs largs = {
+               .lock_stateid = &lsp->ls_stateid,
+               .open_stateid = &state->stateid,
+               .lock_owner = {
+                       .clientid = server->nfs4_state->cl_clientid,
+                       .id = lsp->ls_id,
+               },
+               .reclaim = reclaim,
+       };
        struct nfs_lockargs arg = {
                .fh = NFS_FH(inode),
                .type = nfs4_lck_type(cmd, request),
                .offset = request->fl_start,
                .length = nfs4_lck_length(request),
+               .u = {
+                       .lock = &largs,
+               },
        };
        struct nfs_lockres res = {
                .server = server,
@@ -2904,56 +2916,39 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
                .rpc_resp       = &res,
                .rpc_cred       = state->owner->so_cred,
        };
-       struct nfs_lock_opargs largs = {
-               .reclaim = reclaim,
-               .new_lock_owner = 0,
-       };
-       struct nfs_seqid *lock_seqid;
        int status = -ENOMEM;
 
-       lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
-       if (lock_seqid == NULL)
+       largs.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+       if (largs.lock_seqid == NULL)
                return -ENOMEM;
        if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) {
                struct nfs4_state_owner *owner = state->owner;
-               struct nfs_open_to_lock otl = {
-                       .lock_owner = {
-                               .clientid = server->nfs4_state->cl_clientid,
-                       },
-               };
-
-               otl.lock_seqid = lock_seqid;
-               otl.lock_owner.id = lsp->ls_id;
-               memcpy(&otl.open_stateid, &state->stateid, sizeof(otl.open_stateid));
-               largs.u.open_lock = &otl;
+
+               largs.open_seqid = nfs_alloc_seqid(&owner->so_seqid);
+               if (largs.open_seqid == NULL)
+                       goto out;
                largs.new_lock_owner = 1;
-               arg.u.lock = &largs;
-               otl.open_seqid = nfs_alloc_seqid(&owner->so_seqid);
-               if (otl.open_seqid != NULL) {
-                       status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
-                       /* increment seqid on success, and seqid mutating errors */
-                       nfs_increment_open_seqid(status, otl.open_seqid);
-                       nfs_free_seqid(otl.open_seqid);
+               status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+               /* increment open seqid on success, and seqid mutating errors */
+               if (largs.new_lock_owner != 0) {
+                       nfs_increment_open_seqid(status, largs.open_seqid);
+                       if (status == 0)
+                               nfs_confirm_seqid(&lsp->ls_seqid, 0);
                }
-               if (status == 0)
-                       nfs_confirm_seqid(&lsp->ls_seqid, 0);
-       } else {
-               struct nfs_exist_lock el;
-               memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid));
-               largs.u.exist_lock = &el;
-               arg.u.lock = &largs;
-               el.seqid = lock_seqid;
+               nfs_free_seqid(largs.open_seqid);
+       } else
                status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
-       }
-       /* increment seqid on success, and seqid mutating errors*/
-       nfs_increment_lock_seqid(status, lock_seqid);
+       /* increment lock seqid on success, and seqid mutating errors*/
+       nfs_increment_lock_seqid(status, largs.lock_seqid);
        /* save the returned stateid. */
        if (status == 0) {
-               memcpy(lsp->ls_stateid.data, res.u.stateid.data, sizeof(lsp->ls_stateid.data));
+               memcpy(lsp->ls_stateid.data, res.u.stateid.data,
+                               sizeof(lsp->ls_stateid.data));
                lsp->ls_flags |= NFS_LOCK_INITIALIZED;
        } else if (status == -NFS4ERR_DENIED)
                status = -EAGAIN;
-       nfs_free_seqid(lock_seqid);
+out:
+       nfs_free_seqid(largs.lock_seqid);
        return status;
 }
 
index 4706192..c5c7523 100644 (file)
@@ -729,22 +729,18 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
        WRITE64(arg->length);
        WRITE32(opargs->new_lock_owner);
        if (opargs->new_lock_owner){
-               struct nfs_open_to_lock *ol = opargs->u.open_lock;
-
                RESERVE_SPACE(40);
-               WRITE32(ol->open_seqid->sequence->counter);
-               WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid));
-               WRITE32(ol->lock_seqid->sequence->counter);
-               WRITE64(ol->lock_owner.clientid);
+               WRITE32(opargs->open_seqid->sequence->counter);
+               WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data));
+               WRITE32(opargs->lock_seqid->sequence->counter);
+               WRITE64(opargs->lock_owner.clientid);
                WRITE32(4);
-               WRITE32(ol->lock_owner.id);
+               WRITE32(opargs->lock_owner.id);
        }
        else {
-               struct nfs_exist_lock *el = opargs->u.exist_lock;
-
                RESERVE_SPACE(20);
-               WRITEMEM(&el->stateid, sizeof(el->stateid));
-               WRITE32(el->seqid->sequence->counter);
+               WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data));
+               WRITE32(opargs->lock_seqid->sequence->counter);
        }
 
        return 0;
@@ -1535,16 +1531,14 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka
                .nops   = 2,
        };
        struct nfs_lock_opargs *opargs = args->u.lock;
-       struct nfs_seqid *seqid;
        int status;
 
-       if (opargs->new_lock_owner)
-               seqid = opargs->u.open_lock->lock_seqid;
-       else
-               seqid = opargs->u.exist_lock->seqid;
-       status = nfs_wait_on_sequence(seqid, req->rq_task);
+       status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task);
        if (status != 0)
                goto out;
+       /* Do we need to do an open_to_lock_owner? */
+       if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)
+               opargs->new_lock_owner = 0;
        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
        encode_compound_hdr(&xdr, &hdr);
        status = encode_putfh(&xdr, args->fh);
@@ -2908,8 +2902,8 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res)
 
        status = decode_op_hdr(xdr, OP_LOCK);
        if (status == 0) {
-               READ_BUF(sizeof(nfs4_stateid));
-               COPYMEM(&res->u.stateid, sizeof(res->u.stateid));
+               READ_BUF(sizeof(res->u.stateid.data));
+               COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
        } else if (status == -NFS4ERR_DENIED)
                return decode_lock_denied(xdr, &res->u.denied);
        return status;
index 849f95c..57efcc2 100644 (file)
@@ -165,25 +165,14 @@ struct nfs_lowner {
        u32                     id;
 };
 
-struct nfs_open_to_lock {
-       struct nfs_seqid *      open_seqid;
-       nfs4_stateid            open_stateid;
+struct nfs_lock_opargs {
        struct nfs_seqid *      lock_seqid;
+       nfs4_stateid *          lock_stateid;
+       struct nfs_seqid *      open_seqid;
+       nfs4_stateid *          open_stateid;
        struct nfs_lowner       lock_owner;
-};
-
-struct nfs_exist_lock {
-       nfs4_stateid            stateid;
-       struct nfs_seqid *      seqid;
-};
-
-struct nfs_lock_opargs {
        __u32                   reclaim;
        __u32                   new_lock_owner;
-       union {
-               struct nfs_open_to_lock *open_lock;
-               struct nfs_exist_lock   *exist_lock;
-       } u;
 };
 
 struct nfs_locku_opargs {