Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db783688 authored by Jeff Layton's avatar Jeff Layton Committed by Anna Schumaker
Browse files

nfs: add handling for CB_NOTIFY_LOCK in client



For now, the callback doesn't do anything. Support for that will be
added in later patches.

Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent a8ce377a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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,
+12 −0
Original line number Diff line number Diff line
@@ -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 */
+50 −1
Original line number Diff line number Diff line
@@ -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
@@ -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)
@@ -746,6 +790,7 @@ 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;

@@ -753,7 +798,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
	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:
@@ -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 */
};