xfs: Check for extent overflow when swapping extents
authorChandan Babu R <chandanrlinux@gmail.com>
Sat, 23 Jan 2021 00:48:15 +0000 (16:48 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Sat, 23 Jan 2021 00:54:48 +0000 (16:54 -0800)
Removing an initial range of source/donor file's extent and adding a new
extent (from donor/source file) in its place will cause extent count to
increase by 1.

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/libxfs/xfs_inode_fork.h
fs/xfs/xfs_bmap_util.c

index c8f279edc5c1ff307d982f8e60d881fdb08b41a5..9e2137cd73724b965c4dca278ec3114d8a13b632 100644 (file)
@@ -88,6 +88,13 @@ struct xfs_ifork {
  */
 #define XFS_IEXT_REFLINK_END_COW_CNT   (2)
 
+/*
+ * Removing an initial range of source/donor file's extent and adding a new
+ * extent (from donor/source file) in its place will cause extent count to
+ * increase by 1.
+ */
+#define XFS_IEXT_SWAP_RMAP_CNT         (1)
+
 /*
  * Fork handling.
  */
index 6ac7a6ac26581afdf3eef9c665aba245af4acd6d..f3f8c48ff5bf107514d2ddc0a8668808ed2d12ff 100644 (file)
@@ -1399,6 +1399,22 @@ xfs_swap_extent_rmap(
                                        irec.br_blockcount);
                        trace_xfs_swap_extent_rmap_remap_piece(tip, &uirec);
 
+                       if (xfs_bmap_is_real_extent(&uirec)) {
+                               error = xfs_iext_count_may_overflow(ip,
+                                               XFS_DATA_FORK,
+                                               XFS_IEXT_SWAP_RMAP_CNT);
+                               if (error)
+                                       goto out;
+                       }
+
+                       if (xfs_bmap_is_real_extent(&irec)) {
+                               error = xfs_iext_count_may_overflow(tip,
+                                               XFS_DATA_FORK,
+                                               XFS_IEXT_SWAP_RMAP_CNT);
+                               if (error)
+                                       goto out;
+                       }
+
                        /* Remove the mapping from the donor file. */
                        xfs_bmap_unmap_extent(tp, tip, &uirec);