Skip to content

Commit

Permalink
nfs: add handling for CB_NOTIFY_LOCK in client
Browse files Browse the repository at this point in the history
For now, the callback doesn't do anything. Support for that will be
added in later patches.

Signed-off-by: Jeff Layton <[email protected]>
Signed-off-by: Anna Schumaker <[email protected]>
  • Loading branch information
jtlayton authored and amschuma-ntap committed Sep 22, 2016
1 parent a8ce377 commit db78368
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
9 changes: 9 additions & 0 deletions fs/nfs/callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,15 @@ extern __be32 nfs4_callback_devicenotify(
struct cb_devicenotifyargs *args,
void *dummy, struct cb_process_state *cps);

struct cb_notify_lock_args {
struct nfs_fh cbnl_fh;
struct nfs_lowner cbnl_owner;
bool cbnl_valid;
};

extern __be32 nfs4_callback_notify_lock(struct cb_notify_lock_args *args,
void *dummy,
struct cb_process_state *cps);
#endif /* CONFIG_NFS_V4_1 */
extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *);
extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args,
Expand Down
12 changes: 12 additions & 0 deletions fs/nfs/callback_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,4 +628,16 @@ __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy,
dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
return status;
}

__be32 nfs4_callback_notify_lock(struct cb_notify_lock_args *args, void *dummy,
struct cb_process_state *cps)
{
if (!cps->clp) /* set in cb_sequence */
return htonl(NFS4ERR_OP_NOT_IN_SESSION);

dprintk_rcu("NFS: CB_NOTIFY_LOCK request from %s\n",
rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR));

return htonl(NFS4_OK);
}
#endif /* CONFIG_NFS_V4_1 */
51 changes: 50 additions & 1 deletion fs/nfs/callback_xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
(1 + 3) * 4) // seqid, 3 slotids
#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#define CB_OP_NOTIFY_LOCK_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#endif /* CONFIG_NFS_V4_1 */

#define NFSDBG_FACILITY NFSDBG_CALLBACK
Expand Down Expand Up @@ -534,6 +535,49 @@ static __be32 decode_recallslot_args(struct svc_rqst *rqstp,
return 0;
}

static __be32 decode_lockowner(struct xdr_stream *xdr, struct cb_notify_lock_args *args)
{
__be32 *p;
unsigned int len;

p = read_buf(xdr, 12);
if (unlikely(p == NULL))
return htonl(NFS4ERR_BADXDR);

p = xdr_decode_hyper(p, &args->cbnl_owner.clientid);
len = be32_to_cpu(*p);

p = read_buf(xdr, len);
if (unlikely(p == NULL))
return htonl(NFS4ERR_BADXDR);

/* Only try to decode if the length is right */
if (len == 20) {
p += 2; /* skip "lock id:" */
args->cbnl_owner.s_dev = be32_to_cpu(*p++);
xdr_decode_hyper(p, &args->cbnl_owner.id);
args->cbnl_valid = true;
} else {
args->cbnl_owner.s_dev = 0;
args->cbnl_owner.id = 0;
args->cbnl_valid = false;
}
return 0;
}

static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_notify_lock_args *args)
{
__be32 status;

status = decode_fh(xdr, &args->cbnl_fh);
if (unlikely(status != 0))
goto out;
status = decode_lockowner(xdr, args);
out:
dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
return status;
}

#endif /* CONFIG_NFS_V4_1 */

static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
Expand Down Expand Up @@ -746,14 +790,14 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
case OP_CB_RECALL_SLOT:
case OP_CB_LAYOUTRECALL:
case OP_CB_NOTIFY_DEVICEID:
case OP_CB_NOTIFY_LOCK:
*op = &callback_ops[op_nr];
break;

case OP_CB_NOTIFY:
case OP_CB_PUSH_DELEG:
case OP_CB_RECALLABLE_OBJ_AVAIL:
case OP_CB_WANTS_CANCELLED:
case OP_CB_NOTIFY_LOCK:
return htonl(NFS4ERR_NOTSUPP);

default:
Expand Down Expand Up @@ -1006,6 +1050,11 @@ static struct callback_op callback_ops[] = {
.decode_args = (callback_decode_arg_t)decode_recallslot_args,
.res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ,
},
[OP_CB_NOTIFY_LOCK] = {
.process_op = (callback_process_op_t)nfs4_callback_notify_lock,
.decode_args = (callback_decode_arg_t)decode_notify_lock_args,
.res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ,
},
#endif /* CONFIG_NFS_V4_1 */
};

Expand Down

0 comments on commit db78368

Please sign in to comment.