Lines Matching +full:default +full:- +full:trim

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()
122 list_for_each_entry(busyp, &extents->extent_list, list) { in xfs_discard_extents()
123 struct xfs_group *xg = busyp->group; in xfs_discard_extents()
125 xfs_group_type_buftarg(xg->xg_mount, xg->xg_type); in xfs_discard_extents()
127 trace_xfs_discard_extent(xg, busyp->bno, busyp->length); in xfs_discard_extents()
129 error = __blkdev_issue_discard(btp->bt_bdev, in xfs_discard_extents()
130 xfs_gbno_to_daddr(xg, busyp->bno), in xfs_discard_extents()
131 XFS_FSB_TO_BB(mp, busyp->length), in xfs_discard_extents()
133 if (error && error != -EOPNOTSUPP) { in xfs_discard_extents()
136 (unsigned long long)busyp->bno, in xfs_discard_extents()
137 busyp->length, in xfs_discard_extents()
144 bio->bi_private = extents; in xfs_discard_extents()
145 bio->bi_end_io = xfs_discard_endio; in xfs_discard_extents()
148 xfs_discard_endio_work(&extents->endio_work); in xfs_discard_extents()
156 * Care must be taken setting up the trim cursor as the perags may not have been
158 * read in AGFs and the first operation run on the mounted fs is a trim. This
199 * First time through tcur->count will not have been initialised as in xfs_trim_gather_extents()
200 * pag->pagf_longest is not guaranteed to be valid before we read in xfs_trim_gather_extents()
203 if (!tcur->count) in xfs_trim_gather_extents()
204 tcur->count = pag->pagf_longest; in xfs_trim_gather_extents()
206 if (tcur->by_bno) { in xfs_trim_gather_extents()
207 /* sub-AG discard request always starts at tcur->start */ in xfs_trim_gather_extents()
209 error = xfs_alloc_lookup_le(cur, tcur->start, 0, &i); in xfs_trim_gather_extents()
211 error = xfs_alloc_lookup_ge(cur, tcur->start, 0, &i); in xfs_trim_gather_extents()
212 } else if (tcur->start == 0) { in xfs_trim_gather_extents()
213 /* first time through a by-len starts with max length */ in xfs_trim_gather_extents()
215 error = xfs_alloc_lookup_ge(cur, 0, tcur->count, &i); in xfs_trim_gather_extents()
217 /* nth time through a by-len starts where we left off */ in xfs_trim_gather_extents()
219 error = xfs_alloc_lookup_le(cur, tcur->start, tcur->count, &i); in xfs_trim_gather_extents()
225 tcur->count = 0; in xfs_trim_gather_extents()
242 error = -EFSCORRUPTED; in xfs_trim_gather_extents()
246 if (--batch <= 0) { in xfs_trim_gather_extents()
251 tcur->start = fbno; in xfs_trim_gather_extents()
252 tcur->count = flen; in xfs_trim_gather_extents()
258 * supposed to skip it. Do not bother to trim down partially in xfs_trim_gather_extents()
261 if (fbno + flen < tcur->start) { in xfs_trim_gather_extents()
265 if (fbno > tcur->end) { in xfs_trim_gather_extents()
267 if (tcur->by_bno) { in xfs_trim_gather_extents()
268 tcur->count = 0; in xfs_trim_gather_extents()
274 /* Trim the extent returned to the range we want. */ in xfs_trim_gather_extents()
275 if (fbno < tcur->start) { in xfs_trim_gather_extents()
276 flen -= tcur->start - fbno; in xfs_trim_gather_extents()
277 fbno = tcur->start; in xfs_trim_gather_extents()
279 if (fbno + flen > tcur->end + 1) in xfs_trim_gather_extents()
280 flen = tcur->end - fbno + 1; in xfs_trim_gather_extents()
283 if (flen < tcur->minlen) { in xfs_trim_gather_extents()
285 if (tcur->by_bno) in xfs_trim_gather_extents()
287 tcur->count = 0; in xfs_trim_gather_extents()
301 &extents->extent_list); in xfs_trim_gather_extents()
303 if (tcur->by_bno) in xfs_trim_gather_extents()
316 tcur->count = 0; in xfs_trim_gather_extents()
324 xfs_extent_busy_clear(&extents->extent_list, false); in xfs_trim_gather_extents()
357 if (start != 0 || end != pag_group(pag)->xg_block_count) in xfs_trim_perag_extents()
365 error = -ENOMEM; in xfs_trim_perag_extents()
369 extents->owner = extents; in xfs_trim_perag_extents()
370 INIT_LIST_HEAD(&extents->extent_list); in xfs_trim_perag_extents()
415 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1); in xfs_trim_datadev_extents()
423 xfs_agblock_t agend = pag_group(pag)->xg_block_count; in xfs_trim_datadev_extents()
446 /* minimum length that caller allows us to trim */
468 list_for_each_entry_safe(busyp, n, &tr->extent_list, list) { in xfs_discard_free_rtdev_extents()
469 list_del_init(&busyp->list); in xfs_discard_free_rtdev_extents()
484 struct block_device *bdev = mp->m_rtdev_targp->bt_bdev; in xfs_discard_rtdev_extents()
492 list_for_each_entry(busyp, &tr->extent_list, list) { in xfs_discard_rtdev_extents()
494 start = busyp->bno; in xfs_discard_rtdev_extents()
495 length += busyp->length; in xfs_discard_rtdev_extents()
497 trace_xfs_discard_rtextent(mp, busyp->bno, busyp->length); in xfs_discard_rtdev_extents()
500 xfs_rtb_to_daddr(mp, busyp->bno), in xfs_discard_rtdev_extents()
501 XFS_FSB_TO_BB(mp, busyp->length), in xfs_discard_rtdev_extents()
510 if (error == -EOPNOTSUPP) in xfs_discard_rtdev_extents()
536 if (rec->ar_startext > tr->stop_rtx) { in xfs_trim_gather_rtextent()
542 tr->restart_rtx = rec->ar_startext; in xfs_trim_gather_rtextent()
543 return -ECANCELED; in xfs_trim_gather_rtextent()
546 rbno = xfs_rtx_to_rtb(rtg, rec->ar_startext); in xfs_trim_gather_rtextent()
547 rlen = xfs_rtbxlen_to_blen(rtg_mount(rtg), rec->ar_extcount); in xfs_trim_gather_rtextent()
550 if (rlen < tr->minlen_fsb) { in xfs_trim_gather_rtextent()
557 return -ENOMEM; in xfs_trim_gather_rtextent()
559 busyp->bno = rbno; in xfs_trim_gather_rtextent()
560 busyp->length = rlen; in xfs_trim_gather_rtextent()
561 INIT_LIST_HEAD(&busyp->list); in xfs_trim_gather_rtextent()
562 list_add_tail(&busyp->list, &tr->extent_list); in xfs_trim_gather_rtextent()
564 tr->restart_rtx = rec->ar_startext + rec->ar_extcount; in xfs_trim_gather_rtextent()
568 /* Trim extents on an !rtgroups realtime device */
596 if (error == -ECANCELED) in xfs_trim_rtextents()
625 /* minimum length that caller allows us to trim */
649 if (--tr->batch <= 0) { in xfs_trim_gather_rtgroup_extent()
655 tr->restart_rtx = rec->ar_startext; in xfs_trim_gather_rtgroup_extent()
656 return -ECANCELED; in xfs_trim_gather_rtgroup_extent()
659 rgbno = xfs_rtx_to_rgbno(rtg, rec->ar_startext); in xfs_trim_gather_rtgroup_extent()
660 len = xfs_rtxlen_to_extlen(rtg_mount(rtg), rec->ar_extcount); in xfs_trim_gather_rtgroup_extent()
663 if (len < tr->minlen_fsb) { in xfs_trim_gather_rtgroup_extent()
678 &tr->extents->extent_list); in xfs_trim_gather_rtgroup_extent()
680 tr->queued++; in xfs_trim_gather_rtgroup_extent()
681 tr->restart_rtx = rec->ar_startext + rec->ar_extcount; in xfs_trim_gather_rtgroup_extent()
685 /* Trim extents in this rtgroup using the busy extent machinery. */
709 error = -ENOMEM; in xfs_trim_rtgroup_extents()
715 tr.extents->owner = tr.extents; in xfs_trim_rtgroup_extents()
716 INIT_LIST_HEAD(&tr.extents->extent_list); in xfs_trim_rtgroup_extents()
722 if (error == -ECANCELED) in xfs_trim_rtgroup_extents()
768 daddr_offset = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); in xfs_trim_rtdev_extents()
770 start -= daddr_offset; in xfs_trim_rtdev_extents()
780 end -= daddr_offset; in xfs_trim_rtdev_extents()
782 end_rtx = xfs_rtb_to_rtx(mp, end_rtbno + mp->m_sb.sb_rextsize - 1); in xfs_trim_rtdev_extents()
786 xfs_rtxnum_t rtg_end = rtg->rtg_extents; in xfs_trim_rtdev_extents()
810 # define xfs_trim_rtdev_extents(...) (-EOPNOTSUPP)
814 * trim a range of the filesystem.
820 * comparisons for determining the correct offset and regions to trim.
831 bdev_discard_granularity(mp->m_ddev_targp->bt_bdev); in xfs_ioc_trim()
840 return -EPERM; in xfs_ioc_trim()
842 if (mp->m_rtdev_targp && !xfs_has_zoned(mp) && in xfs_ioc_trim()
843 bdev_max_discard_sectors(mp->m_rtdev_targp->bt_bdev)) in xfs_ioc_trim()
844 rt_bdev = mp->m_rtdev_targp->bt_bdev; in xfs_ioc_trim()
845 if (!bdev_max_discard_sectors(mp->m_ddev_targp->bt_bdev) && !rt_bdev) in xfs_ioc_trim()
846 return -EOPNOTSUPP; in xfs_ioc_trim()
853 * We haven't recovered the log, so we cannot use our bnobt-guided in xfs_ioc_trim()
857 return -EROFS; in xfs_ioc_trim()
860 return -EFAULT; in xfs_ioc_trim()
868 * of ULLONG_MAX or slightly lower. And ULLONG_MAX is the default in xfs_ioc_trim()
872 max_blocks = mp->m_sb.sb_dblocks + mp->m_sb.sb_rblocks; in xfs_ioc_trim()
874 range.minlen > XFS_FSB_TO_B(mp, mp->m_ag_max_usable) || in xfs_ioc_trim()
875 range.len < mp->m_sb.sb_blocksize) in xfs_ioc_trim()
876 return -EINVAL; in xfs_ioc_trim()
879 end = start + BTOBBT(range.len) - 1; in xfs_ioc_trim()
881 if (bdev_max_discard_sectors(mp->m_ddev_targp->bt_bdev)) { in xfs_ioc_trim()
897 XFS_FSB_TO_B(mp, max_blocks) - range.start); in xfs_ioc_trim()
899 return -EFAULT; in xfs_ioc_trim()