]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/nfs/file.c
Merge tag 'usb-5.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[linux.git] / fs / nfs / file.c
index 8eb731d9be3eae2d7b63308af27edd6dc397ea67..f96367a2463e37a355d777fdfe4314eeb561191e 100644 (file)
@@ -204,44 +204,39 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap);
 static int
 nfs_file_fsync_commit(struct file *file, int datasync)
 {
-       struct nfs_open_context *ctx = nfs_file_open_context(file);
        struct inode *inode = file_inode(file);
-       int do_resend, status;
-       int ret = 0;
+       int ret;
 
        dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync);
 
        nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
-       do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
-       status = nfs_commit_inode(inode, FLUSH_SYNC);
-       if (status == 0)
-               status = file_check_and_advance_wb_err(file);
-       if (status < 0) {
-               ret = status;
-               goto out;
-       }
-       do_resend |= test_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
-       if (do_resend)
-               ret = -EAGAIN;
-out:
-       return ret;
+       ret = nfs_commit_inode(inode, FLUSH_SYNC);
+       if (ret < 0)
+               return ret;
+       return file_check_and_advance_wb_err(file);
 }
 
 int
 nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
-       int ret;
+       struct nfs_open_context *ctx = nfs_file_open_context(file);
        struct inode *inode = file_inode(file);
+       int ret;
 
        trace_nfs_fsync_enter(inode);
 
-       do {
+       for (;;) {
                ret = file_write_and_wait_range(file, start, end);
                if (ret != 0)
                        break;
                ret = nfs_file_fsync_commit(file, datasync);
-               if (!ret)
-                       ret = pnfs_sync_inode(inode, !!datasync);
+               if (ret != 0)
+                       break;
+               ret = pnfs_sync_inode(inode, !!datasync);
+               if (ret != 0)
+                       break;
+               if (!test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags))
+                       break;
                /*
                 * If nfs_file_fsync_commit detected a server reboot, then
                 * resend all dirty pages that might have been covered by
@@ -249,7 +244,7 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                 */
                start = 0;
                end = LLONG_MAX;
-       } while (ret == -EAGAIN);
+       }
 
        trace_nfs_fsync_exit(inode, ret);
        return ret;
@@ -489,7 +484,19 @@ static int nfs_launder_page(struct page *page)
 static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
                                                sector_t *span)
 {
+       unsigned long blocks;
+       long long isize;
        struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host);
+       struct inode *inode = file->f_mapping->host;
+
+       spin_lock(&inode->i_lock);
+       blocks = inode->i_blocks;
+       isize = inode->i_size;
+       spin_unlock(&inode->i_lock);
+       if (blocks*512 < isize) {
+               pr_warn("swap activate: swapfile has holes\n");
+               return -EINVAL;
+       }
 
        *span = sis->pages;