From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 439CD26E71E for ; Thu, 7 Aug 2025 16:25:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754583953; cv=none; b=ZhHm6UF1rJkyz8C9/EMbDOZUV3LdWpVhBRSE5IvLKB7Liv9n1UeSxHz28akSAsdyCLYSGH6meq0SAfmpH/ssQR3JiY/90UxJIplmoIHHBhs9DL1+8FHlV6lp+8xlGytvN8CVrkaDYtbWPceuP6MWa1t602JIUEXEoHB08g87ERY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754583953; c=relaxed/simple; bh=bFstP4HCSgskatojgV3YVec11xapRB3V0dosTpXMEnA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Jw3toeyDazBt+StHKo3MqzwCNJXYSYYjXyqg2qaMF0OXKO8+vfx/VPnzadVTSrc6h6Vns3wZRNhkgwzS9Qa7nXrJX6v35DW8wCKvIHBLGQ48ZYPBGqRuQC4ir5xBxJKqT9hx7AjG572KFrfF2XKwVCM0+ab6fviscNQ50SpXjoQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RB1Jwywy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RB1Jwywy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9E4CCC4CEEB; Thu, 7 Aug 2025 16:25:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754583951; bh=bFstP4HCSgskatojgV3YVec11xapRB3V0dosTpXMEnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RB1JwywyOShNxDsXGM3/kGg8IKEfJuvz8Q/Wig+kC/bhDGgqLoGO4s8ZJHKC/qBxS aHv/dR3PT88gro7mcVZQGDhnhN633i7sj68TmsU+/DliLlNFEC95F8gTBQoFSPXRrO BrH6tngukPovuMdeFoVR66fDB4cVP5QjUQs9lQJZLChTynfo5eNKPgtDymv+N5UNrJ dOTlwurXzkPBSIhxaCHsCCp7HRk/xp8eugD8o4aZPZ0+di/4qja7/h4qYywXrHgSGd q75ecAJTi5Mutw3Aig/2ORYeAlzJeHEM/ziBjZvqLZlNtdSwDkXluvufwlA6egkEgd 9c0xb94ZFvqdg== From: Mike Snitzer To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Subject: [PATCH v5 4/7] NFSD: add io_cache_write controls to debugfs interface Date: Thu, 7 Aug 2025 12:25:41 -0400 Message-ID: <20250807162544.17191-5-snitzer@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20250807162544.17191-1-snitzer@kernel.org> References: <20250807162544.17191-1-snitzer@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add 'io_cache_write' to NFSD's debugfs interface so that: Any data written by NFSD will either be: - cached using page cache (NFSD_IO_BUFFERED=1) - cached but removed from the page cache upon completion (NFSD_IO_DONTCACHE=2). - not cached (NFSD_IO_DIRECT=3) io_cache_write may be set by writing to: /sys/kernel/debug/nfsd/io_cache_write If NFSD_IO_DONTCACHE is specified using 2, FOP_DONTCACHE must be advertised as supported by the underlying filesystem (e.g. XFS), otherwise all IO flagged with RWF_DONTCACHE will fail with -EOPNOTSUPP. If NFSD_IO_DIRECT is specified using 3, the IO must be aligned relative to the underlying block device's logical_block_size. Also the memory buffer used to store the WRITE payload must be aligned relative to the underlying block device's dma_alignment. Signed-off-by: Mike Snitzer --- fs/nfsd/debugfs.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/nfsd.h | 1 + fs/nfsd/vfs.c | 16 ++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/fs/nfsd/debugfs.c b/fs/nfsd/debugfs.c index c07f71d4e84f4..872de65f0e9ac 100644 --- a/fs/nfsd/debugfs.c +++ b/fs/nfsd/debugfs.c @@ -87,6 +87,47 @@ static int nfsd_io_cache_read_set(void *data, u64 val) DEFINE_DEBUGFS_ATTRIBUTE(nfsd_io_cache_read_fops, nfsd_io_cache_read_get, nfsd_io_cache_read_set, "%llu\n"); +/* + * /sys/kernel/debug/nfsd/io_cache_write + * + * Contents: + * %1: NFS WRITE will use buffered IO + * %2: NFS WRITE will use dontcache (buffered IO w/ dropbehind) + * %3: NFS WRITE will use direct IO + * + * The default value of this setting is zero (UNSPECIFIED). + * This setting takes immediate effect for all NFS versions, + * all exports, and in all NFSD net namespaces. + */ + +static int nfsd_io_cache_write_get(void *data, u64 *val) +{ + *val = nfsd_io_cache_write; + return 0; +} + +static int nfsd_io_cache_write_set(void *data, u64 val) +{ + int ret = 0; + + switch (val) { + case NFSD_IO_BUFFERED: + case NFSD_IO_DONTCACHE: + case NFSD_IO_DIRECT: + nfsd_io_cache_write = val; + break; + default: + nfsd_io_cache_write = NFSD_IO_UNSPECIFIED; + ret = -EINVAL; + break; + } + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(nfsd_io_cache_write_fops, nfsd_io_cache_write_get, + nfsd_io_cache_write_set, "%llu\n"); + void nfsd_debugfs_exit(void) { debugfs_remove_recursive(nfsd_top_dir); @@ -102,4 +143,7 @@ void nfsd_debugfs_init(void) debugfs_create_file("io_cache_read", S_IWUSR | S_IRUGO, nfsd_top_dir, NULL, &nfsd_io_cache_read_fops); + + debugfs_create_file("io_cache_write", S_IWUSR | S_IRUGO, + nfsd_top_dir, NULL, &nfsd_io_cache_write_fops); } diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 6ef799405145f..fe935b4cda538 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -161,6 +161,7 @@ enum { }; extern u64 nfsd_io_cache_read __read_mostly; +extern u64 nfsd_io_cache_write __read_mostly; extern int nfsd_max_blksize; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 26b6d96258711..5768244c7a3c3 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -50,6 +50,7 @@ bool nfsd_disable_splice_read __read_mostly; u64 nfsd_io_cache_read __read_mostly; +u64 nfsd_io_cache_write __read_mostly; /** * nfserrno - Map Linux errnos to NFS errnos @@ -1234,6 +1235,21 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, nvecs = xdr_buf_to_bvec(rqstp->rq_bvec, rqstp->rq_maxpages, payload); iov_iter_bvec(&iter, ITER_SOURCE, rqstp->rq_bvec, nvecs, *cnt); + + switch (nfsd_io_cache_write) { + case NFSD_IO_DIRECT: + /* direct I/O must be aligned to device logical sector size */ + if (nf->nf_dio_mem_align && nf->nf_dio_offset_align && + (((offset | *cnt) & (nf->nf_dio_offset_align-1)) == 0)) + kiocb.ki_flags |= IOCB_DIRECT; + break; + case NFSD_IO_DONTCACHE: + kiocb.ki_flags |= IOCB_DONTCACHE; + break; + case NFSD_IO_BUFFERED: + break; + } + since = READ_ONCE(file->f_wb_err); if (verf) nfsd_copy_write_verifier(verf, nn); -- 2.44.0