[PATCH 8/9] xfs: defrag: copy data from old blocks to new blocks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



copy data from old blocks to new blocks synchronously

Signed-off-by: Wengang Wang <wen.gang.wang@xxxxxxxxxx>
---
 fs/xfs/xfs_defrag.c | 56 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/fs/xfs/xfs_defrag.c b/fs/xfs/xfs_defrag.c
index 3c86dd1f5cd4..0375b542024e 100644
--- a/fs/xfs/xfs_defrag.c
+++ b/fs/xfs/xfs_defrag.c
@@ -502,6 +502,57 @@ static int xfs_guarantee_cow_extent(struct xfs_defrag_info *di,
 	return error;
 }
 
+static int xfs_do_copy_extent_sync(struct xfs_mount *mp, xfs_fsblock_t src_blk,
+				   xfs_fsblock_t tgt_blk, xfs_filblks_t count)
+{
+	struct xfs_buf  *bp = NULL;
+	xfs_daddr_t	src_daddr, tgt_daddr;
+	size_t		nblocks;
+	int		error;
+
+	src_daddr = XFS_FSB_TO_DADDR(mp, src_blk);
+	tgt_daddr = XFS_FSB_TO_DADDR(mp, tgt_blk);
+	nblocks = XFS_FSB_TO_BB(mp, count);
+
+	error = xfs_buf_read_uncached(mp->m_ddev_targp, src_daddr, nblocks, 0, &bp, NULL);
+	if (error)
+		goto rel_bp;
+
+	/* write to new blocks */
+	bp->b_maps[0].bm_bn = tgt_daddr;
+	error = xfs_bwrite(bp);
+rel_bp:
+	if (bp)
+		xfs_buf_relse(bp);
+	return error;
+}
+
+/* Physically copy data from old extents to new extents synchronously
+ * Note: @new extent is expected either exact same as piece size or it's bigger
+ * than that.
+ */
+static int xfs_defrag_copy_piece_sync(struct xfs_defrag_info *di,
+				      struct xfs_bmbt_irec *new)
+{
+	struct xfs_defrag_piece	*dp = &di->di_dp;
+	xfs_fsblock_t		new_strt_blk;
+	int			error = 0;
+	int			i;
+
+	new_strt_blk = new->br_startblock + dp->dp_start_off - new->br_startoff;
+	for (i = 0; i < dp->dp_nr_ext; i++) {
+		struct xfs_bmbt_irec *irec = &dp->dp_extents[i];
+
+		error = xfs_do_copy_extent_sync(di->di_ip->i_mount,
+			irec->br_startblock, new_strt_blk,
+			irec->br_blockcount);
+		if (error)
+			break;
+		new_strt_blk += irec->br_blockcount;
+	}
+	return error;
+}
+
 /* defrag on the given piece
  * XFS_ILOCK_EXCL is held by caller
  */
@@ -523,6 +574,11 @@ static int xfs_defrag_file_piece(struct xfs_defrag_info *di)
 		goto out;
 
 	ASSERT(imap.br_blockcount >= di->di_dp.dp_len);
+
+	/* copy data to new blocks */
+	error = xfs_defrag_copy_piece_sync(di, &imap);
+	if (error)
+		goto out;
 out:
 	return error;
 }
-- 
2.39.3 (Apple Git-145)





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux