]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/xfs/libxfs/xfs_bmap.c
Merge branch 'xfs-dax-updates' into for-next
[karo-tx-linux.git] / fs / xfs / libxfs / xfs_bmap.c
index ab92d10890ed743d3a3cffae2d361e9cf732d0ae..119c2422aac78bcbfb65b8af527efff0aa8e5951 100644 (file)
@@ -3802,8 +3802,13 @@ xfs_bmap_btalloc(
        args.wasdel = ap->wasdel;
        args.isfl = 0;
        args.userdata = ap->userdata;
-       if ((error = xfs_alloc_vextent(&args)))
+       if (ap->userdata & XFS_ALLOC_USERDATA_ZERO)
+               args.ip = ap->ip;
+
+       error = xfs_alloc_vextent(&args);
+       if (error)
                return error;
+
        if (tryagain && args.fsbno == NULLFSBLOCK) {
                /*
                 * Exact allocation failed. Now try with alignment
@@ -4302,11 +4307,14 @@ xfs_bmapi_allocate(
 
        /*
         * Indicate if this is the first user data in the file, or just any
-        * user data.
+        * user data. And if it is userdata, indicate whether it needs to
+        * be initialised to zero during allocation.
         */
        if (!(bma->flags & XFS_BMAPI_METADATA)) {
                bma->userdata = (bma->offset == 0) ?
                        XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
+               if (bma->flags & XFS_BMAPI_ZERO)
+                       bma->userdata |= XFS_ALLOC_USERDATA_ZERO;
        }
 
        bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
@@ -4421,6 +4429,17 @@ xfs_bmapi_convert_unwritten(
        mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
                                ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
 
+       /*
+        * Before insertion into the bmbt, zero the range being converted
+        * if required.
+        */
+       if (flags & XFS_BMAPI_ZERO) {
+               error = xfs_zero_extent(bma->ip, mval->br_startblock,
+                                       mval->br_blockcount);
+               if (error)
+                       return error;
+       }
+
        error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx,
                        &bma->cur, mval, bma->firstblock, bma->flist,
                        &tmp_logflags);
@@ -4514,6 +4533,18 @@ xfs_bmapi_write(
        ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
+       /* zeroing is for currently only for data extents, not metadata */
+       ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) !=
+                       (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO));
+       /*
+        * we can allocate unwritten extents or pre-zero allocated blocks,
+        * but it makes no sense to do both at once. This would result in
+        * zeroing the unwritten extent twice, but it still being an
+        * unwritten extent....
+        */
+       ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) !=
+                       (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO));
+
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
             XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),