fs/nfsd/blocklayoutxdr.c

Source file repositories/reference/linux-study-clean/fs/nfsd/blocklayoutxdr.c

File Facts

System
Linux kernel
Corpus path
fs/nfsd/blocklayoutxdr.c
Extension
.c
Size
7560 bytes
Lines
296
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (nfsd4_decode_deviceid4(xdr, &bex.vol_id)) {
			nfserr = nfserr_bad_xdr;
			goto fail;
		}

		if (xdr_stream_decode_u64(xdr, &bex.foff)) {
			nfserr = nfserr_bad_xdr;
			goto fail;
		}
		if (bex.foff & (block_size - 1)) {
			nfserr = nfserr_inval;
			goto fail;
		}

		if (xdr_stream_decode_u64(xdr, &bex.len)) {
			nfserr = nfserr_bad_xdr;
			goto fail;
		}
		if (bex.len & (block_size - 1)) {
			nfserr = nfserr_inval;
			goto fail;
		}

		if (xdr_stream_decode_u64(xdr, &bex.soff)) {
			nfserr = nfserr_bad_xdr;
			goto fail;
		}
		if (bex.soff & (block_size - 1)) {
			nfserr = nfserr_inval;
			goto fail;
		}

		if (xdr_stream_decode_u32(xdr, &bex.es)) {
			nfserr = nfserr_bad_xdr;
			goto fail;
		}
		if (bex.es != PNFS_BLOCK_READWRITE_DATA) {
			nfserr = nfserr_inval;
			goto fail;
		}

		iomaps[i].offset = bex.foff;
		iomaps[i].length = bex.len;
	}

	*iomapp = iomaps;
	*nr_iomapsp = nr_iomaps;
	return nfs_ok;
fail:
	kfree(iomaps);
	return nfserr;
}

/**
 * nfsd4_scsi_decode_layoutupdate - decode the scsi layout extent array
 * @xdr: subbuf set to the encoded array
 * @iomapp: pointer to store the decoded extent array
 * @nr_iomapsp: pointer to store the number of extents
 * @block_size: alignment of extent offset and length
 *
 * This function decodes the opaque field of the layoutupdate4 structure
 * in a layoutcommit request for the scsi layout driver. The field is
 * actually an array of extents sent by the client. It also checks that
 * the offset and length of each extent are aligned by @block_size.
 *
 * Return values:
 *   %nfs_ok: Successful decoding, @iomapp and @nr_iomapsp are valid
 *   %nfserr_bad_xdr: The encoded array in @xdr is invalid
 *   %nfserr_inval: An unaligned extent found
 *   %nfserr_delay: Failed to allocate memory for @iomapp
 */
__be32
nfsd4_scsi_decode_layoutupdate(struct xdr_stream *xdr, struct iomap **iomapp,
		int *nr_iomapsp, u32 block_size)
{
	struct iomap *iomaps;
	u32 nr_iomaps, expected, len, i;
	__be32 nfserr;

	if (xdr_stream_decode_u32(xdr, &nr_iomaps))
		return nfserr_bad_xdr;

	len = sizeof(__be32) + xdr_stream_remaining(xdr);
	expected = sizeof(__be32) + nr_iomaps * PNFS_SCSI_RANGE_SIZE;
	if (len != expected)
		return nfserr_bad_xdr;

	iomaps = kzalloc_objs(*iomaps, nr_iomaps);
	if (!iomaps)
		return nfserr_delay;

Annotation

Implementation Notes