Lines Matching +full:low +full:- +full:to +full:- +full:high

1 // SPDX-License-Identifier: GPL-2.0+
32 /* Convert an xfs_fsmap to an fsmap. */
38 dest->fmr_device = src->fmr_device; in xfs_fsmap_from_internal()
39 dest->fmr_flags = src->fmr_flags; in xfs_fsmap_from_internal()
40 dest->fmr_physical = BBTOB(src->fmr_physical); in xfs_fsmap_from_internal()
41 dest->fmr_owner = src->fmr_owner; in xfs_fsmap_from_internal()
42 dest->fmr_offset = BBTOB(src->fmr_offset); in xfs_fsmap_from_internal()
43 dest->fmr_length = BBTOB(src->fmr_length); in xfs_fsmap_from_internal()
44 dest->fmr_reserved[0] = 0; in xfs_fsmap_from_internal()
45 dest->fmr_reserved[1] = 0; in xfs_fsmap_from_internal()
46 dest->fmr_reserved[2] = 0; in xfs_fsmap_from_internal()
49 /* Convert an fsmap to an xfs_fsmap. */
55 dest->fmr_device = src->fmr_device; in xfs_fsmap_to_internal()
56 dest->fmr_flags = src->fmr_flags; in xfs_fsmap_to_internal()
57 dest->fmr_physical = BTOBBT(src->fmr_physical); in xfs_fsmap_to_internal()
58 dest->fmr_owner = src->fmr_owner; in xfs_fsmap_to_internal()
59 dest->fmr_offset = BTOBBT(src->fmr_offset); in xfs_fsmap_to_internal()
60 dest->fmr_length = BTOBBT(src->fmr_length); in xfs_fsmap_to_internal()
69 if (!(src->fmr_flags & FMR_OF_SPECIAL_OWNER)) { in xfs_fsmap_owner_to_rmap()
70 dest->rm_owner = src->fmr_owner; in xfs_fsmap_owner_to_rmap()
74 switch (src->fmr_owner) { in xfs_fsmap_owner_to_rmap()
76 case -1ULL: /* "highest owner id possible" */ in xfs_fsmap_owner_to_rmap()
77 dest->rm_owner = src->fmr_owner; in xfs_fsmap_owner_to_rmap()
80 dest->rm_owner = XFS_RMAP_OWN_NULL; in xfs_fsmap_owner_to_rmap()
83 dest->rm_owner = XFS_RMAP_OWN_UNKNOWN; in xfs_fsmap_owner_to_rmap()
86 dest->rm_owner = XFS_RMAP_OWN_FS; in xfs_fsmap_owner_to_rmap()
89 dest->rm_owner = XFS_RMAP_OWN_LOG; in xfs_fsmap_owner_to_rmap()
92 dest->rm_owner = XFS_RMAP_OWN_AG; in xfs_fsmap_owner_to_rmap()
95 dest->rm_owner = XFS_RMAP_OWN_INOBT; in xfs_fsmap_owner_to_rmap()
98 dest->rm_owner = XFS_RMAP_OWN_INODES; in xfs_fsmap_owner_to_rmap()
101 dest->rm_owner = XFS_RMAP_OWN_REFC; in xfs_fsmap_owner_to_rmap()
104 dest->rm_owner = XFS_RMAP_OWN_COW; in xfs_fsmap_owner_to_rmap()
109 return -EINVAL; in xfs_fsmap_owner_to_rmap()
120 dest->fmr_flags = 0; in xfs_fsmap_owner_from_frec()
121 if (!XFS_RMAP_NON_INODE_OWNER(frec->owner)) { in xfs_fsmap_owner_from_frec()
122 dest->fmr_owner = frec->owner; in xfs_fsmap_owner_from_frec()
125 dest->fmr_flags |= FMR_OF_SPECIAL_OWNER; in xfs_fsmap_owner_from_frec()
127 switch (frec->owner) { in xfs_fsmap_owner_from_frec()
129 dest->fmr_owner = XFS_FMR_OWN_FS; in xfs_fsmap_owner_from_frec()
132 dest->fmr_owner = XFS_FMR_OWN_LOG; in xfs_fsmap_owner_from_frec()
135 dest->fmr_owner = XFS_FMR_OWN_AG; in xfs_fsmap_owner_from_frec()
138 dest->fmr_owner = XFS_FMR_OWN_INOBT; in xfs_fsmap_owner_from_frec()
141 dest->fmr_owner = XFS_FMR_OWN_INODES; in xfs_fsmap_owner_from_frec()
144 dest->fmr_owner = XFS_FMR_OWN_REFC; in xfs_fsmap_owner_from_frec()
147 dest->fmr_owner = XFS_FMR_OWN_COW; in xfs_fsmap_owner_from_frec()
150 dest->fmr_owner = XFS_FMR_OWN_FREE; in xfs_fsmap_owner_from_frec()
154 return -EFSCORRUPTED; in xfs_fsmap_owner_from_frec()
166 /* daddr of low fsmap key when we're using the rtbitmap */
168 /* daddr of high fsmap key, or the last daddr on the device */
173 * Low rmap key for the query. If low.rm_blockcount is nonzero, this
174 * is the second (or later) call to retrieve the recordset in pieces.
176 * by the rmapbt query to filter out any records that start before
179 struct xfs_rmap_irec low; member
180 struct xfs_rmap_irec high; /* high rmap key */ member
202 return d1->dev - d2->dev; in xfs_getfsmap_dev_compare()
213 struct xfs_mount *mp = tp->t_mountp; in xfs_getfsmap_is_shared()
220 if (!xfs_has_reflink(mp) || !info->group) in xfs_getfsmap_is_shared()
223 if (info->group->xg_type == XG_TYPE_RTG) in xfs_getfsmap_is_shared()
224 cur = xfs_rtrefcountbt_init_cursor(tp, to_rtg(info->group)); in xfs_getfsmap_is_shared()
226 cur = xfs_refcountbt_init_cursor(mp, tp, info->agf_bp, in xfs_getfsmap_is_shared()
227 to_perag(info->group)); in xfs_getfsmap_is_shared()
230 error = xfs_refcount_find_shared(cur, frec->rec_key, in xfs_getfsmap_is_shared()
231 XFS_BB_TO_FSBT(mp, frec->len_daddr), &fbno, &flen, in xfs_getfsmap_is_shared()
252 rec = &info->fsmap_recs[info->head->fmh_entries++]; in xfs_getfsmap_format()
261 if (info->low_daddr != XFS_BUF_DADDR_NULL) in xfs_getfsmap_frec_before_start()
262 return frec->start_daddr < info->low_daddr; in xfs_getfsmap_frec_before_start()
263 if (info->low.rm_blockcount) { in xfs_getfsmap_frec_before_start()
265 .rm_startblock = frec->rec_key, in xfs_getfsmap_frec_before_start()
266 .rm_owner = frec->owner, in xfs_getfsmap_frec_before_start()
267 .rm_flags = frec->rm_flags, in xfs_getfsmap_frec_before_start()
270 return xfs_rmap_compare(&rec, &info->low) < 0; in xfs_getfsmap_frec_before_start()
288 struct xfs_mount *mp = tp->t_mountp; in xfs_getfsmap_helper()
293 return -EINTR; in xfs_getfsmap_helper()
303 if (info->head->fmh_count == 0) { in xfs_getfsmap_helper()
304 if (info->head->fmh_entries == UINT_MAX) in xfs_getfsmap_helper()
305 return -ECANCELED; in xfs_getfsmap_helper()
307 if (frec->start_daddr > info->next_daddr) in xfs_getfsmap_helper()
308 info->head->fmh_entries++; in xfs_getfsmap_helper()
310 if (info->last) in xfs_getfsmap_helper()
313 info->head->fmh_entries++; in xfs_getfsmap_helper()
322 if (frec->start_daddr > info->next_daddr) { in xfs_getfsmap_helper()
323 if (info->head->fmh_entries >= info->head->fmh_count) in xfs_getfsmap_helper()
324 return -ECANCELED; in xfs_getfsmap_helper()
326 fmr.fmr_device = info->dev; in xfs_getfsmap_helper()
327 fmr.fmr_physical = info->next_daddr; in xfs_getfsmap_helper()
328 fmr.fmr_owner = info->missing_owner; in xfs_getfsmap_helper()
330 fmr.fmr_length = frec->start_daddr - info->next_daddr; in xfs_getfsmap_helper()
335 if (info->last) in xfs_getfsmap_helper()
339 if (info->head->fmh_entries >= info->head->fmh_count) in xfs_getfsmap_helper()
340 return -ECANCELED; in xfs_getfsmap_helper()
342 trace_xfs_fsmap_mapping(mp, info->dev, in xfs_getfsmap_helper()
343 info->group ? info->group->xg_gno : NULLAGNUMBER, in xfs_getfsmap_helper()
346 fmr.fmr_device = info->dev; in xfs_getfsmap_helper()
347 fmr.fmr_physical = frec->start_daddr; in xfs_getfsmap_helper()
351 fmr.fmr_offset = XFS_FSB_TO_BB(mp, frec->offset); in xfs_getfsmap_helper()
352 fmr.fmr_length = frec->len_daddr; in xfs_getfsmap_helper()
353 if (frec->rm_flags & XFS_RMAP_UNWRITTEN) in xfs_getfsmap_helper()
355 if (frec->rm_flags & XFS_RMAP_ATTR_FORK) in xfs_getfsmap_helper()
357 if (frec->rm_flags & XFS_RMAP_BMBT_BLOCK) in xfs_getfsmap_helper()
369 info->next_daddr = max(info->next_daddr, in xfs_getfsmap_helper()
370 frec->start_daddr + frec->len_daddr); in xfs_getfsmap_helper()
384 * For an info->last query, we're looking for a gap between the last in xfs_getfsmap_group_helper()
385 * mapping emitted and the high key specified by userspace. If the in xfs_getfsmap_group_helper()
386 * user's query spans less than 1 fsblock, then info->high and in xfs_getfsmap_group_helper()
387 * info->low will have the same rm_startblock, which causes rec_daddr in xfs_getfsmap_group_helper()
388 * and next_daddr to be the same. Therefore, use the end_daddr that in xfs_getfsmap_group_helper()
389 * we calculated from userspace's high key to synthesize the record. in xfs_getfsmap_group_helper()
392 if (info->last) in xfs_getfsmap_group_helper()
393 frec->start_daddr = info->end_daddr + 1; in xfs_getfsmap_group_helper()
395 frec->start_daddr = xfs_gbno_to_daddr(xg, startblock); in xfs_getfsmap_group_helper()
397 frec->len_daddr = XFS_FSB_TO_BB(xg->xg_mount, blockcount); in xfs_getfsmap_group_helper()
409 .owner = rec->rm_owner, in xfs_getfsmap_rmapbt_helper()
410 .offset = rec->rm_offset, in xfs_getfsmap_rmapbt_helper()
411 .rm_flags = rec->rm_flags, in xfs_getfsmap_rmapbt_helper()
412 .rec_key = rec->rm_startblock, in xfs_getfsmap_rmapbt_helper()
416 return xfs_getfsmap_group_helper(info, cur->bc_tp, cur->bc_group, in xfs_getfsmap_rmapbt_helper()
417 rec->rm_startblock, rec->rm_blockcount, &frec); in xfs_getfsmap_rmapbt_helper()
429 .rec_key = rec->ar_startblock, in xfs_getfsmap_datadev_bnobt_helper()
433 return xfs_getfsmap_group_helper(info, cur->bc_tp, cur->bc_group, in xfs_getfsmap_datadev_bnobt_helper()
434 rec->ar_startblock, rec->ar_blockcount, &frec); in xfs_getfsmap_datadev_bnobt_helper()
443 irec->rm_flags = 0; in xfs_getfsmap_set_irec_flags()
444 if (fmr->fmr_flags & FMR_OF_ATTR_FORK) in xfs_getfsmap_set_irec_flags()
445 irec->rm_flags |= XFS_RMAP_ATTR_FORK; in xfs_getfsmap_set_irec_flags()
446 if (fmr->fmr_flags & FMR_OF_EXTENT_MAP) in xfs_getfsmap_set_irec_flags()
447 irec->rm_flags |= XFS_RMAP_BMBT_BLOCK; in xfs_getfsmap_set_irec_flags()
448 if (fmr->fmr_flags & FMR_OF_PREALLOC) in xfs_getfsmap_set_irec_flags()
449 irec->rm_flags |= XFS_RMAP_UNWRITTEN; in xfs_getfsmap_set_irec_flags()
457 if (XFS_RMAP_NON_INODE_OWNER(r->rm_owner)) in rmap_not_shareable()
459 if (r->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK | in rmap_not_shareable()
477 struct xfs_mount *mp = tp->t_mountp; in __xfs_getfsmap_datadev()
486 eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); in __xfs_getfsmap_datadev()
490 end_fsb = XFS_DADDR_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); in __xfs_getfsmap_datadev()
493 * Convert the fsmap low/high keys to AG based keys. Initialize in __xfs_getfsmap_datadev()
494 * low to the fsmap low key and max out the high key to the end in __xfs_getfsmap_datadev()
497 info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); in __xfs_getfsmap_datadev()
498 error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); in __xfs_getfsmap_datadev()
501 info->low.rm_blockcount = XFS_BB_TO_FSBT(mp, keys[0].fmr_length); in __xfs_getfsmap_datadev()
502 xfs_getfsmap_set_irec_flags(&info->low, &keys[0]); in __xfs_getfsmap_datadev()
504 /* Adjust the low key if we are continuing from where we left off. */ in __xfs_getfsmap_datadev()
505 if (info->low.rm_blockcount == 0) { in __xfs_getfsmap_datadev()
506 /* No previous record from which to continue */ in __xfs_getfsmap_datadev()
507 } else if (rmap_not_shareable(mp, &info->low)) { in __xfs_getfsmap_datadev()
509 info->low.rm_owner = 0; in __xfs_getfsmap_datadev()
510 info->low.rm_offset = 0; in __xfs_getfsmap_datadev()
512 start_fsb += info->low.rm_blockcount; in __xfs_getfsmap_datadev()
517 info->low.rm_offset += info->low.rm_blockcount; in __xfs_getfsmap_datadev()
519 info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb); in __xfs_getfsmap_datadev()
521 info->high.rm_startblock = -1U; in __xfs_getfsmap_datadev()
522 info->high.rm_owner = ULLONG_MAX; in __xfs_getfsmap_datadev()
523 info->high.rm_offset = ULLONG_MAX; in __xfs_getfsmap_datadev()
524 info->high.rm_blockcount = 0; in __xfs_getfsmap_datadev()
525 info->high.rm_flags = XFS_RMAP_KEY_FLAGS | XFS_RMAP_REC_FLAGS; in __xfs_getfsmap_datadev()
532 * Set the AG high key from the fsmap high key if this in __xfs_getfsmap_datadev()
535 info->group = pag_group(pag); in __xfs_getfsmap_datadev()
537 info->high.rm_startblock = XFS_FSB_TO_AGBNO(mp, in __xfs_getfsmap_datadev()
539 info->high.rm_offset = XFS_BB_TO_FSBT(mp, in __xfs_getfsmap_datadev()
541 error = xfs_fsmap_owner_to_rmap(&info->high, &keys[1]); in __xfs_getfsmap_datadev()
544 xfs_getfsmap_set_irec_flags(&info->high, &keys[1]); in __xfs_getfsmap_datadev()
550 xfs_trans_brelse(tp, info->agf_bp); in __xfs_getfsmap_datadev()
551 info->agf_bp = NULL; in __xfs_getfsmap_datadev()
554 error = xfs_alloc_read_agf(pag, tp, 0, &info->agf_bp); in __xfs_getfsmap_datadev()
558 trace_xfs_fsmap_low_group_key(mp, info->dev, pag_agno(pag), in __xfs_getfsmap_datadev()
559 &info->low); in __xfs_getfsmap_datadev()
560 trace_xfs_fsmap_high_group_key(mp, info->dev, pag_agno(pag), in __xfs_getfsmap_datadev()
561 &info->high); in __xfs_getfsmap_datadev()
568 * Set the AG low key to the start of the AG prior to in __xfs_getfsmap_datadev()
569 * moving on to the next AG. in __xfs_getfsmap_datadev()
572 memset(&info->low, 0, sizeof(info->low)); in __xfs_getfsmap_datadev()
576 * before we drop the reference to the perag when the loop in __xfs_getfsmap_datadev()
580 info->last = true; in __xfs_getfsmap_datadev()
585 info->group = NULL; in __xfs_getfsmap_datadev()
591 if (info->agf_bp) { in __xfs_getfsmap_datadev()
592 xfs_trans_brelse(tp, info->agf_bp); in __xfs_getfsmap_datadev()
593 info->agf_bp = NULL; in __xfs_getfsmap_datadev()
595 if (info->group) { in __xfs_getfsmap_datadev()
597 info->group = NULL; in __xfs_getfsmap_datadev()
615 if (info->last) in xfs_getfsmap_datadev_rmapbt_query()
616 return xfs_getfsmap_rmapbt_helper(*curpp, &info->high, info); in xfs_getfsmap_datadev_rmapbt_query()
619 *curpp = xfs_rmapbt_init_cursor(tp->t_mountp, tp, info->agf_bp, in xfs_getfsmap_datadev_rmapbt_query()
620 to_perag(info->group)); in xfs_getfsmap_datadev_rmapbt_query()
621 return xfs_rmap_query_range(*curpp, &info->low, &info->high, in xfs_getfsmap_datadev_rmapbt_query()
632 info->missing_owner = XFS_FMR_OWN_FREE; in xfs_getfsmap_datadev_rmapbt()
648 if (info->last) in xfs_getfsmap_datadev_bnobt_query()
652 *curpp = xfs_bnobt_init_cursor(tp->t_mountp, tp, info->agf_bp, in xfs_getfsmap_datadev_bnobt_query()
653 to_perag(info->group)); in xfs_getfsmap_datadev_bnobt_query()
654 key->ar_startblock = info->low.rm_startblock; in xfs_getfsmap_datadev_bnobt_query()
655 key[1].ar_startblock = info->high.rm_startblock; in xfs_getfsmap_datadev_bnobt_query()
670 info->missing_owner = XFS_FMR_OWN_UNKNOWN; in xfs_getfsmap_datadev_bnobt()
687 struct xfs_mount *mp = tp->t_mountp; in xfs_getfsmap_logdev()
691 eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); in xfs_getfsmap_logdev()
696 end_fsb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); in xfs_getfsmap_logdev()
698 /* Adjust the low key if we are continuing from where we left off. */ in xfs_getfsmap_logdev()
700 info->low_daddr = XFS_FSB_TO_BB(mp, start_fsb); in xfs_getfsmap_logdev()
702 trace_xfs_fsmap_low_linear_key(mp, info->dev, start_fsb); in xfs_getfsmap_logdev()
703 trace_xfs_fsmap_high_linear_key(mp, info->dev, end_fsb); in xfs_getfsmap_logdev()
709 frec.len_daddr = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); in xfs_getfsmap_logdev()
728 xfs_rtx_to_rtb(rtg, rec->ar_startext); in xfs_getfsmap_rtdev_rtbitmap_helper()
730 xfs_rtbxlen_to_blen(mp, rec->ar_extcount); in xfs_getfsmap_rtdev_rtbitmap_helper()
733 * For an info->last query, we're looking for a gap between the last in xfs_getfsmap_rtdev_rtbitmap_helper()
734 * mapping emitted and the high key specified by userspace. If the in xfs_getfsmap_rtdev_rtbitmap_helper()
735 * user's query spans less than 1 fsblock, then info->high and in xfs_getfsmap_rtdev_rtbitmap_helper()
736 * info->low will have the same rm_startblock, which causes rec_daddr in xfs_getfsmap_rtdev_rtbitmap_helper()
737 * and next_daddr to be the same. Therefore, use the end_daddr that in xfs_getfsmap_rtdev_rtbitmap_helper()
738 * we calculated from userspace's high key to synthesize the record. in xfs_getfsmap_rtdev_rtbitmap_helper()
741 if (info->last) in xfs_getfsmap_rtdev_rtbitmap_helper()
742 frec.start_daddr = info->end_daddr + 1; in xfs_getfsmap_rtdev_rtbitmap_helper()
757 struct xfs_mount *mp = tp->t_mountp; in xfs_getfsmap_rtdev_rtbitmap()
765 eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks); in xfs_getfsmap_rtdev_rtbitmap()
769 info->missing_owner = XFS_FMR_OWN_UNKNOWN; in xfs_getfsmap_rtdev_rtbitmap()
771 /* Adjust the low key if we are continuing from where we left off. */ in xfs_getfsmap_rtdev_rtbitmap()
775 info->low_daddr = xfs_rtb_to_daddr(mp, start_rtbno); in xfs_getfsmap_rtdev_rtbitmap()
776 if (info->low_daddr >= eofs) in xfs_getfsmap_rtdev_rtbitmap()
782 end_rtbno = xfs_daddr_to_rtb(mp, min(eofs - 1, keys[1].fmr_physical)); in xfs_getfsmap_rtdev_rtbitmap()
785 trace_xfs_fsmap_low_linear_key(mp, info->dev, start_rtbno); in xfs_getfsmap_rtdev_rtbitmap()
786 trace_xfs_fsmap_high_linear_key(mp, info->dev, end_rtbno); in xfs_getfsmap_rtdev_rtbitmap()
788 end_rtx = -1ULL; in xfs_getfsmap_rtdev_rtbitmap()
793 end_rtbno + mp->m_sb.sb_rextsize - 1); in xfs_getfsmap_rtdev_rtbitmap()
795 info->group = rtg_group(rtg); in xfs_getfsmap_rtdev_rtbitmap()
804 * zero-length free extent starting at the rtx after the end in xfs_getfsmap_rtdev_rtbitmap()
810 rtg->rtg_extents), in xfs_getfsmap_rtdev_rtbitmap()
813 info->last = true; in xfs_getfsmap_rtdev_rtbitmap()
821 info->group = NULL; in xfs_getfsmap_rtdev_rtbitmap()
827 if (info->group) { in xfs_getfsmap_rtdev_rtbitmap()
829 info->group = NULL; in xfs_getfsmap_rtdev_rtbitmap()
845 .owner = rec->rm_owner, in xfs_getfsmap_rtdev_rmapbt_helper()
846 .offset = rec->rm_offset, in xfs_getfsmap_rtdev_rmapbt_helper()
847 .rm_flags = rec->rm_flags, in xfs_getfsmap_rtdev_rmapbt_helper()
848 .rec_key = rec->rm_startblock, in xfs_getfsmap_rtdev_rmapbt_helper()
852 return xfs_getfsmap_group_helper(info, cur->bc_tp, cur->bc_group, in xfs_getfsmap_rtdev_rmapbt_helper()
853 rec->rm_startblock, rec->rm_blockcount, &frec); in xfs_getfsmap_rtdev_rmapbt_helper()
863 struct xfs_rtgroup *rtg = to_rtg(info->group); in xfs_getfsmap_rtdev_rmapbt_query()
868 return xfs_rmap_query_range(*curpp, &info->low, &info->high, in xfs_getfsmap_rtdev_rmapbt_query()
879 struct xfs_mount *mp = tp->t_mountp; in xfs_getfsmap_rtdev_rmapbt()
888 eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks); in xfs_getfsmap_rtdev_rmapbt()
892 end_rtb = xfs_daddr_to_rtb(mp, min(eofs - 1, keys[1].fmr_physical)); in xfs_getfsmap_rtdev_rmapbt()
894 info->missing_owner = XFS_FMR_OWN_FREE; in xfs_getfsmap_rtdev_rmapbt()
897 * Convert the fsmap low/high keys to rtgroup based keys. Initialize in xfs_getfsmap_rtdev_rmapbt()
898 * low to the fsmap low key and max out the high key to the end in xfs_getfsmap_rtdev_rmapbt()
901 info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); in xfs_getfsmap_rtdev_rmapbt()
902 error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); in xfs_getfsmap_rtdev_rmapbt()
905 info->low.rm_blockcount = XFS_BB_TO_FSBT(mp, keys[0].fmr_length); in xfs_getfsmap_rtdev_rmapbt()
906 xfs_getfsmap_set_irec_flags(&info->low, &keys[0]); in xfs_getfsmap_rtdev_rmapbt()
908 /* Adjust the low key if we are continuing from where we left off. */ in xfs_getfsmap_rtdev_rmapbt()
909 if (info->low.rm_blockcount == 0) { in xfs_getfsmap_rtdev_rmapbt()
910 /* No previous record from which to continue */ in xfs_getfsmap_rtdev_rmapbt()
911 } else if (rmap_not_shareable(mp, &info->low)) { in xfs_getfsmap_rtdev_rmapbt()
913 info->low.rm_owner = 0; in xfs_getfsmap_rtdev_rmapbt()
914 info->low.rm_offset = 0; in xfs_getfsmap_rtdev_rmapbt()
916 start_rtb += info->low.rm_blockcount; in xfs_getfsmap_rtdev_rmapbt()
921 info->low.rm_offset += info->low.rm_blockcount; in xfs_getfsmap_rtdev_rmapbt()
923 info->low.rm_startblock = xfs_rtb_to_rgbno(mp, start_rtb); in xfs_getfsmap_rtdev_rmapbt()
925 info->high.rm_startblock = -1U; in xfs_getfsmap_rtdev_rmapbt()
926 info->high.rm_owner = ULLONG_MAX; in xfs_getfsmap_rtdev_rmapbt()
927 info->high.rm_offset = ULLONG_MAX; in xfs_getfsmap_rtdev_rmapbt()
928 info->high.rm_blockcount = 0; in xfs_getfsmap_rtdev_rmapbt()
929 info->high.rm_flags = XFS_RMAP_KEY_FLAGS | XFS_RMAP_REC_FLAGS; in xfs_getfsmap_rtdev_rmapbt()
936 * Set the rtgroup high key from the fsmap high key if this in xfs_getfsmap_rtdev_rmapbt()
939 info->group = rtg_group(rtg); in xfs_getfsmap_rtdev_rmapbt()
941 info->high.rm_startblock = in xfs_getfsmap_rtdev_rmapbt()
943 info->high.rm_offset = in xfs_getfsmap_rtdev_rmapbt()
945 error = xfs_fsmap_owner_to_rmap(&info->high, &keys[1]); in xfs_getfsmap_rtdev_rmapbt()
948 xfs_getfsmap_set_irec_flags(&info->high, &keys[1]); in xfs_getfsmap_rtdev_rmapbt()
952 xfs_rtgroup_unlock(to_rtg(bt_cur->bc_group), in xfs_getfsmap_rtdev_rmapbt()
959 trace_xfs_fsmap_low_group_key(mp, info->dev, rtg_rgno(rtg), in xfs_getfsmap_rtdev_rmapbt()
960 &info->low); in xfs_getfsmap_rtdev_rmapbt()
961 trace_xfs_fsmap_high_group_key(mp, info->dev, rtg_rgno(rtg), in xfs_getfsmap_rtdev_rmapbt()
962 &info->high); in xfs_getfsmap_rtdev_rmapbt()
969 * Set the rtgroup low key to the start of the rtgroup prior to in xfs_getfsmap_rtdev_rmapbt()
970 * moving on to the next rtgroup. in xfs_getfsmap_rtdev_rmapbt()
973 memset(&info->low, 0, sizeof(info->low)); in xfs_getfsmap_rtdev_rmapbt()
977 * before we drop the reference to the perag when the loop in xfs_getfsmap_rtdev_rmapbt()
981 info->last = true; in xfs_getfsmap_rtdev_rmapbt()
983 &info->high, info); in xfs_getfsmap_rtdev_rmapbt()
987 info->group = NULL; in xfs_getfsmap_rtdev_rmapbt()
991 xfs_rtgroup_unlock(to_rtg(bt_cur->bc_group), in xfs_getfsmap_rtdev_rmapbt()
999 info->group = NULL; in xfs_getfsmap_rtdev_rmapbt()
1013 if (fm->fmr_device == 0 || fm->fmr_device == UINT_MAX || in xfs_getfsmap_is_valid_device()
1014 fm->fmr_device == new_encode_dev(mp->m_ddev_targp->bt_dev)) in xfs_getfsmap_is_valid_device()
1016 if (mp->m_logdev_targp && in xfs_getfsmap_is_valid_device()
1017 fm->fmr_device == new_encode_dev(mp->m_logdev_targp->bt_dev)) in xfs_getfsmap_is_valid_device()
1019 if (mp->m_rtdev_targp && in xfs_getfsmap_is_valid_device()
1020 fm->fmr_device == new_encode_dev(mp->m_rtdev_targp->bt_dev)) in xfs_getfsmap_is_valid_device()
1025 /* Ensure that the low key is less than the high key. */
1031 if (low_key->fmr_flags & (FMR_OF_SPECIAL_OWNER | FMR_OF_EXTENT_MAP)) { in xfs_getfsmap_check_keys()
1032 if (low_key->fmr_offset) in xfs_getfsmap_check_keys()
1035 if (high_key->fmr_flags != -1U && in xfs_getfsmap_check_keys()
1036 (high_key->fmr_flags & (FMR_OF_SPECIAL_OWNER | in xfs_getfsmap_check_keys()
1038 if (high_key->fmr_offset && high_key->fmr_offset != -1ULL) in xfs_getfsmap_check_keys()
1041 if (high_key->fmr_length && high_key->fmr_length != -1ULL) in xfs_getfsmap_check_keys()
1044 if (low_key->fmr_device > high_key->fmr_device) in xfs_getfsmap_check_keys()
1046 if (low_key->fmr_device < high_key->fmr_device) in xfs_getfsmap_check_keys()
1049 if (low_key->fmr_physical > high_key->fmr_physical) in xfs_getfsmap_check_keys()
1051 if (low_key->fmr_physical < high_key->fmr_physical) in xfs_getfsmap_check_keys()
1054 if (low_key->fmr_owner > high_key->fmr_owner) in xfs_getfsmap_check_keys()
1056 if (low_key->fmr_owner < high_key->fmr_owner) in xfs_getfsmap_check_keys()
1059 if (low_key->fmr_offset > high_key->fmr_offset) in xfs_getfsmap_check_keys()
1061 if (low_key->fmr_offset < high_key->fmr_offset) in xfs_getfsmap_check_keys()
1078 * in the supplied records array until there are no more reverse mappings to
1080 * function returns -ECANCELED to indicate that more records would have been
1083 * Key to Confusion
1084 * ----------------
1086 * xfs_fsmap_head.fmh_keys -- low and high fsmap keys passed in;
1087 * these reflect fs-wide sector addrs.
1088 * dkeys -- fmh_keys used to query each device;
1089 * these are fmh_keys but w/ the low key
1091 * xfs_getfsmap_info.next_daddr -- next disk addr we expect to see; this
1094 * xfs_getfsmap_info.low/high -- per-AG low/high keys computed from
1095 * dkeys; used to query the metadata.
1104 struct xfs_fsmap dkeys[2]; /* per-dev keys */ in xfs_getfsmap()
1114 if (head->fmh_iflags & ~FMH_IF_VALID) in xfs_getfsmap()
1115 return -EINVAL; in xfs_getfsmap()
1116 if (!xfs_getfsmap_is_valid_device(mp, &head->fmh_keys[0]) || in xfs_getfsmap()
1117 !xfs_getfsmap_is_valid_device(mp, &head->fmh_keys[1])) in xfs_getfsmap()
1118 return -EINVAL; in xfs_getfsmap()
1119 if (!xfs_getfsmap_check_keys(&head->fmh_keys[0], &head->fmh_keys[1])) in xfs_getfsmap()
1120 return -EINVAL; in xfs_getfsmap()
1124 head->fmh_entries = 0; in xfs_getfsmap()
1128 handlers[0].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); in xfs_getfsmap()
1129 handlers[0].dev = new_encode_dev(mp->m_ddev_targp->bt_dev); in xfs_getfsmap()
1134 if (mp->m_logdev_targp != mp->m_ddev_targp) { in xfs_getfsmap()
1136 mp->m_sb.sb_logblocks); in xfs_getfsmap()
1137 handlers[1].dev = new_encode_dev(mp->m_logdev_targp->bt_dev); in xfs_getfsmap()
1141 if (mp->m_rtdev_targp) { in xfs_getfsmap()
1142 handlers[2].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks); in xfs_getfsmap()
1143 handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev); in xfs_getfsmap()
1155 * To continue where we left off, we allow userspace to use the in xfs_getfsmap()
1156 * last mapping from a previous call as the low key of the next. in xfs_getfsmap()
1157 * This is identified by a non-zero length in the low key. We in xfs_getfsmap()
1158 * have to increment the low key in this scenario to ensure we in xfs_getfsmap()
1162 * If the low key mapping refers to file data, the same physical in xfs_getfsmap()
1163 * blocks could be mapped to several other files/offsets. in xfs_getfsmap()
1164 * According to rmapbt record ordering, the minimal next in xfs_getfsmap()
1167 * the file offset to continue the search appropriately. For in xfs_getfsmap()
1168 * all other low key mapping types (attr blocks, metadata), each in xfs_getfsmap()
1172 dkeys[0] = head->fmh_keys[0]; in xfs_getfsmap()
1175 info.next_daddr = head->fmh_keys[0].fmr_physical + in xfs_getfsmap()
1176 head->fmh_keys[0].fmr_length; in xfs_getfsmap()
1183 if (head->fmh_keys[0].fmr_device > handlers[i].dev) in xfs_getfsmap()
1185 if (head->fmh_keys[1].fmr_device < handlers[i].dev) in xfs_getfsmap()
1189 * If this device number matches the high key, we have to pass in xfs_getfsmap()
1190 * the high key to the handler to limit the query results, and in xfs_getfsmap()
1194 if (handlers[i].dev == head->fmh_keys[1].fmr_device) { in xfs_getfsmap()
1195 dkeys[1] = head->fmh_keys[1]; in xfs_getfsmap()
1196 info.end_daddr = min(handlers[i].nr_sectors - 1, in xfs_getfsmap()
1199 info.end_daddr = handlers[i].nr_sectors - 1; in xfs_getfsmap()
1203 * If the device number exceeds the low key, zero out the low in xfs_getfsmap()
1206 if (handlers[i].dev > head->fmh_keys[0].fmr_device) in xfs_getfsmap()
1211 * buffer locking abilities to detect cycles in the rmapbt in xfs_getfsmap()
1222 info.low.rm_blockcount = 0; in xfs_getfsmap()
1233 head->fmh_oflags = FMH_OF_DEV_T; in xfs_getfsmap()
1251 return -EFAULT; in xfs_ioc_getfsmap()
1257 return -EINVAL; in xfs_ioc_getfsmap()
1260 * Use an internal memory buffer so that we don't have to copy fsmap in xfs_ioc_getfsmap()
1261 * data to userspace while holding locks. Start by trying to allocate in xfs_ioc_getfsmap()
1262 * up to 128k for the buffer, but fall back to a single page if needed. in xfs_ioc_getfsmap()
1272 return -ENOMEM; in xfs_ioc_getfsmap()
1279 trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); in xfs_ioc_getfsmap()
1280 trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]); in xfs_ioc_getfsmap()
1287 user_recs = &arg->fmh_recs[head.fmh_entries]; in xfs_ioc_getfsmap()
1290 head.fmh_count - head.fmh_entries); in xfs_ioc_getfsmap()
1293 error = xfs_getfsmap(ip->i_mount, &xhead, recs); in xfs_ioc_getfsmap()
1298 * whatever we got to userspace and break out. in xfs_ioc_getfsmap()
1302 case -ECANCELED: in xfs_ioc_getfsmap()
1305 * records we got to userspace and go again if we have in xfs_ioc_getfsmap()
1318 * new records to return, we're done. in xfs_ioc_getfsmap()
1323 /* Copy all the records we got out to userspace. */ in xfs_ioc_getfsmap()
1326 error = -EFAULT; in xfs_ioc_getfsmap()
1330 /* Remember the last record flags we copied to userspace. */ in xfs_ioc_getfsmap()
1331 last_rec = &recs[xhead.fmh_entries - 1]; in xfs_ioc_getfsmap()
1332 last_flags = last_rec->fmr_flags; in xfs_ioc_getfsmap()
1334 /* Set up the low key for the next iteration. */ in xfs_ioc_getfsmap()
1336 trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); in xfs_ioc_getfsmap()
1347 user_rec = &arg->fmh_recs[head.fmh_entries - 1]; in xfs_ioc_getfsmap()
1349 if (copy_to_user(&user_rec->fmr_flags, &last_flags, in xfs_ioc_getfsmap()
1351 error = -EFAULT; in xfs_ioc_getfsmap()
1358 error = -EFAULT; in xfs_ioc_getfsmap()