Merge tag 'v4.4.18' into linux-linaro-lsk-v4.4
[firefly-linux-kernel-4.4.55.git] / fs / fuse / file.c
index c2e340d6ec6e8fc179721f2c61483f2aa1034b70..d58d4c0af0ce548bf7f24b6f71f32b6a2c2e96c0 100644 (file)
@@ -417,6 +417,15 @@ static int fuse_flush(struct file *file, fl_owner_t id)
        fuse_sync_writes(inode);
        mutex_unlock(&inode->i_mutex);
 
+       if (test_bit(AS_ENOSPC, &file->f_mapping->flags) &&
+           test_and_clear_bit(AS_ENOSPC, &file->f_mapping->flags))
+               err = -ENOSPC;
+       if (test_bit(AS_EIO, &file->f_mapping->flags) &&
+           test_and_clear_bit(AS_EIO, &file->f_mapping->flags))
+               err = -EIO;
+       if (err)
+               return err;
+
        req = fuse_get_req_nofail_nopages(fc, file);
        memset(&inarg, 0, sizeof(inarg));
        inarg.fh = ff->fh;
@@ -462,6 +471,21 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
                goto out;
 
        fuse_sync_writes(inode);
+
+       /*
+        * Due to implementation of fuse writeback
+        * filemap_write_and_wait_range() does not catch errors.
+        * We have to do this directly after fuse_sync_writes()
+        */
+       if (test_bit(AS_ENOSPC, &file->f_mapping->flags) &&
+           test_and_clear_bit(AS_ENOSPC, &file->f_mapping->flags))
+               err = -ENOSPC;
+       if (test_bit(AS_EIO, &file->f_mapping->flags) &&
+           test_and_clear_bit(AS_EIO, &file->f_mapping->flags))
+               err = -EIO;
+       if (err)
+               goto out;
+
        err = sync_inode_metadata(inode, 1);
        if (err)
                goto out;