#include "xfs_ag_resv.h"
 #include "xfs_refcount.h"
 #include "xfs_rmap_btree.h"
+#include "xfs_icache.h"
 
 
 kmem_zone_t            *xfs_bmap_free_item_zone;
 xfs_bmapi_reserve_delalloc(
        struct xfs_inode        *ip,
        int                     whichfork,
-       xfs_fileoff_t           aoff,
+       xfs_fileoff_t           off,
        xfs_filblks_t           len,
+       xfs_filblks_t           prealloc,
        struct xfs_bmbt_irec    *got,
        xfs_extnum_t            *lastx,
        int                     eof)
        char                    rt = XFS_IS_REALTIME_INODE(ip);
        xfs_extlen_t            extsz;
        int                     error;
+       xfs_fileoff_t           aoff = off;
 
-       alen = XFS_FILBLKS_MIN(len, MAXEXTLEN);
+       /*
+        * Cap the alloc length. Keep track of prealloc so we know whether to
+        * tag the inode before we return.
+        */
+       alen = XFS_FILBLKS_MIN(len + prealloc, MAXEXTLEN);
        if (!eof)
                alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
+       if (prealloc && alen >= len)
+               prealloc = alen - len;
 
        /* Figure out the extent size, adjust alen */
        if (whichfork == XFS_COW_FORK)
         */
        xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got);
 
+       /*
+        * Tag the inode if blocks were preallocated. Note that COW fork
+        * preallocation can occur at the start or end of the extent, even when
+        * prealloc == 0, so we must also check the aligned offset and length.
+        */
+       if (whichfork == XFS_DATA_FORK && prealloc)
+               xfs_inode_set_eofblocks_tag(ip);
+       if (whichfork == XFS_COW_FORK && (prealloc || aoff < off || alen > len))
+               xfs_inode_set_cowblocks_tag(ip);
+
        ASSERT(got->br_startoff <= aoff);
        ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen);
        ASSERT(isnullstartblock(got->br_startblock));
 
                int num_exts);
 int    xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset);
 int    xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork,
-               xfs_fileoff_t aoff, xfs_filblks_t len,
+               xfs_fileoff_t off, xfs_filblks_t len, xfs_filblks_t prealloc,
                struct xfs_bmbt_irec *got, xfs_extnum_t *lastx, int eof);
 
 enum xfs_bmap_intent_type {
 
 
 retry:
        error = xfs_bmapi_reserve_delalloc(ip, XFS_DATA_FORK, offset_fsb,
-                       end_fsb - offset_fsb, &got, &idx, eof);
+                       end_fsb - offset_fsb, 0, &got, &idx, eof);
        switch (error) {
        case 0:
                break;
 
 
 retry:
        error = xfs_bmapi_reserve_delalloc(ip, XFS_COW_FORK, imap->br_startoff,
-                       end_fsb - imap->br_startoff, &got, &idx, eof);
+                       end_fsb - imap->br_startoff, 0, &got, &idx, eof);
        switch (error) {
        case 0:
                break;