Skip to content

Commit

Permalink
nfsd: Fix a write performance regression
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Trond Myklebust authored and Chuck Lever committed Mar 31, 2022
1 parent 5f7b839 commit 6b8a943
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions fs/nfsd/filecache.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@ nfsd_file_check_write_error(struct nfsd_file *nf)
return filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err));
}

static void
nfsd_file_flush(struct nfsd_file *nf)
{
if (nf->nf_file && vfs_fsync(nf->nf_file, 1) != 0)
nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id));
}

static void
nfsd_file_do_unhash(struct nfsd_file *nf)
{
Expand Down Expand Up @@ -302,11 +309,14 @@ nfsd_file_put(struct nfsd_file *nf)
return;
}

filemap_flush(nf->nf_file->f_mapping);
is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
nfsd_file_put_noref(nf);
if (is_hashed)
if (!is_hashed) {
nfsd_file_flush(nf);
nfsd_file_put_noref(nf);
} else {
nfsd_file_put_noref(nf);
nfsd_file_schedule_laundrette();
}
if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT)
nfsd_file_gc();
}
Expand All @@ -327,6 +337,7 @@ nfsd_file_dispose_list(struct list_head *dispose)
while(!list_empty(dispose)) {
nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
list_del(&nf->nf_lru);
nfsd_file_flush(nf);
nfsd_file_put_noref(nf);
}
}
Expand All @@ -340,6 +351,7 @@ nfsd_file_dispose_list_sync(struct list_head *dispose)
while(!list_empty(dispose)) {
nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
list_del(&nf->nf_lru);
nfsd_file_flush(nf);
if (!refcount_dec_and_test(&nf->nf_ref))
continue;
if (nfsd_file_free(nf))
Expand Down

0 comments on commit 6b8a943

Please sign in to comment.