btrfs: fix RWF_NOWAIT write not failling when we need to cow
[platform/kernel/linux-rpi.git] / fs / btrfs / file.c
index 04faa04..6d5d905 100644 (file)
@@ -1904,18 +1904,29 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
        pos = iocb->ki_pos;
        count = iov_iter_count(from);
        if (iocb->ki_flags & IOCB_NOWAIT) {
+               size_t nocow_bytes = count;
+
                /*
                 * We will allocate space in case nodatacow is not set,
                 * so bail
                 */
                if (!(BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
                                              BTRFS_INODE_PREALLOC)) ||
-                   check_can_nocow(BTRFS_I(inode), pos, &count) <= 0) {
+                   check_can_nocow(BTRFS_I(inode), pos, &nocow_bytes) <= 0) {
                        inode_unlock(inode);
                        return -EAGAIN;
                }
                /* check_can_nocow() locks the snapshot lock on success */
                btrfs_drew_write_unlock(&root->snapshot_lock);
+               /*
+                * There are holes in the range or parts of the range that must
+                * be COWed (shared extents, RO block groups, etc), so just bail
+                * out.
+                */
+               if (nocow_bytes < count) {
+                       inode_unlock(inode);
+                       return -EAGAIN;
+               }
        }
 
        current->backing_dev_info = inode_to_bdi(inode);