Skip to content

Commit 6b8a943

Browse files
Trond Myklebustchucklever
authored andcommitted
nfsd: Fix a write performance regression
The call to filemap_flush() in nfsd_file_put() is there to ensure that we clear out any writes belonging to a NFSv3 client relatively quickly and avoid situations where the file can't be evicted by the garbage collector. It also ensures that we detect write errors quickly. The problem is this causes a regression in performance for some workloads. So try to improve matters by deferring writeback until we're ready to close the file, and need to detect errors so that we can force the client to resend. Tested-by: Jan Kara <jack@suse.cz> Fixes: b666930 ("nfsd: Reduce the number of calls to nfsd_file_gc()") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Link: https://lore.kernel.org/all/20220330103457.r4xrhy2d6nhtouzk@quack3.lan Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 5f7b839 commit 6b8a943

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

fs/nfsd/filecache.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,13 @@ nfsd_file_check_write_error(struct nfsd_file *nf)
235235
return filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err));
236236
}
237237

238+
static void
239+
nfsd_file_flush(struct nfsd_file *nf)
240+
{
241+
if (nf->nf_file && vfs_fsync(nf->nf_file, 1) != 0)
242+
nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id));
243+
}
244+
238245
static void
239246
nfsd_file_do_unhash(struct nfsd_file *nf)
240247
{
@@ -302,11 +309,14 @@ nfsd_file_put(struct nfsd_file *nf)
302309
return;
303310
}
304311

305-
filemap_flush(nf->nf_file->f_mapping);
306312
is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
307-
nfsd_file_put_noref(nf);
308-
if (is_hashed)
313+
if (!is_hashed) {
314+
nfsd_file_flush(nf);
315+
nfsd_file_put_noref(nf);
316+
} else {
317+
nfsd_file_put_noref(nf);
309318
nfsd_file_schedule_laundrette();
319+
}
310320
if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT)
311321
nfsd_file_gc();
312322
}
@@ -327,6 +337,7 @@ nfsd_file_dispose_list(struct list_head *dispose)
327337
while(!list_empty(dispose)) {
328338
nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
329339
list_del(&nf->nf_lru);
340+
nfsd_file_flush(nf);
330341
nfsd_file_put_noref(nf);
331342
}
332343
}
@@ -340,6 +351,7 @@ nfsd_file_dispose_list_sync(struct list_head *dispose)
340351
while(!list_empty(dispose)) {
341352
nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
342353
list_del(&nf->nf_lru);
354+
nfsd_file_flush(nf);
343355
if (!refcount_dec_and_test(&nf->nf_ref))
344356
continue;
345357
if (nfsd_file_free(nf))

0 commit comments

Comments
 (0)