Commit 902893e3 authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

NFS: Enable use of the RWF_DONTCACHE flag on the NFS client



The NFS client needs to defer dropbehind until after any writes to the
folio have been persisted on the server. Since this may be a 2 step
process, use folio_end_writeback_no_dropbehind() to allow release of the
writeback flag, and then call folio_end_dropbehind() once the COMMIT is
done.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <anna.schumaker@oracle.com>
parent 010054a5
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -363,6 +363,8 @@ static bool nfs_want_read_modify_write(struct file *file, struct folio *folio,

	if (pnfs_ld_read_whole_page(file_inode(file)))
		return true;
	if (folio_test_dropbehind(folio))
		return false;
	/* Open for reading too? */
	if (file->f_mode & FMODE_READ)
		return true;
@@ -382,7 +384,6 @@ static int nfs_write_begin(const struct kiocb *iocb,
			   loff_t pos, unsigned len, struct folio **foliop,
			   void **fsdata)
{
	fgf_t fgp = FGP_WRITEBEGIN;
	struct folio *folio;
	struct file *file = iocb->ki_filp;
	int once_thru = 0;
@@ -394,10 +395,8 @@ static int nfs_write_begin(const struct kiocb *iocb,
		file, mapping->host->i_ino, len, (long long) pos);
	nfs_truncate_last_folio(mapping, i_size_read(mapping->host), pos);

	fgp |= fgf_set_order(len);
start:
	folio = __filemap_get_folio(mapping, pos >> PAGE_SHIFT, fgp,
				    mapping_gfp_mask(mapping));
	folio = write_begin_get_folio(iocb, mapping, pos >> PAGE_SHIFT, len);
	if (IS_ERR(folio)) {
		ret = PTR_ERR(folio);
		goto out;
@@ -411,6 +410,7 @@ static int nfs_write_begin(const struct kiocb *iocb,
	} else if (!once_thru &&
		   nfs_want_read_modify_write(file, folio, pos, len)) {
		once_thru = 1;
		folio_clear_dropbehind(folio);
		ret = nfs_read_folio(file, folio);
		folio_put(folio);
		if (!ret)
@@ -963,5 +963,6 @@ const struct file_operations nfs_file_operations = {
	.splice_write	= iter_file_splice_write,
	.check_flags	= nfs_check_flags,
	.setlease	= simple_nosetlease,
	.fop_flags	= FOP_DONTCACHE,
};
EXPORT_SYMBOL_GPL(nfs_file_operations);
+1 −0
Original line number Diff line number Diff line
@@ -456,4 +456,5 @@ const struct file_operations nfs4_file_operations = {
#else
	.llseek		= nfs_file_llseek,
#endif
	.fop_flags	= FOP_DONTCACHE,
};
+3 −1
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ static void nfs_folio_end_writeback(struct folio *folio)
{
	struct nfs_server *nfss = NFS_SERVER(folio->mapping->host);

	folio_end_writeback(folio);
	folio_end_writeback_no_dropbehind(folio);
	if (atomic_long_dec_return(&nfss->writeback) <
	    NFS_CONGESTION_OFF_THRESH) {
		nfss->write_congested = 0;
@@ -748,6 +748,8 @@ static void nfs_inode_remove_request(struct nfs_page *req)
			clear_bit(PG_MAPPED, &req->wb_head->wb_flags);
		}
		spin_unlock(&mapping->i_private_lock);

		folio_end_dropbehind(folio);
	}
	nfs_page_group_unlock(req);