aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-04-17 02:07:36 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2018-05-02 12:21:33 -0400
commit021ba8e98fe5c6691b3cc3669faafa02403aa211 (patch)
tree9b4b92b15794cb1e2c7a70f7dae329b3923679b2
parent7b38460dc8e4eafba06c78f8e37099d3b34d473c (diff)
xfs: cap the length of deduplication requests
Since deduplication potentially has to read in all the pages in both files in order to compare the contents, cap the deduplication request length at MAX_RW_COUNT/2 (roughly 1GB) so that we have /some/ upper bound on the request length and can't just lock up the kernel forever. Found by running generic/304 after commit 1ddae54555b62 ("common/rc: add missing 'local' keywords"). Reported-by: matorola@gmail.com Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
-rw-r--r--fs/xfs/xfs_file.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index eed073cc4778..e70fb8ccecea 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -880,8 +880,18 @@ xfs_file_dedupe_range(
880 struct file *dst_file, 880 struct file *dst_file,
881 u64 dst_loff) 881 u64 dst_loff)
882{ 882{
883 struct inode *srci = file_inode(src_file);
884 u64 max_dedupe;
883 int error; 885 int error;
884 886
887 /*
888 * Since we have to read all these pages in to compare them, cut
889 * it off at MAX_RW_COUNT/2 rounded down to the nearest block.
890 * That means we won't do more than MAX_RW_COUNT IO per request.
891 */
892 max_dedupe = (MAX_RW_COUNT >> 1) & ~(i_blocksize(srci) - 1);
893 if (len > max_dedupe)
894 len = max_dedupe;
885 error = xfs_reflink_remap_range(src_file, loff, dst_file, dst_loff, 895 error = xfs_reflink_remap_range(src_file, loff, dst_file, dst_loff,
886 len, true); 896 len, true);
887 if (error) 897 if (error)