diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2018-04-17 08:07:36 +0200 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2018-05-02 18:21:33 +0200 |
commit | 021ba8e98fe5c6691b3cc3669faafa02403aa211 (patch) | |
tree | 9b4b92b15794cb1e2c7a70f7dae329b3923679b2 /fs | |
parent | xfs: don't fail when converting shortform attr to long form during ATTR_REPLACE (diff) | |
download | linux-021ba8e98fe5c6691b3cc3669faafa02403aa211.tar.xz linux-021ba8e98fe5c6691b3cc3669faafa02403aa211.zip |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_file.c | 10 |
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( struct file *dst_file, u64 dst_loff) { + struct inode *srci = file_inode(src_file); + u64 max_dedupe; int error; + /* + * Since we have to read all these pages in to compare them, cut + * it off at MAX_RW_COUNT/2 rounded down to the nearest block. + * That means we won't do more than MAX_RW_COUNT IO per request. + */ + max_dedupe = (MAX_RW_COUNT >> 1) & ~(i_blocksize(srci) - 1); + if (len > max_dedupe) + len = max_dedupe; error = xfs_reflink_remap_range(src_file, loff, dst_file, dst_loff, len, true); if (error) |