Lines Matching +full:- +full:- +full:trim +full:- +full:-
1 // SPDX-License-Identifier: GPL-2.0
33 * gathering extents to trim, we must hold the AGF lock to lock out other
51 * We can't do this exactly with free space - once we drop the AGF lock, the
57 * This is exactly how online discard works - free extents are marked busy when
87 xfs_extent_busy_clear(&extents->extent_list, false); in xfs_discard_endio_work()
88 kfree(extents->owner); in xfs_discard_endio_work()
92 * Queue up the actual completion to a thread to avoid IRQ-safe locking for
99 struct xfs_busy_extents *extents = bio->bi_private; in xfs_discard_endio()
101 INIT_WORK(&extents->endio_work, xfs_discard_endio_work); in xfs_discard_endio()
102 queue_work(xfs_discard_wq, &extents->endio_work); in xfs_discard_endio()
110 struct xfs_mount *mp = xg->xg_mount; in xfs_group_bdev()
112 switch (xg->xg_type) { in xfs_group_bdev()
114 return mp->m_ddev_targp->bt_bdev; in xfs_group_bdev()
116 return mp->m_rtdev_targp->bt_bdev; in xfs_group_bdev()
140 list_for_each_entry(busyp, &extents->extent_list, list) { in xfs_discard_extents()
141 trace_xfs_discard_extent(busyp->group, busyp->bno, in xfs_discard_extents()
142 busyp->length); in xfs_discard_extents()
144 error = __blkdev_issue_discard(xfs_group_bdev(busyp->group), in xfs_discard_extents()
145 xfs_gbno_to_daddr(busyp->group, busyp->bno), in xfs_discard_extents()
146 XFS_FSB_TO_BB(mp, busyp->length), in xfs_discard_extents()
148 if (error && error != -EOPNOTSUPP) { in xfs_discard_extents()
151 (unsigned long long)busyp->bno, in xfs_discard_extents()
152 busyp->length, in xfs_discard_extents()
159 bio->bi_private = extents; in xfs_discard_extents()
160 bio->bi_end_io = xfs_discard_endio; in xfs_discard_extents()
163 xfs_discard_endio_work(&extents->endio_work); in xfs_discard_extents()
207 if (tcur->by_bno) { in xfs_trim_gather_extents()
208 /* sub-AG discard request always starts at tcur->start */ in xfs_trim_gather_extents()
210 error = xfs_alloc_lookup_le(cur, tcur->start, 0, &i); in xfs_trim_gather_extents()
212 error = xfs_alloc_lookup_ge(cur, tcur->start, 0, &i); in xfs_trim_gather_extents()
213 } else if (tcur->start == 0) { in xfs_trim_gather_extents()
214 /* first time through a by-len starts with max length */ in xfs_trim_gather_extents()
216 error = xfs_alloc_lookup_ge(cur, 0, tcur->count, &i); in xfs_trim_gather_extents()
218 /* nth time through a by-len starts where we left off */ in xfs_trim_gather_extents()
220 error = xfs_alloc_lookup_le(cur, tcur->start, tcur->count, &i); in xfs_trim_gather_extents()
226 tcur->count = 0; in xfs_trim_gather_extents()
243 error = -EFSCORRUPTED; in xfs_trim_gather_extents()
247 if (--batch <= 0) { in xfs_trim_gather_extents()
252 tcur->start = fbno; in xfs_trim_gather_extents()
253 tcur->count = flen; in xfs_trim_gather_extents()
259 * supposed to skip it. Do not bother to trim down partially in xfs_trim_gather_extents()
262 if (fbno + flen < tcur->start) { in xfs_trim_gather_extents()
266 if (fbno > tcur->end) { in xfs_trim_gather_extents()
268 if (tcur->by_bno) { in xfs_trim_gather_extents()
269 tcur->count = 0; in xfs_trim_gather_extents()
275 /* Trim the extent returned to the range we want. */ in xfs_trim_gather_extents()
276 if (fbno < tcur->start) { in xfs_trim_gather_extents()
277 flen -= tcur->start - fbno; in xfs_trim_gather_extents()
278 fbno = tcur->start; in xfs_trim_gather_extents()
280 if (fbno + flen > tcur->end + 1) in xfs_trim_gather_extents()
281 flen = tcur->end - fbno + 1; in xfs_trim_gather_extents()
284 if (flen < tcur->minlen) { in xfs_trim_gather_extents()
286 if (tcur->by_bno) in xfs_trim_gather_extents()
288 tcur->count = 0; in xfs_trim_gather_extents()
302 &extents->extent_list); in xfs_trim_gather_extents()
304 if (tcur->by_bno) in xfs_trim_gather_extents()
317 tcur->count = 0; in xfs_trim_gather_extents()
325 xfs_extent_busy_clear(&extents->extent_list, false); in xfs_trim_gather_extents()
353 .count = pag->pagf_longest, in xfs_trim_perag_extents()
359 if (start != 0 || end != pag_group(pag)->xg_block_count) in xfs_trim_perag_extents()
367 error = -ENOMEM; in xfs_trim_perag_extents()
371 extents->owner = extents; in xfs_trim_perag_extents()
372 INIT_LIST_HEAD(&extents->extent_list); in xfs_trim_perag_extents()
417 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1); in xfs_trim_datadev_extents()
425 xfs_agblock_t agend = pag_group(pag)->xg_block_count; in xfs_trim_datadev_extents()
448 /* minimum length that caller allows us to trim */
470 list_for_each_entry_safe(busyp, n, &tr->extent_list, list) { in xfs_discard_free_rtdev_extents()
471 list_del_init(&busyp->list); in xfs_discard_free_rtdev_extents()
486 struct block_device *bdev = mp->m_rtdev_targp->bt_bdev; in xfs_discard_rtdev_extents()
494 list_for_each_entry(busyp, &tr->extent_list, list) { in xfs_discard_rtdev_extents()
496 start = busyp->bno; in xfs_discard_rtdev_extents()
497 length += busyp->length; in xfs_discard_rtdev_extents()
499 trace_xfs_discard_rtextent(mp, busyp->bno, busyp->length); in xfs_discard_rtdev_extents()
502 xfs_rtb_to_daddr(mp, busyp->bno), in xfs_discard_rtdev_extents()
503 XFS_FSB_TO_BB(mp, busyp->length), in xfs_discard_rtdev_extents()
512 if (error == -EOPNOTSUPP) in xfs_discard_rtdev_extents()
538 if (rec->ar_startext > tr->stop_rtx) { in xfs_trim_gather_rtextent()
544 tr->restart_rtx = rec->ar_startext; in xfs_trim_gather_rtextent()
545 return -ECANCELED; in xfs_trim_gather_rtextent()
548 rbno = xfs_rtx_to_rtb(rtg, rec->ar_startext); in xfs_trim_gather_rtextent()
549 rlen = xfs_rtbxlen_to_blen(rtg_mount(rtg), rec->ar_extcount); in xfs_trim_gather_rtextent()
552 if (rlen < tr->minlen_fsb) { in xfs_trim_gather_rtextent()
559 return -ENOMEM; in xfs_trim_gather_rtextent()
561 busyp->bno = rbno; in xfs_trim_gather_rtextent()
562 busyp->length = rlen; in xfs_trim_gather_rtextent()
563 INIT_LIST_HEAD(&busyp->list); in xfs_trim_gather_rtextent()
564 list_add_tail(&busyp->list, &tr->extent_list); in xfs_trim_gather_rtextent()
566 tr->restart_rtx = rec->ar_startext + rec->ar_extcount; in xfs_trim_gather_rtextent()
570 /* Trim extents on an !rtgroups realtime device */
600 if (error == -ECANCELED) in xfs_trim_rtextents()
629 /* minimum length that caller allows us to trim */
653 if (--tr->batch <= 0) { in xfs_trim_gather_rtgroup_extent()
659 tr->restart_rtx = rec->ar_startext; in xfs_trim_gather_rtgroup_extent()
660 return -ECANCELED; in xfs_trim_gather_rtgroup_extent()
663 rgbno = xfs_rtx_to_rgbno(rtg, rec->ar_startext); in xfs_trim_gather_rtgroup_extent()
664 len = xfs_rtxlen_to_extlen(rtg_mount(rtg), rec->ar_extcount); in xfs_trim_gather_rtgroup_extent()
667 if (len < tr->minlen_fsb) { in xfs_trim_gather_rtgroup_extent()
682 &tr->extents->extent_list); in xfs_trim_gather_rtgroup_extent()
684 tr->queued++; in xfs_trim_gather_rtgroup_extent()
685 tr->restart_rtx = rec->ar_startext + rec->ar_extcount; in xfs_trim_gather_rtgroup_extent()
689 /* Trim extents in this rtgroup using the busy extent machinery. */
715 error = -ENOMEM; in xfs_trim_rtgroup_extents()
721 tr.extents->owner = tr.extents; in xfs_trim_rtgroup_extents()
722 INIT_LIST_HEAD(&tr.extents->extent_list); in xfs_trim_rtgroup_extents()
728 if (error == -ECANCELED) in xfs_trim_rtgroup_extents()
774 daddr_offset = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); in xfs_trim_rtdev_extents()
776 start -= daddr_offset; in xfs_trim_rtdev_extents()
786 end -= daddr_offset; in xfs_trim_rtdev_extents()
788 end_rtx = xfs_rtb_to_rtx(mp, end_rtbno + mp->m_sb.sb_rextsize - 1); in xfs_trim_rtdev_extents()
792 xfs_rtxnum_t rtg_end = rtg->rtg_extents; in xfs_trim_rtdev_extents()
816 # define xfs_trim_rtdev_extents(...) (-EOPNOTSUPP)
820 * trim a range of the filesystem.
826 * comparisons for determining the correct offset and regions to trim.
837 bdev_discard_granularity(mp->m_ddev_targp->bt_bdev); in xfs_ioc_trim()
846 return -EPERM; in xfs_ioc_trim()
848 if (mp->m_rtdev_targp && !xfs_has_zoned(mp) && in xfs_ioc_trim()
849 bdev_max_discard_sectors(mp->m_rtdev_targp->bt_bdev)) in xfs_ioc_trim()
850 rt_bdev = mp->m_rtdev_targp->bt_bdev; in xfs_ioc_trim()
851 if (!bdev_max_discard_sectors(mp->m_ddev_targp->bt_bdev) && !rt_bdev) in xfs_ioc_trim()
852 return -EOPNOTSUPP; in xfs_ioc_trim()
859 * We haven't recovered the log, so we cannot use our bnobt-guided in xfs_ioc_trim()
863 return -EROFS; in xfs_ioc_trim()
866 return -EFAULT; in xfs_ioc_trim()
878 max_blocks = mp->m_sb.sb_dblocks + mp->m_sb.sb_rblocks; in xfs_ioc_trim()
880 range.minlen > XFS_FSB_TO_B(mp, mp->m_ag_max_usable) || in xfs_ioc_trim()
881 range.len < mp->m_sb.sb_blocksize) in xfs_ioc_trim()
882 return -EINVAL; in xfs_ioc_trim()
885 end = start + BTOBBT(range.len) - 1; in xfs_ioc_trim()
887 if (bdev_max_discard_sectors(mp->m_ddev_targp->bt_bdev)) { in xfs_ioc_trim()
903 XFS_FSB_TO_B(mp, max_blocks) - range.start); in xfs_ioc_trim()
905 return -EFAULT; in xfs_ioc_trim()