NFS: Add support for eager writes
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Fri, 12 Feb 2021 21:49:48 +0000 (16:49 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Tue, 16 Feb 2021 21:11:14 +0000 (16:11 -0500)
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: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/file.c
fs/nfs/write.c
include/linux/nfs_fs_sb.h

index 03fd1dcc96bdf3946012565a193b2327b93ffc6e..16ad5050e0468124761768817df2436aa63970e3 100644 (file)
@@ -606,8 +606,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
-       unsigned long written = 0;
-       ssize_t result;
+       unsigned int mntflags = NFS_SERVER(inode)->flags;
+       ssize_t result, written;
        errseq_t since;
        int error;
 
@@ -648,6 +648,21 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
 
        written = result;
        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);
        if (result < 0)
                goto out;
index 6193350356a872d8b867c15ea5f7880b7382575b..82bdcb982186ff5f26317189f10d55036d6cdae0 100644 (file)
@@ -712,16 +712,23 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
 {
        struct inode *inode = mapping->host;
        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;
 
        nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
 
-       ioc = nfs_io_completion_alloc(GFP_KERNEL);
-       if (ioc)
-               nfs_io_completion_init(ioc, nfs_io_completion_commit, inode);
+       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);
+               if (ioc)
+                       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);
        pgio.pg_io_completion = ioc;
        err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
index 962e8313f007d8c1629a82d5112ddb08c0f90cc4..6f76b32a0238fd06cf2fbbe209a94e0c41bba092 100644 (file)
@@ -153,6 +153,8 @@ struct nfs_server {
 #define NFS_MOUNT_LOCAL_FCNTL          0x200000
 #define NFS_MOUNT_SOFTERR              0x400000
 #define NFS_MOUNT_SOFTREVAL            0x800000
+#define NFS_MOUNT_WRITE_EAGER          0x01000000
+#define NFS_MOUNT_WRITE_WAIT           0x02000000
 
        unsigned int            caps;           /* server capabilities */
        unsigned int            rsize;          /* read size */