Merge tag 'xfs-4.13-merge-5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[sfrench/cifs-2.6.git] / fs / xfs / xfs_iomap.c
index 86f1a9fa46d25969c3f4e66edeba89213b1b49f6..813394c62849727ddd4a5f97c5aa9041b6bc6987 100644 (file)
@@ -995,6 +995,11 @@ xfs_file_iomap_begin(
                lockmode = xfs_ilock_data_map_shared(ip);
        }
 
+       if ((flags & IOMAP_NOWAIT) && !(ip->i_df.if_flags & XFS_IFEXTENTS)) {
+               error = -EAGAIN;
+               goto out_unlock;
+       }
+
        ASSERT(offset <= mp->m_super->s_maxbytes);
        if ((xfs_fsize_t)offset + length > mp->m_super->s_maxbytes)
                length = mp->m_super->s_maxbytes - offset;
@@ -1016,6 +1021,15 @@ xfs_file_iomap_begin(
 
        if ((flags & (IOMAP_WRITE | IOMAP_ZERO)) && xfs_is_reflink_inode(ip)) {
                if (flags & IOMAP_DIRECT) {
+                       /*
+                        * A reflinked inode will result in CoW alloc.
+                        * FIXME: It could still overwrite on unshared extents
+                        * and not need allocation.
+                        */
+                       if (flags & IOMAP_NOWAIT) {
+                               error = -EAGAIN;
+                               goto out_unlock;
+                       }
                        /* may drop and re-acquire the ilock */
                        error = xfs_reflink_allocate_cow(ip, &imap, &shared,
                                        &lockmode);
@@ -1032,6 +1046,14 @@ xfs_file_iomap_begin(
        }
 
        if ((flags & IOMAP_WRITE) && imap_needs_alloc(inode, &imap, nimaps)) {
+               /*
+                * If nowait is set bail since we are going to make
+                * allocations.
+                */
+               if (flags & IOMAP_NOWAIT) {
+                       error = -EAGAIN;
+                       goto out_unlock;
+               }
                /*
                 * We cap the maximum length we map here to MAX_WRITEBACK_PAGES
                 * pages to keep the chunks of work done where somewhat symmetric