]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: return work remaining at the end of a bunmapi operation
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 25 Oct 2016 01:37:28 +0000 (12:37 +1100)
committerDave Chinner <david@fromorbit.com>
Tue, 25 Oct 2016 01:37:28 +0000 (12:37 +1100)
Source kernel commit: 4453593be6c54e7581467e80f4a2757be098a3a2

Return the range of file blocks that bunmapi didn't free.  This hint
is used by CoW and reflink to figure out what part of an extent
actually got freed so that it can set up the appropriate atomic
remapping of just the freed range.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/xfs_bmap.c
libxfs/xfs_bmap.h

index 4c3b4a33ab36c9f20c886d0e453c963e1fade5b2..ab455db398e0f17920a58dc85fd2111d34afa1a4 100644 (file)
@@ -5090,17 +5090,16 @@ done:
  * *done is set.
  */
 int                                            /* error */
-xfs_bunmapi(
+__xfs_bunmapi(
        xfs_trans_t             *tp,            /* transaction pointer */
        struct xfs_inode        *ip,            /* incore inode */
        xfs_fileoff_t           bno,            /* starting offset to unmap */
-       xfs_filblks_t           len,            /* length to unmap in file */
+       xfs_filblks_t           *rlen,          /* i/o: amount remaining */
        int                     flags,          /* misc flags */
        xfs_extnum_t            nexts,          /* number of extents max */
        xfs_fsblock_t           *firstblock,    /* first allocated block
                                                   controls a.g. for allocs */
-       struct xfs_defer_ops    *dfops,         /* i/o: list extents to free */
-       int                     *done)          /* set if not done yet */
+       struct xfs_defer_ops    *dfops)         /* i/o: deferred updates */
 {
        xfs_btree_cur_t         *cur;           /* bmap btree cursor */
        xfs_bmbt_irec_t         del;            /* extent being deleted */
@@ -5122,6 +5121,7 @@ xfs_bunmapi(
        int                     wasdel;         /* was a delayed alloc extent */
        int                     whichfork;      /* data or attribute fork */
        xfs_fsblock_t           sum;
+       xfs_filblks_t           len = *rlen;    /* length to unmap in file */
 
        trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_);
 
@@ -5148,7 +5148,7 @@ xfs_bunmapi(
                return error;
        nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
        if (nextents == 0) {
-               *done = 1;
+               *rlen = 0;
                return 0;
        }
        XFS_STATS_INC(mp, xs_blk_unmap);
@@ -5419,7 +5419,10 @@ nodelete:
                        extno++;
                }
        }
-       *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0;
+       if (bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0)
+               *rlen = 0;
+       else
+               *rlen = bno - start + 1;
 
        /*
         * Convert to a btree if necessary.
@@ -5475,6 +5478,27 @@ error0:
        return error;
 }
 
+/* Unmap a range of a file. */
+int
+xfs_bunmapi(
+       xfs_trans_t             *tp,
+       struct xfs_inode        *ip,
+       xfs_fileoff_t           bno,
+       xfs_filblks_t           len,
+       int                     flags,
+       xfs_extnum_t            nexts,
+       xfs_fsblock_t           *firstblock,
+       struct xfs_defer_ops    *dfops,
+       int                     *done)
+{
+       int                     error;
+
+       error = __xfs_bunmapi(tp, ip, bno, &len, flags, nexts, firstblock,
+                       dfops);
+       *done = (len == 0);
+       return error;
+}
+
 /*
  * Determine whether an extent shift can be accomplished by a merge with the
  * extent that precedes the target hole of the shift.
index 2c2f8833d85a4c1cd501b78c8a301fc027675bf7..abee9a473653f0b08d65dae249336a5405e07793 100644 (file)
@@ -197,6 +197,10 @@ int        xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip,
                xfs_fsblock_t *firstblock, xfs_extlen_t total,
                struct xfs_bmbt_irec *mval, int *nmap,
                struct xfs_defer_ops *dfops);
+int    __xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip,
+               xfs_fileoff_t bno, xfs_filblks_t *rlen, int flags,
+               xfs_extnum_t nexts, xfs_fsblock_t *firstblock,
+               struct xfs_defer_ops *dfops);
 int    xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip,
                xfs_fileoff_t bno, xfs_filblks_t len, int flags,
                xfs_extnum_t nexts, xfs_fsblock_t *firstblock,