NFSv4: Fix up handling of open_to_lock sequence ids
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
faf5f49c2d
commit
06735b3454
|
@ -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 inode *inode = state->inode;
|
||||||
struct nfs_server *server = NFS_SERVER(inode);
|
struct nfs_server *server = NFS_SERVER(inode);
|
||||||
struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
|
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 = {
|
struct nfs_lockargs arg = {
|
||||||
.fh = NFS_FH(inode),
|
.fh = NFS_FH(inode),
|
||||||
.type = nfs4_lck_type(cmd, request),
|
.type = nfs4_lck_type(cmd, request),
|
||||||
.offset = request->fl_start,
|
.offset = request->fl_start,
|
||||||
.length = nfs4_lck_length(request),
|
.length = nfs4_lck_length(request),
|
||||||
|
.u = {
|
||||||
|
.lock = &largs,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
struct nfs_lockres res = {
|
struct nfs_lockres res = {
|
||||||
.server = server,
|
.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_resp = &res,
|
||||||
.rpc_cred = state->owner->so_cred,
|
.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;
|
int status = -ENOMEM;
|
||||||
|
|
||||||
lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
|
largs.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
|
||||||
if (lock_seqid == NULL)
|
if (largs.lock_seqid == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) {
|
if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) {
|
||||||
struct nfs4_state_owner *owner = state->owner;
|
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;
|
largs.open_seqid = nfs_alloc_seqid(&owner->so_seqid);
|
||||||
otl.lock_owner.id = lsp->ls_id;
|
if (largs.open_seqid == NULL)
|
||||||
memcpy(&otl.open_stateid, &state->stateid, sizeof(otl.open_stateid));
|
goto out;
|
||||||
largs.u.open_lock = &otl;
|
|
||||||
largs.new_lock_owner = 1;
|
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);
|
|
||||||
}
|
|
||||||
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 = ⪙
|
|
||||||
arg.u.lock = &largs;
|
|
||||||
el.seqid = lock_seqid;
|
|
||||||
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
|
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
|
||||||
}
|
/* increment open seqid on success, and seqid mutating errors */
|
||||||
/* increment seqid on success, and seqid mutating errors*/
|
if (largs.new_lock_owner != 0) {
|
||||||
nfs_increment_lock_seqid(status, lock_seqid);
|
nfs_increment_open_seqid(status, largs.open_seqid);
|
||||||
|
if (status == 0)
|
||||||
|
nfs_confirm_seqid(&lsp->ls_seqid, 0);
|
||||||
|
}
|
||||||
|
nfs_free_seqid(largs.open_seqid);
|
||||||
|
} else
|
||||||
|
status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
|
||||||
|
/* increment lock seqid on success, and seqid mutating errors*/
|
||||||
|
nfs_increment_lock_seqid(status, largs.lock_seqid);
|
||||||
/* save the returned stateid. */
|
/* save the returned stateid. */
|
||||||
if (status == 0) {
|
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;
|
lsp->ls_flags |= NFS_LOCK_INITIALIZED;
|
||||||
} else if (status == -NFS4ERR_DENIED)
|
} else if (status == -NFS4ERR_DENIED)
|
||||||
status = -EAGAIN;
|
status = -EAGAIN;
|
||||||
nfs_free_seqid(lock_seqid);
|
out:
|
||||||
|
nfs_free_seqid(largs.lock_seqid);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -729,22 +729,18 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
|
||||||
WRITE64(arg->length);
|
WRITE64(arg->length);
|
||||||
WRITE32(opargs->new_lock_owner);
|
WRITE32(opargs->new_lock_owner);
|
||||||
if (opargs->new_lock_owner){
|
if (opargs->new_lock_owner){
|
||||||
struct nfs_open_to_lock *ol = opargs->u.open_lock;
|
|
||||||
|
|
||||||
RESERVE_SPACE(40);
|
RESERVE_SPACE(40);
|
||||||
WRITE32(ol->open_seqid->sequence->counter);
|
WRITE32(opargs->open_seqid->sequence->counter);
|
||||||
WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid));
|
WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data));
|
||||||
WRITE32(ol->lock_seqid->sequence->counter);
|
WRITE32(opargs->lock_seqid->sequence->counter);
|
||||||
WRITE64(ol->lock_owner.clientid);
|
WRITE64(opargs->lock_owner.clientid);
|
||||||
WRITE32(4);
|
WRITE32(4);
|
||||||
WRITE32(ol->lock_owner.id);
|
WRITE32(opargs->lock_owner.id);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
struct nfs_exist_lock *el = opargs->u.exist_lock;
|
|
||||||
|
|
||||||
RESERVE_SPACE(20);
|
RESERVE_SPACE(20);
|
||||||
WRITEMEM(&el->stateid, sizeof(el->stateid));
|
WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data));
|
||||||
WRITE32(el->seqid->sequence->counter);
|
WRITE32(opargs->lock_seqid->sequence->counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1535,16 +1531,14 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka
|
||||||
.nops = 2,
|
.nops = 2,
|
||||||
};
|
};
|
||||||
struct nfs_lock_opargs *opargs = args->u.lock;
|
struct nfs_lock_opargs *opargs = args->u.lock;
|
||||||
struct nfs_seqid *seqid;
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (opargs->new_lock_owner)
|
status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task);
|
||||||
seqid = opargs->u.open_lock->lock_seqid;
|
|
||||||
else
|
|
||||||
seqid = opargs->u.exist_lock->seqid;
|
|
||||||
status = nfs_wait_on_sequence(seqid, req->rq_task);
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
goto out;
|
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);
|
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
|
||||||
encode_compound_hdr(&xdr, &hdr);
|
encode_compound_hdr(&xdr, &hdr);
|
||||||
status = encode_putfh(&xdr, args->fh);
|
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);
|
status = decode_op_hdr(xdr, OP_LOCK);
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
READ_BUF(sizeof(nfs4_stateid));
|
READ_BUF(sizeof(res->u.stateid.data));
|
||||||
COPYMEM(&res->u.stateid, sizeof(res->u.stateid));
|
COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
|
||||||
} else if (status == -NFS4ERR_DENIED)
|
} else if (status == -NFS4ERR_DENIED)
|
||||||
return decode_lock_denied(xdr, &res->u.denied);
|
return decode_lock_denied(xdr, &res->u.denied);
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -165,25 +165,14 @@ struct nfs_lowner {
|
||||||
u32 id;
|
u32 id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfs_open_to_lock {
|
|
||||||
struct nfs_seqid * open_seqid;
|
|
||||||
nfs4_stateid open_stateid;
|
|
||||||
struct nfs_seqid * lock_seqid;
|
|
||||||
struct nfs_lowner lock_owner;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nfs_exist_lock {
|
|
||||||
nfs4_stateid stateid;
|
|
||||||
struct nfs_seqid * seqid;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nfs_lock_opargs {
|
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;
|
||||||
__u32 reclaim;
|
__u32 reclaim;
|
||||||
__u32 new_lock_owner;
|
__u32 new_lock_owner;
|
||||||
union {
|
|
||||||
struct nfs_open_to_lock *open_lock;
|
|
||||||
struct nfs_exist_lock *exist_lock;
|
|
||||||
} u;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfs_locku_opargs {
|
struct nfs_locku_opargs {
|
||||||
|
|
Loading…
Reference in New Issue