]> Pileus Git - ~andy/linux/blobdiff - fs/xfs/xfs_iomap.c
Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[~andy/linux] / fs / xfs / xfs_iomap.c
index 7f537663365b08436f1ad29015b77df33f691109..add06b4e9a635511afc3e2716836e210ff794c46 100644 (file)
@@ -41,6 +41,7 @@
 #include "xfs_utils.h"
 #include "xfs_iomap.h"
 #include "xfs_trace.h"
+#include "xfs_icache.h"
 
 
 #define XFS_WRITEIO_ALIGN(mp,off)      (((off) >> mp->m_writeio_log) \
@@ -373,7 +374,7 @@ xfs_iomap_write_delay(
        xfs_extlen_t    extsz;
        int             nimaps;
        xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
-       int             prealloc, flushed = 0;
+       int             prealloc;
        int             error;
 
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
@@ -434,31 +435,29 @@ retry:
        }
 
        /*
-        * If bmapi returned us nothing, we got either ENOSPC or EDQUOT.  For
-        * ENOSPC, * flush all other inodes with delalloc blocks to free up
-        * some of the excess reserved metadata space. For both cases, retry
+        * If bmapi returned us nothing, we got either ENOSPC or EDQUOT. Retry
         * without EOF preallocation.
         */
        if (nimaps == 0) {
                trace_xfs_delalloc_enospc(ip, offset, count);
-               if (flushed)
-                       return XFS_ERROR(error ? error : ENOSPC);
-
-               if (error == ENOSPC) {
-                       xfs_iunlock(ip, XFS_ILOCK_EXCL);
-                       xfs_flush_inodes(ip);
-                       xfs_ilock(ip, XFS_ILOCK_EXCL);
+               if (prealloc) {
+                       prealloc = 0;
+                       error = 0;
+                       goto retry;
                }
-
-               flushed = 1;
-               error = 0;
-               prealloc = 0;
-               goto retry;
+               return XFS_ERROR(error ? error : ENOSPC);
        }
 
        if (!(imap[0].br_startblock || XFS_IS_REALTIME_INODE(ip)))
                return xfs_alert_fsblock_zero(ip, &imap[0]);
 
+       /*
+        * Tag the inode as speculatively preallocated so we can reclaim this
+        * space on demand, if necessary.
+        */
+       if (prealloc)
+               xfs_inode_set_eofblocks_tag(ip);
+
        *ret_imap = imap[0];
        return 0;
 }