|
@@ -4089,7 +4089,6 @@ xfs_bmap_read_extents(
|
|
|
xfs_extnum_t num_recs;
|
|
|
xfs_extnum_t start;
|
|
|
|
|
|
-
|
|
|
num_recs = xfs_btree_get_numrecs(block);
|
|
|
if (unlikely(i + num_recs > room)) {
|
|
|
ASSERT(i + num_recs <= room);
|
|
@@ -4746,6 +4745,69 @@ xfs_bmapi_allocate(
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+STATIC int
|
|
|
+xfs_bmapi_convert_unwritten(
|
|
|
+ struct xfs_bmalloca *bma,
|
|
|
+ struct xfs_bmbt_irec *mval,
|
|
|
+ xfs_filblks_t len,
|
|
|
+ xfs_extnum_t *lastx,
|
|
|
+ struct xfs_btree_cur **cur,
|
|
|
+ xfs_fsblock_t *firstblock,
|
|
|
+ struct xfs_bmap_free *flist,
|
|
|
+ int flags,
|
|
|
+ int *logflags)
|
|
|
+{
|
|
|
+ int whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
|
|
|
+ XFS_ATTR_FORK : XFS_DATA_FORK;
|
|
|
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
|
|
|
+ int error;
|
|
|
+
|
|
|
+ *logflags = 0;
|
|
|
+
|
|
|
+ /* check if we need to do unwritten->real conversion */
|
|
|
+ if (mval->br_state == XFS_EXT_UNWRITTEN &&
|
|
|
+ (flags & XFS_BMAPI_PREALLOC))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /* check if we need to do real->unwritten conversion */
|
|
|
+ if (mval->br_state == XFS_EXT_NORM &&
|
|
|
+ (flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) !=
|
|
|
+ (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Modify (by adding) the state flag, if writing.
|
|
|
+ */
|
|
|
+ ASSERT(mval->br_blockcount <= len);
|
|
|
+ if ((ifp->if_flags & XFS_IFBROOT) && !*cur) {
|
|
|
+ *cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp,
|
|
|
+ bma->ip, whichfork);
|
|
|
+ (*cur)->bc_private.b.firstblock = *firstblock;
|
|
|
+ (*cur)->bc_private.b.flist = flist;
|
|
|
+ }
|
|
|
+ mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
|
|
|
+ ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
|
|
|
+
|
|
|
+ error = xfs_bmap_add_extent(bma->tp, bma->ip, lastx, cur, mval,
|
|
|
+ firstblock, flist, logflags, whichfork);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Update our extent pointer, given that xfs_bmap_add_extent might
|
|
|
+ * have merged it into one of the neighbouring ones.
|
|
|
+ */
|
|
|
+ xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), bma->gotp);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We may have combined previously unwritten space with written space,
|
|
|
+ * so generate another request.
|
|
|
+ */
|
|
|
+ if (mval->br_blockcount < len)
|
|
|
+ return EAGAIN;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Map file blocks to filesystem blocks.
|
|
|
* File range is given by the bno/len pair.
|
|
@@ -4932,45 +4994,16 @@ xfs_bmapi(
|
|
|
/* Deal with the allocated space we found. */
|
|
|
xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
|
|
|
|
|
|
- /*
|
|
|
- * Check if writing previously allocated but
|
|
|
- * unwritten extents.
|
|
|
- */
|
|
|
- if (wr &&
|
|
|
- ((mval->br_state == XFS_EXT_UNWRITTEN &&
|
|
|
- ((flags & XFS_BMAPI_PREALLOC) == 0)) ||
|
|
|
- (mval->br_state == XFS_EXT_NORM &&
|
|
|
- ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) ==
|
|
|
- (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) {
|
|
|
- /*
|
|
|
- * Modify (by adding) the state flag, if writing.
|
|
|
- */
|
|
|
- ASSERT(mval->br_blockcount <= len);
|
|
|
- if ((ifp->if_flags & XFS_IFBROOT) && !cur) {
|
|
|
- cur = xfs_bmbt_init_cursor(mp,
|
|
|
- tp, ip, whichfork);
|
|
|
- cur->bc_private.b.firstblock =
|
|
|
- *firstblock;
|
|
|
- cur->bc_private.b.flist = flist;
|
|
|
- }
|
|
|
- mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
|
|
|
- ? XFS_EXT_NORM
|
|
|
- : XFS_EXT_UNWRITTEN;
|
|
|
- error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, mval,
|
|
|
- firstblock, flist, &tmp_logflags,
|
|
|
- whichfork);
|
|
|
+ /* Execute unwritten extent conversion if necessary */
|
|
|
+ if (wr) {
|
|
|
+ error = xfs_bmapi_convert_unwritten(&bma, mval, len,
|
|
|
+ &lastx, &cur, firstblock, flist, flags,
|
|
|
+ &tmp_logflags);
|
|
|
logflags |= tmp_logflags;
|
|
|
+ if (error == EAGAIN)
|
|
|
+ continue;
|
|
|
if (error)
|
|
|
goto error0;
|
|
|
- ep = xfs_iext_get_ext(ifp, lastx);
|
|
|
- xfs_bmbt_get_all(ep, &got);
|
|
|
- /*
|
|
|
- * We may have combined previously unwritten
|
|
|
- * space with written space, so generate
|
|
|
- * another request.
|
|
|
- */
|
|
|
- if (mval->br_blockcount < len)
|
|
|
- continue;
|
|
|
}
|
|
|
|
|
|
/* update the extent map to return */
|