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

NFS: Add support for eager writes



Support eager writing to the server, meaning that we write the data to
cache on the server, and wait for that to complete. This ensures that we
see ENOSPC errors immediately.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 75cfb200
Loading
Loading
Loading
Loading
+17 −2
Original line number Original line Diff line number Diff line
@@ -606,8 +606,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
{
{
	struct file *file = iocb->ki_filp;
	struct file *file = iocb->ki_filp;
	struct inode *inode = file_inode(file);
	struct inode *inode = file_inode(file);
	unsigned long written = 0;
	unsigned int mntflags = NFS_SERVER(inode)->flags;
	ssize_t result;
	ssize_t result, written;
	errseq_t since;
	errseq_t since;
	int error;
	int error;


@@ -648,6 +648,21 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)


	written = result;
	written = result;
	iocb->ki_pos += written;
	iocb->ki_pos += written;

	if (mntflags & NFS_MOUNT_WRITE_EAGER) {
		result = filemap_fdatawrite_range(file->f_mapping,
						  iocb->ki_pos - written,
						  iocb->ki_pos - 1);
		if (result < 0)
			goto out;
	}
	if (mntflags & NFS_MOUNT_WRITE_WAIT) {
		result = filemap_fdatawait_range(file->f_mapping,
						 iocb->ki_pos - written,
						 iocb->ki_pos - 1);
		if (result < 0)
			goto out;
	}
	result = generic_write_sync(iocb, written);
	result = generic_write_sync(iocb, written);
	if (result < 0)
	if (result < 0)
		goto out;
		goto out;
+12 −5
Original line number Original line Diff line number Diff line
@@ -712,16 +712,23 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
{
{
	struct inode *inode = mapping->host;
	struct inode *inode = mapping->host;
	struct nfs_pageio_descriptor pgio;
	struct nfs_pageio_descriptor pgio;
	struct nfs_io_completion *ioc;
	struct nfs_io_completion *ioc = NULL;
	unsigned int mntflags = NFS_SERVER(inode)->flags;
	int priority = 0;
	int err;
	int err;


	nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
	nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);


	if (!(mntflags & NFS_MOUNT_WRITE_EAGER) || wbc->for_kupdate ||
	    wbc->for_background || wbc->for_sync || wbc->for_reclaim) {
		ioc = nfs_io_completion_alloc(GFP_KERNEL);
		ioc = nfs_io_completion_alloc(GFP_KERNEL);
		if (ioc)
		if (ioc)
		nfs_io_completion_init(ioc, nfs_io_completion_commit, inode);
			nfs_io_completion_init(ioc, nfs_io_completion_commit,
					       inode);
		priority = wb_priority(wbc);
	}


	nfs_pageio_init_write(&pgio, inode, wb_priority(wbc), false,
	nfs_pageio_init_write(&pgio, inode, priority, false,
				&nfs_async_write_completion_ops);
				&nfs_async_write_completion_ops);
	pgio.pg_io_completion = ioc;
	pgio.pg_io_completion = ioc;
	err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
	err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
+2 −0
Original line number Original line Diff line number Diff line
@@ -153,6 +153,8 @@ struct nfs_server {
#define NFS_MOUNT_LOCAL_FCNTL		0x200000
#define NFS_MOUNT_LOCAL_FCNTL		0x200000
#define NFS_MOUNT_SOFTERR		0x400000
#define NFS_MOUNT_SOFTERR		0x400000
#define NFS_MOUNT_SOFTREVAL		0x800000
#define NFS_MOUNT_SOFTREVAL		0x800000
#define NFS_MOUNT_WRITE_EAGER		0x01000000
#define NFS_MOUNT_WRITE_WAIT		0x02000000


	unsigned int		caps;		/* server capabilities */
	unsigned int		caps;		/* server capabilities */
	unsigned int		rsize;		/* read size */
	unsigned int		rsize;		/* read size */