@@ -85,6 +85,21 @@ struct xfs_ifork {
* Hence number of extents increases by 2.
*/
#define XFS_IEXT_REFLINK_END_COW_CNT 2
+/*
+ * Remapping an extent involves unmapping the existing extent and
+ * mapping in the new extent.
+ * When unmapping, an extent containing the entire unmap
+ * range can be split into two extents,
+ * i.e. | Old extent | hole | Old extent |
+ * Hence extent count increases by 1.
+ *
+ * Mapping in the new extent into the destination file can increase
+ * the extent count by 1.
+ */
+#define XFS_IEXT_REFLINK_REMAP_CNT(smap_real, dmap_written) \
+ (((smap_real) ? 1 : 0) + ((dmap_written) ? 1 : 0))
+
+
/*
* Fork handling.
*/
@@ -1100,6 +1100,11 @@ xfs_reflink_remap_extent(
goto out_cancel;
}
+ error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
+ XFS_IEXT_REFLINK_REMAP_CNT(smap_real, dmap_written));
+ if (error)
+ goto out_cancel;
+
if (smap_real) {
/*
* If the extent we're unmapping is backed by storage (written
Remapping an extent involves unmapping the existing extent and mapping in the new extent. When unmapping, an extent containing the entire unmap range can be split into two extents, i.e. | Old extent | hole | Old extent | Hence extent count increases by 1. Mapping in the new extent into the destination file can increase the extent count by 1. Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com> --- fs/xfs/libxfs/xfs_inode_fork.h | 15 +++++++++++++++ fs/xfs/xfs_reflink.c | 5 +++++ 2 files changed, 20 insertions(+)