|
@@ -3800,8 +3800,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
|
|
@@ -4300,11 +4305,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;
|
|
@@ -4419,6 +4427,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);
|
|
@@ -4512,6 +4531,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),
|