diff options
-rw-r--r-- | fs/xfs/xfs_discard.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index 244e797dae32..8a24f0c6c860 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c | |||
@@ -38,7 +38,7 @@ xfs_trim_extents( | |||
38 | struct xfs_mount *mp, | 38 | struct xfs_mount *mp, |
39 | xfs_agnumber_t agno, | 39 | xfs_agnumber_t agno, |
40 | xfs_fsblock_t start, | 40 | xfs_fsblock_t start, |
41 | xfs_fsblock_t len, | 41 | xfs_fsblock_t end, |
42 | xfs_fsblock_t minlen, | 42 | xfs_fsblock_t minlen, |
43 | __uint64_t *blocks_trimmed) | 43 | __uint64_t *blocks_trimmed) |
44 | { | 44 | { |
@@ -100,7 +100,7 @@ xfs_trim_extents( | |||
100 | * down partially overlapping ranges for now. | 100 | * down partially overlapping ranges for now. |
101 | */ | 101 | */ |
102 | if (XFS_AGB_TO_FSB(mp, agno, fbno) + flen < start || | 102 | if (XFS_AGB_TO_FSB(mp, agno, fbno) + flen < start || |
103 | XFS_AGB_TO_FSB(mp, agno, fbno) >= start + len) { | 103 | XFS_AGB_TO_FSB(mp, agno, fbno) > end) { |
104 | trace_xfs_discard_exclude(mp, agno, fbno, flen); | 104 | trace_xfs_discard_exclude(mp, agno, fbno, flen); |
105 | goto next_extent; | 105 | goto next_extent; |
106 | } | 106 | } |
@@ -145,7 +145,7 @@ xfs_ioc_trim( | |||
145 | struct request_queue *q = mp->m_ddev_targp->bt_bdev->bd_disk->queue; | 145 | struct request_queue *q = mp->m_ddev_targp->bt_bdev->bd_disk->queue; |
146 | unsigned int granularity = q->limits.discard_granularity; | 146 | unsigned int granularity = q->limits.discard_granularity; |
147 | struct fstrim_range range; | 147 | struct fstrim_range range; |
148 | xfs_fsblock_t start, len, minlen; | 148 | xfs_fsblock_t start, end, minlen; |
149 | xfs_agnumber_t start_agno, end_agno, agno; | 149 | xfs_agnumber_t start_agno, end_agno, agno; |
150 | __uint64_t blocks_trimmed = 0; | 150 | __uint64_t blocks_trimmed = 0; |
151 | int error, last_error = 0; | 151 | int error, last_error = 0; |
@@ -165,19 +165,19 @@ xfs_ioc_trim( | |||
165 | * matter as trimming blocks is an advisory interface. | 165 | * matter as trimming blocks is an advisory interface. |
166 | */ | 166 | */ |
167 | start = XFS_B_TO_FSBT(mp, range.start); | 167 | start = XFS_B_TO_FSBT(mp, range.start); |
168 | len = XFS_B_TO_FSBT(mp, range.len); | 168 | end = start + XFS_B_TO_FSBT(mp, range.len) - 1; |
169 | minlen = XFS_B_TO_FSB(mp, max_t(u64, granularity, range.minlen)); | 169 | minlen = XFS_B_TO_FSB(mp, max_t(u64, granularity, range.minlen)); |
170 | 170 | ||
171 | start_agno = XFS_FSB_TO_AGNO(mp, start); | 171 | if (start >= mp->m_sb.sb_dblocks) |
172 | if (start_agno >= mp->m_sb.sb_agcount) | ||
173 | return -XFS_ERROR(EINVAL); | 172 | return -XFS_ERROR(EINVAL); |
173 | if (end > mp->m_sb.sb_dblocks - 1) | ||
174 | end = mp->m_sb.sb_dblocks - 1; | ||
174 | 175 | ||
175 | end_agno = XFS_FSB_TO_AGNO(mp, start + len); | 176 | start_agno = XFS_FSB_TO_AGNO(mp, start); |
176 | if (end_agno >= mp->m_sb.sb_agcount) | 177 | end_agno = XFS_FSB_TO_AGNO(mp, end); |
177 | end_agno = mp->m_sb.sb_agcount - 1; | ||
178 | 178 | ||
179 | for (agno = start_agno; agno <= end_agno; agno++) { | 179 | for (agno = start_agno; agno <= end_agno; agno++) { |
180 | error = -xfs_trim_extents(mp, agno, start, len, minlen, | 180 | error = -xfs_trim_extents(mp, agno, start, end, minlen, |
181 | &blocks_trimmed); | 181 | &blocks_trimmed); |
182 | if (error) | 182 | if (error) |
183 | last_error = error; | 183 | last_error = error; |