[PATCH 1/2] NFSD: Fix duplicate fsnotify access events for iterator READs
Ameer Hamza <[email protected]>
| Newsgroups | org.kernel.vger.linux-nfs,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
A READ served without splice emits two fsnotify access events; a local read of the same file emits one. vfs_iocb_iter_read() emits an access event when the read succeeds, and nfsd_finish_read() emits a second one for the same READ. An inotify watch on an exported file sees each of these READs twice, so anything counting accesses counts double. READs take this path whenever nfsd does not use splice, for example with sec=krb5i or sec=krb5p, or when nfsd_disable_splice_read is set, as the NFSD_IO_DONTCACHE and NFSD_IO_DIRECT modes do. Spliced READs are not affected, since splice_direct_to_actor() emits no event and nfsd_finish_read() emits their only one. Move the fsnotify_access() call from nfsd_finish_read() into nfsd_splice_read(), the one path whose VFS helper does not emit it. Each READ now emits exactly one access event whichever path serves it. Measured with an inotify watch: the iterator path drops from two events per READ to one, and the splice path is unchanged at one. Suggested-by: Chuck Lever <[email protected]> Link: https://lore.kernel.org/linux-nfs/[email protected]/ Fixes: 507df40ebf316 ("NFSD: Hoist rq_vec preparation into nfsd_read()") Cc: [email protected] Assisted-by: Claude:claude-fable-5 Signed-off-by: Ameer Hamza <[email protected]> --- fs/nfsd/vfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index f9131827d391e..f45d4ad70b964 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1046,7 +1046,6 @@ static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp, nfsd_stats_io_read_add(nn, fhp->fh_export, host_err); *eof = nfsd_eof_on_read(file, offset, host_err, *count); *count = host_err; - fsnotify_access(file); trace_nfsd_read_io_done(rqstp, fhp, offset, *count); return 0; } else { @@ -1084,6 +1083,9 @@ __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, if (!host_err) host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor); + /* splice_direct_to_actor() does not emit an fsnotify event */ + if (host_err >= 0) + fsnotify_access(file); return nfsd_finish_read(rqstp, fhp, file, offset, count, eof, host_err); } base-commit: c5f58d03c50196301ac2ce7da81e8be33eba57c6 -- 2.53.0