Commit 5185980d authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: Replace READ* macros in nfsd4_decode_layoutcommit()

parent 04495971
Loading
Loading
Loading
Loading
+58 −62
Original line number Diff line number Diff line
@@ -274,20 +274,6 @@ nfsd4_decode_component4(struct nfsd4_compoundargs *argp, char **namp, u32 *lenp)
	return nfs_ok;
}

static __be32
nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
{
	DECODE_HEAD;

	READ_BUF(12);
	p = xdr_decode_hyper(p, &tv->tv_sec);
	tv->tv_nsec = be32_to_cpup(p++);
	if (tv->tv_nsec >= (u32)1000000000)
		return nfserr_inval;

	DECODE_TAIL;
}

static __be32
nfsd4_decode_nfstime4(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
{
@@ -651,6 +637,29 @@ nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
	memcpy(devid, p, sizeof(*devid));
	return nfs_ok;
}

static __be32
nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
			   struct nfsd4_layoutcommit *lcp)
{
	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_layout_type) < 0)
		return nfserr_bad_xdr;
	if (lcp->lc_layout_type < LAYOUT_NFSV4_1_FILES)
		return nfserr_bad_xdr;
	if (lcp->lc_layout_type >= LAYOUT_TYPE_MAX)
		return nfserr_bad_xdr;

	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_up_len) < 0)
		return nfserr_bad_xdr;
	if (lcp->lc_up_len > 0) {
		lcp->lc_up_layout = xdr_inline_decode(argp->xdr, lcp->lc_up_len);
		if (!lcp->lc_up_layout)
			return nfserr_bad_xdr;
	}

	return nfs_ok;
}

#endif /* CONFIG_NFSD_PNFS */

static __be32
@@ -1796,6 +1805,41 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
	return nfs_ok;
}

static __be32
nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
			  struct nfsd4_layoutcommit *lcp)
{
	__be32 *p, status;

	if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.offset) < 0)
		return nfserr_bad_xdr;
	if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.length) < 0)
		return nfserr_bad_xdr;
	if (xdr_stream_decode_bool(argp->xdr, &lcp->lc_reclaim) < 0)
		return nfserr_bad_xdr;
	status = nfsd4_decode_stateid4(argp, &lcp->lc_sid);
	if (status)
		return status;
	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_newoffset) < 0)
		return nfserr_bad_xdr;
	if (lcp->lc_newoffset) {
		if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_last_wr) < 0)
			return nfserr_bad_xdr;
	} else
		lcp->lc_last_wr = 0;
	p = xdr_inline_decode(argp->xdr, XDR_UNIT);
	if (!p)
		return nfserr_bad_xdr;
	if (xdr_item_is_present(p)) {
		status = nfsd4_decode_nfstime4(argp, &lcp->lc_mtime);
		if (status)
			return status;
	} else {
		lcp->lc_mtime.tv_nsec = UTIME_NOW;
	}
	return nfsd4_decode_layoutupdate4(argp, lcp);
}

static __be32
nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
		struct nfsd4_layoutget *lgp)
@@ -1820,54 +1864,6 @@ nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
	DECODE_TAIL;
}

static __be32
nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
		struct nfsd4_layoutcommit *lcp)
{
	DECODE_HEAD;
	u32 timechange;

	READ_BUF(20);
	p = xdr_decode_hyper(p, &lcp->lc_seg.offset);
	p = xdr_decode_hyper(p, &lcp->lc_seg.length);
	lcp->lc_reclaim = be32_to_cpup(p++);

	status = nfsd4_decode_stateid(argp, &lcp->lc_sid);
	if (status)
		return status;

	READ_BUF(4);
	lcp->lc_newoffset = be32_to_cpup(p++);
	if (lcp->lc_newoffset) {
		READ_BUF(8);
		p = xdr_decode_hyper(p, &lcp->lc_last_wr);
	} else
		lcp->lc_last_wr = 0;
	READ_BUF(4);
	timechange = be32_to_cpup(p++);
	if (timechange) {
		status = nfsd4_decode_time(argp, &lcp->lc_mtime);
		if (status)
			return status;
	} else {
		lcp->lc_mtime.tv_nsec = UTIME_NOW;
	}
	READ_BUF(8);
	lcp->lc_layout_type = be32_to_cpup(p++);

	/*
	 * Save the layout update in XDR format and let the layout driver deal
	 * with it later.
	 */
	lcp->lc_up_len = be32_to_cpup(p++);
	if (lcp->lc_up_len > 0) {
		READ_BUF(lcp->lc_up_len);
		READMEM(lcp->lc_up_layout, lcp->lc_up_len);
	}

	DECODE_TAIL;
}

static __be32
nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
		struct nfsd4_layoutreturn *lrp)