Commit 8918cc0d authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: Add helper for decoding locker4



Refactor for clarity.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 144e8269
Loading
Loading
Loading
Loading
+43 −21
Original line number Diff line number Diff line
@@ -833,6 +833,48 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
	return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen);
}

static __be32
nfsd4_decode_open_to_lock_owner4(struct nfsd4_compoundargs *argp,
				 struct nfsd4_lock *lock)
{
	__be32 status;

	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_open_seqid) < 0)
		return nfserr_bad_xdr;
	status = nfsd4_decode_stateid4(argp, &lock->lk_new_open_stateid);
	if (status)
		return status;
	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_lock_seqid) < 0)
		return nfserr_bad_xdr;
	return nfsd4_decode_state_owner4(argp, &lock->lk_new_clientid,
					 &lock->lk_new_owner);
}

static __be32
nfsd4_decode_exist_lock_owner4(struct nfsd4_compoundargs *argp,
			       struct nfsd4_lock *lock)
{
	__be32 status;

	status = nfsd4_decode_stateid4(argp, &lock->lk_old_lock_stateid);
	if (status)
		return status;
	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_old_lock_seqid) < 0)
		return nfserr_bad_xdr;

	return nfs_ok;
}

static __be32
nfsd4_decode_locker4(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
{
	if (xdr_stream_decode_bool(argp->xdr, &lock->lk_is_new) < 0)
		return nfserr_bad_xdr;
	if (lock->lk_is_new)
		return nfsd4_decode_open_to_lock_owner4(argp, lock);
	return nfsd4_decode_exist_lock_owner4(argp, lock);
}

static __be32
nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
{
@@ -848,27 +890,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
	lock->lk_reclaim = be32_to_cpup(p++);
	p = xdr_decode_hyper(p, &lock->lk_offset);
	p = xdr_decode_hyper(p, &lock->lk_length);
	lock->lk_is_new = be32_to_cpup(p++);

	if (lock->lk_is_new) {
		READ_BUF(4);
		lock->lk_new_open_seqid = be32_to_cpup(p++);
		status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
		if (status)
			return status;
		READ_BUF(4);
		lock->lk_new_lock_seqid = be32_to_cpup(p++);
		status = nfsd4_decode_state_owner4(argp, &lock->lk_new_clientid,
						   &lock->lk_new_owner);
		if (status)
			return status;
	} else {
		status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
		if (status)
			return status;
		READ_BUF(4);
		lock->lk_old_lock_seqid = be32_to_cpup(p++);
	}
	status = nfsd4_decode_locker4(argp, lock);

	DECODE_TAIL;
}
+21 −0
Original line number Diff line number Diff line
@@ -550,6 +550,27 @@ static inline bool xdr_item_is_present(const __be32 *p)
	return *p != xdr_zero;
}

/**
 * xdr_stream_decode_bool - Decode a boolean
 * @xdr: pointer to xdr_stream
 * @ptr: pointer to a u32 in which to store the result
 *
 * Return values:
 *   %0 on success
 *   %-EBADMSG on XDR buffer overflow
 */
static inline ssize_t
xdr_stream_decode_bool(struct xdr_stream *xdr, __u32 *ptr)
{
	const size_t count = sizeof(*ptr);
	__be32 *p = xdr_inline_decode(xdr, count);

	if (unlikely(!p))
		return -EBADMSG;
	*ptr = (*p != xdr_zero);
	return 0;
}

/**
 * xdr_stream_decode_u32 - Decode a 32-bit integer
 * @xdr: pointer to xdr_stream