Commit 12181490 authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: Add experimental setting to disable the use of splice read



NFSD currently has two separate code paths for handling read
requests. One uses page splicing; the other is a traditional read
based on an iov iterator.

Because most Linux file systems support splice read, the latter
does not get nearly the same test experience as splice reads.

To force the use of vectored reads for testing and benchmarking,
introduce the ability to disable splice reads for all NFS READ
operations.

Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 9fe5ea76
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -6,6 +6,32 @@

static struct dentry *nfsd_top_dir __read_mostly;

/*
 * /sys/kernel/debug/nfsd/disable-splice-read
 *
 * Contents:
 *   %0: NFS READ is allowed to use page splicing
 *   %1: NFS READ uses only iov iter read
 *
 * The default value of this setting is zero (page splicing is
 * allowed). This setting takes immediate effect for all NFS
 * versions, all exports, and in all NFSD net namespaces.
 */

static int nfsd_dsr_get(void *data, u64 *val)
{
	*val = nfsd_disable_splice_read ? 1 : 0;
	return 0;
}

static int nfsd_dsr_set(void *data, u64 val)
{
	nfsd_disable_splice_read = (val > 0) ? true : false;
	return 0;
}

DEFINE_DEBUGFS_ATTRIBUTE(nfsd_dsr_fops, nfsd_dsr_get, nfsd_dsr_set, "%llu\n");

void nfsd_debugfs_exit(void)
{
	debugfs_remove_recursive(nfsd_top_dir);
@@ -15,4 +41,7 @@ void nfsd_debugfs_exit(void)
void nfsd_debugfs_init(void)
{
	nfsd_top_dir = debugfs_create_dir("nfsd", NULL);

	debugfs_create_file("disable-splice-read", S_IWUSR | S_IRUGO,
			    nfsd_top_dir, NULL, &nfsd_dsr_fops);
}
+2 −0
Original line number Diff line number Diff line
@@ -164,6 +164,8 @@ static inline void nfsd_debugfs_init(void) {}
static inline void nfsd_debugfs_exit(void) {}
#endif

extern bool nfsd_disable_splice_read __read_mostly;

extern int nfsd_max_blksize;

static inline int nfsd_v4client(struct svc_rqst *rq)
+4 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@

#define NFSDDBG_FACILITY		NFSDDBG_FILEOP

bool nfsd_disable_splice_read __read_mostly;

/**
 * nfserrno - Map Linux errnos to NFS errnos
 * @errno: POSIX(-ish) error code to be mapped
@@ -1236,6 +1238,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
 */
bool nfsd_read_splice_ok(struct svc_rqst *rqstp)
{
	if (nfsd_disable_splice_read)
		return false;
	switch (svc_auth_flavor(rqstp)) {
	case RPC_AUTH_GSS_KRB5I:
	case RPC_AUTH_GSS_KRB5P: