1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2017 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <darrick.wong@oracle.com> 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_log_format.h" 11 #include "xfs_trans_resv.h" 12 #include "xfs_mount.h" 13 #include "xfs_inode.h" 14 #include "xfs_trans.h" 15 #include "xfs_btree.h" 16 #include "xfs_rmap_btree.h" 17 #include "xfs_trace.h" 18 #include "xfs_rmap.h" 19 #include "xfs_alloc.h" 20 #include "xfs_bit.h" 21 #include <linux/fsmap.h> 22 #include "xfs_fsmap.h" 23 #include "xfs_refcount.h" 24 #include "xfs_refcount_btree.h" 25 #include "xfs_alloc_btree.h" 26 #include "xfs_rtalloc.h" 27 #include "xfs_ag.h" 28 29 /* Convert an xfs_fsmap to an fsmap. */ 30 static void 31 xfs_fsmap_from_internal( 32 struct fsmap *dest, 33 struct xfs_fsmap *src) 34 { 35 dest->fmr_device = src->fmr_device; 36 dest->fmr_flags = src->fmr_flags; 37 dest->fmr_physical = BBTOB(src->fmr_physical); 38 dest->fmr_owner = src->fmr_owner; 39 dest->fmr_offset = BBTOB(src->fmr_offset); 40 dest->fmr_length = BBTOB(src->fmr_length); 41 dest->fmr_reserved[0] = 0; 42 dest->fmr_reserved[1] = 0; 43 dest->fmr_reserved[2] = 0; 44 } 45 46 /* Convert an fsmap to an xfs_fsmap. */ 47 void 48 xfs_fsmap_to_internal( 49 struct xfs_fsmap *dest, 50 struct fsmap *src) 51 { 52 dest->fmr_device = src->fmr_device; 53 dest->fmr_flags = src->fmr_flags; 54 dest->fmr_physical = BTOBBT(src->fmr_physical); 55 dest->fmr_owner = src->fmr_owner; 56 dest->fmr_offset = BTOBBT(src->fmr_offset); 57 dest->fmr_length = BTOBBT(src->fmr_length); 58 } 59 60 /* Convert an fsmap owner into an rmapbt owner. */ 61 static int 62 xfs_fsmap_owner_to_rmap( 63 struct xfs_rmap_irec *dest, 64 struct xfs_fsmap *src) 65 { 66 if (!(src->fmr_flags & FMR_OF_SPECIAL_OWNER)) { 67 dest->rm_owner = src->fmr_owner; 68 return 0; 69 } 70 71 switch (src->fmr_owner) { 72 case 0: /* "lowest owner id possible" */ 73 case -1ULL: /* "highest owner id possible" */ 74 dest->rm_owner = 0; 75 break; 76 case XFS_FMR_OWN_FREE: 77 dest->rm_owner = XFS_RMAP_OWN_NULL; 78 break; 79 case XFS_FMR_OWN_UNKNOWN: 80 dest->rm_owner = XFS_RMAP_OWN_UNKNOWN; 81 break; 82 case XFS_FMR_OWN_FS: 83 dest->rm_owner = XFS_RMAP_OWN_FS; 84 break; 85 case XFS_FMR_OWN_LOG: 86 dest->rm_owner = XFS_RMAP_OWN_LOG; 87 break; 88 case XFS_FMR_OWN_AG: 89 dest->rm_owner = XFS_RMAP_OWN_AG; 90 break; 91 case XFS_FMR_OWN_INOBT: 92 dest->rm_owner = XFS_RMAP_OWN_INOBT; 93 break; 94 case XFS_FMR_OWN_INODES: 95 dest->rm_owner = XFS_RMAP_OWN_INODES; 96 break; 97 case XFS_FMR_OWN_REFC: 98 dest->rm_owner = XFS_RMAP_OWN_REFC; 99 break; 100 case XFS_FMR_OWN_COW: 101 dest->rm_owner = XFS_RMAP_OWN_COW; 102 break; 103 case XFS_FMR_OWN_DEFECTIVE: /* not implemented */ 104 /* fall through */ 105 default: 106 return -EINVAL; 107 } 108 return 0; 109 } 110 111 /* Convert an rmapbt owner into an fsmap owner. */ 112 static int 113 xfs_fsmap_owner_from_rmap( 114 struct xfs_fsmap *dest, 115 struct xfs_rmap_irec *src) 116 { 117 dest->fmr_flags = 0; 118 if (!XFS_RMAP_NON_INODE_OWNER(src->rm_owner)) { 119 dest->fmr_owner = src->rm_owner; 120 return 0; 121 } 122 dest->fmr_flags |= FMR_OF_SPECIAL_OWNER; 123 124 switch (src->rm_owner) { 125 case XFS_RMAP_OWN_FS: 126 dest->fmr_owner = XFS_FMR_OWN_FS; 127 break; 128 case XFS_RMAP_OWN_LOG: 129 dest->fmr_owner = XFS_FMR_OWN_LOG; 130 break; 131 case XFS_RMAP_OWN_AG: 132 dest->fmr_owner = XFS_FMR_OWN_AG; 133 break; 134 case XFS_RMAP_OWN_INOBT: 135 dest->fmr_owner = XFS_FMR_OWN_INOBT; 136 break; 137 case XFS_RMAP_OWN_INODES: 138 dest->fmr_owner = XFS_FMR_OWN_INODES; 139 break; 140 case XFS_RMAP_OWN_REFC: 141 dest->fmr_owner = XFS_FMR_OWN_REFC; 142 break; 143 case XFS_RMAP_OWN_COW: 144 dest->fmr_owner = XFS_FMR_OWN_COW; 145 break; 146 case XFS_RMAP_OWN_NULL: /* "free" */ 147 dest->fmr_owner = XFS_FMR_OWN_FREE; 148 break; 149 default: 150 ASSERT(0); 151 return -EFSCORRUPTED; 152 } 153 return 0; 154 } 155 156 /* getfsmap query state */ 157 struct xfs_getfsmap_info { 158 struct xfs_fsmap_head *head; 159 struct fsmap *fsmap_recs; /* mapping records */ 160 struct xfs_buf *agf_bp; /* AGF, for refcount queries */ 161 struct xfs_perag *pag; /* AG info, if applicable */ 162 xfs_daddr_t next_daddr; /* next daddr we expect */ 163 u64 missing_owner; /* owner of holes */ 164 u32 dev; /* device id */ 165 struct xfs_rmap_irec low; /* low rmap key */ 166 struct xfs_rmap_irec high; /* high rmap key */ 167 bool last; /* last extent? */ 168 }; 169 170 /* Associate a device with a getfsmap handler. */ 171 struct xfs_getfsmap_dev { 172 u32 dev; 173 int (*fn)(struct xfs_trans *tp, 174 struct xfs_fsmap *keys, 175 struct xfs_getfsmap_info *info); 176 }; 177 178 /* Compare two getfsmap device handlers. */ 179 static int 180 xfs_getfsmap_dev_compare( 181 const void *p1, 182 const void *p2) 183 { 184 const struct xfs_getfsmap_dev *d1 = p1; 185 const struct xfs_getfsmap_dev *d2 = p2; 186 187 return d1->dev - d2->dev; 188 } 189 190 /* Decide if this mapping is shared. */ 191 STATIC int 192 xfs_getfsmap_is_shared( 193 struct xfs_trans *tp, 194 struct xfs_getfsmap_info *info, 195 struct xfs_rmap_irec *rec, 196 bool *stat) 197 { 198 struct xfs_mount *mp = tp->t_mountp; 199 struct xfs_btree_cur *cur; 200 xfs_agblock_t fbno; 201 xfs_extlen_t flen; 202 int error; 203 204 *stat = false; 205 if (!xfs_sb_version_hasreflink(&mp->m_sb)) 206 return 0; 207 /* rt files will have no perag structure */ 208 if (!info->pag) 209 return 0; 210 211 /* Are there any shared blocks here? */ 212 flen = 0; 213 cur = xfs_refcountbt_init_cursor(mp, tp, info->agf_bp, info->pag); 214 215 error = xfs_refcount_find_shared(cur, rec->rm_startblock, 216 rec->rm_blockcount, &fbno, &flen, false); 217 218 xfs_btree_del_cursor(cur, error); 219 if (error) 220 return error; 221 222 *stat = flen > 0; 223 return 0; 224 } 225 226 static inline void 227 xfs_getfsmap_format( 228 struct xfs_mount *mp, 229 struct xfs_fsmap *xfm, 230 struct xfs_getfsmap_info *info) 231 { 232 struct fsmap *rec; 233 234 trace_xfs_getfsmap_mapping(mp, xfm); 235 236 rec = &info->fsmap_recs[info->head->fmh_entries++]; 237 xfs_fsmap_from_internal(rec, xfm); 238 } 239 240 /* 241 * Format a reverse mapping for getfsmap, having translated rm_startblock 242 * into the appropriate daddr units. 243 */ 244 STATIC int 245 xfs_getfsmap_helper( 246 struct xfs_trans *tp, 247 struct xfs_getfsmap_info *info, 248 struct xfs_rmap_irec *rec, 249 xfs_daddr_t rec_daddr) 250 { 251 struct xfs_fsmap fmr; 252 struct xfs_mount *mp = tp->t_mountp; 253 bool shared; 254 int error; 255 256 if (fatal_signal_pending(current)) 257 return -EINTR; 258 259 /* 260 * Filter out records that start before our startpoint, if the 261 * caller requested that. 262 */ 263 if (xfs_rmap_compare(rec, &info->low) < 0) { 264 rec_daddr += XFS_FSB_TO_BB(mp, rec->rm_blockcount); 265 if (info->next_daddr < rec_daddr) 266 info->next_daddr = rec_daddr; 267 return 0; 268 } 269 270 /* Are we just counting mappings? */ 271 if (info->head->fmh_count == 0) { 272 if (info->head->fmh_entries == UINT_MAX) 273 return -ECANCELED; 274 275 if (rec_daddr > info->next_daddr) 276 info->head->fmh_entries++; 277 278 if (info->last) 279 return 0; 280 281 info->head->fmh_entries++; 282 283 rec_daddr += XFS_FSB_TO_BB(mp, rec->rm_blockcount); 284 if (info->next_daddr < rec_daddr) 285 info->next_daddr = rec_daddr; 286 return 0; 287 } 288 289 /* 290 * If the record starts past the last physical block we saw, 291 * then we've found a gap. Report the gap as being owned by 292 * whatever the caller specified is the missing owner. 293 */ 294 if (rec_daddr > info->next_daddr) { 295 if (info->head->fmh_entries >= info->head->fmh_count) 296 return -ECANCELED; 297 298 fmr.fmr_device = info->dev; 299 fmr.fmr_physical = info->next_daddr; 300 fmr.fmr_owner = info->missing_owner; 301 fmr.fmr_offset = 0; 302 fmr.fmr_length = rec_daddr - info->next_daddr; 303 fmr.fmr_flags = FMR_OF_SPECIAL_OWNER; 304 xfs_getfsmap_format(mp, &fmr, info); 305 } 306 307 if (info->last) 308 goto out; 309 310 /* Fill out the extent we found */ 311 if (info->head->fmh_entries >= info->head->fmh_count) 312 return -ECANCELED; 313 314 trace_xfs_fsmap_mapping(mp, info->dev, 315 info->pag ? info->pag->pag_agno : NULLAGNUMBER, rec); 316 317 fmr.fmr_device = info->dev; 318 fmr.fmr_physical = rec_daddr; 319 error = xfs_fsmap_owner_from_rmap(&fmr, rec); 320 if (error) 321 return error; 322 fmr.fmr_offset = XFS_FSB_TO_BB(mp, rec->rm_offset); 323 fmr.fmr_length = XFS_FSB_TO_BB(mp, rec->rm_blockcount); 324 if (rec->rm_flags & XFS_RMAP_UNWRITTEN) 325 fmr.fmr_flags |= FMR_OF_PREALLOC; 326 if (rec->rm_flags & XFS_RMAP_ATTR_FORK) 327 fmr.fmr_flags |= FMR_OF_ATTR_FORK; 328 if (rec->rm_flags & XFS_RMAP_BMBT_BLOCK) 329 fmr.fmr_flags |= FMR_OF_EXTENT_MAP; 330 if (fmr.fmr_flags == 0) { 331 error = xfs_getfsmap_is_shared(tp, info, rec, &shared); 332 if (error) 333 return error; 334 if (shared) 335 fmr.fmr_flags |= FMR_OF_SHARED; 336 } 337 338 xfs_getfsmap_format(mp, &fmr, info); 339 out: 340 rec_daddr += XFS_FSB_TO_BB(mp, rec->rm_blockcount); 341 if (info->next_daddr < rec_daddr) 342 info->next_daddr = rec_daddr; 343 return 0; 344 } 345 346 /* Transform a rmapbt irec into a fsmap */ 347 STATIC int 348 xfs_getfsmap_datadev_helper( 349 struct xfs_btree_cur *cur, 350 struct xfs_rmap_irec *rec, 351 void *priv) 352 { 353 struct xfs_mount *mp = cur->bc_mp; 354 struct xfs_getfsmap_info *info = priv; 355 xfs_fsblock_t fsb; 356 xfs_daddr_t rec_daddr; 357 358 fsb = XFS_AGB_TO_FSB(mp, cur->bc_ag.pag->pag_agno, rec->rm_startblock); 359 rec_daddr = XFS_FSB_TO_DADDR(mp, fsb); 360 361 return xfs_getfsmap_helper(cur->bc_tp, info, rec, rec_daddr); 362 } 363 364 /* Transform a bnobt irec into a fsmap */ 365 STATIC int 366 xfs_getfsmap_datadev_bnobt_helper( 367 struct xfs_btree_cur *cur, 368 struct xfs_alloc_rec_incore *rec, 369 void *priv) 370 { 371 struct xfs_mount *mp = cur->bc_mp; 372 struct xfs_getfsmap_info *info = priv; 373 struct xfs_rmap_irec irec; 374 xfs_daddr_t rec_daddr; 375 376 rec_daddr = XFS_AGB_TO_DADDR(mp, cur->bc_ag.pag->pag_agno, 377 rec->ar_startblock); 378 379 irec.rm_startblock = rec->ar_startblock; 380 irec.rm_blockcount = rec->ar_blockcount; 381 irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ 382 irec.rm_offset = 0; 383 irec.rm_flags = 0; 384 385 return xfs_getfsmap_helper(cur->bc_tp, info, &irec, rec_daddr); 386 } 387 388 /* Set rmap flags based on the getfsmap flags */ 389 static void 390 xfs_getfsmap_set_irec_flags( 391 struct xfs_rmap_irec *irec, 392 struct xfs_fsmap *fmr) 393 { 394 irec->rm_flags = 0; 395 if (fmr->fmr_flags & FMR_OF_ATTR_FORK) 396 irec->rm_flags |= XFS_RMAP_ATTR_FORK; 397 if (fmr->fmr_flags & FMR_OF_EXTENT_MAP) 398 irec->rm_flags |= XFS_RMAP_BMBT_BLOCK; 399 if (fmr->fmr_flags & FMR_OF_PREALLOC) 400 irec->rm_flags |= XFS_RMAP_UNWRITTEN; 401 } 402 403 /* Execute a getfsmap query against the log device. */ 404 STATIC int 405 xfs_getfsmap_logdev( 406 struct xfs_trans *tp, 407 struct xfs_fsmap *keys, 408 struct xfs_getfsmap_info *info) 409 { 410 struct xfs_mount *mp = tp->t_mountp; 411 struct xfs_rmap_irec rmap; 412 int error; 413 414 /* Set up search keys */ 415 info->low.rm_startblock = XFS_BB_TO_FSBT(mp, keys[0].fmr_physical); 416 info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); 417 error = xfs_fsmap_owner_to_rmap(&info->low, keys); 418 if (error) 419 return error; 420 info->low.rm_blockcount = 0; 421 xfs_getfsmap_set_irec_flags(&info->low, &keys[0]); 422 423 error = xfs_fsmap_owner_to_rmap(&info->high, keys + 1); 424 if (error) 425 return error; 426 info->high.rm_startblock = -1U; 427 info->high.rm_owner = ULLONG_MAX; 428 info->high.rm_offset = ULLONG_MAX; 429 info->high.rm_blockcount = 0; 430 info->high.rm_flags = XFS_RMAP_KEY_FLAGS | XFS_RMAP_REC_FLAGS; 431 info->missing_owner = XFS_FMR_OWN_FREE; 432 433 trace_xfs_fsmap_low_key(mp, info->dev, NULLAGNUMBER, &info->low); 434 trace_xfs_fsmap_high_key(mp, info->dev, NULLAGNUMBER, &info->high); 435 436 if (keys[0].fmr_physical > 0) 437 return 0; 438 439 /* Fabricate an rmap entry for the external log device. */ 440 rmap.rm_startblock = 0; 441 rmap.rm_blockcount = mp->m_sb.sb_logblocks; 442 rmap.rm_owner = XFS_RMAP_OWN_LOG; 443 rmap.rm_offset = 0; 444 rmap.rm_flags = 0; 445 446 return xfs_getfsmap_helper(tp, info, &rmap, 0); 447 } 448 449 #ifdef CONFIG_XFS_RT 450 /* Transform a rtbitmap "record" into a fsmap */ 451 STATIC int 452 xfs_getfsmap_rtdev_rtbitmap_helper( 453 struct xfs_trans *tp, 454 struct xfs_rtalloc_rec *rec, 455 void *priv) 456 { 457 struct xfs_mount *mp = tp->t_mountp; 458 struct xfs_getfsmap_info *info = priv; 459 struct xfs_rmap_irec irec; 460 xfs_daddr_t rec_daddr; 461 462 irec.rm_startblock = rec->ar_startext * mp->m_sb.sb_rextsize; 463 rec_daddr = XFS_FSB_TO_BB(mp, irec.rm_startblock); 464 irec.rm_blockcount = rec->ar_extcount * mp->m_sb.sb_rextsize; 465 irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ 466 irec.rm_offset = 0; 467 irec.rm_flags = 0; 468 469 return xfs_getfsmap_helper(tp, info, &irec, rec_daddr); 470 } 471 472 /* Execute a getfsmap query against the realtime device. */ 473 STATIC int 474 __xfs_getfsmap_rtdev( 475 struct xfs_trans *tp, 476 struct xfs_fsmap *keys, 477 int (*query_fn)(struct xfs_trans *, 478 struct xfs_getfsmap_info *), 479 struct xfs_getfsmap_info *info) 480 { 481 struct xfs_mount *mp = tp->t_mountp; 482 xfs_fsblock_t start_fsb; 483 xfs_fsblock_t end_fsb; 484 xfs_daddr_t eofs; 485 int error = 0; 486 487 eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks); 488 if (keys[0].fmr_physical >= eofs) 489 return 0; 490 if (keys[1].fmr_physical >= eofs) 491 keys[1].fmr_physical = eofs - 1; 492 start_fsb = XFS_BB_TO_FSBT(mp, keys[0].fmr_physical); 493 end_fsb = XFS_BB_TO_FSB(mp, keys[1].fmr_physical); 494 495 /* Set up search keys */ 496 info->low.rm_startblock = start_fsb; 497 error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); 498 if (error) 499 return error; 500 info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); 501 info->low.rm_blockcount = 0; 502 xfs_getfsmap_set_irec_flags(&info->low, &keys[0]); 503 504 info->high.rm_startblock = end_fsb; 505 error = xfs_fsmap_owner_to_rmap(&info->high, &keys[1]); 506 if (error) 507 return error; 508 info->high.rm_offset = XFS_BB_TO_FSBT(mp, keys[1].fmr_offset); 509 info->high.rm_blockcount = 0; 510 xfs_getfsmap_set_irec_flags(&info->high, &keys[1]); 511 512 trace_xfs_fsmap_low_key(mp, info->dev, NULLAGNUMBER, &info->low); 513 trace_xfs_fsmap_high_key(mp, info->dev, NULLAGNUMBER, &info->high); 514 515 return query_fn(tp, info); 516 } 517 518 /* Actually query the realtime bitmap. */ 519 STATIC int 520 xfs_getfsmap_rtdev_rtbitmap_query( 521 struct xfs_trans *tp, 522 struct xfs_getfsmap_info *info) 523 { 524 struct xfs_rtalloc_rec alow = { 0 }; 525 struct xfs_rtalloc_rec ahigh = { 0 }; 526 int error; 527 528 xfs_ilock(tp->t_mountp->m_rbmip, XFS_ILOCK_SHARED); 529 530 alow.ar_startext = info->low.rm_startblock; 531 ahigh.ar_startext = info->high.rm_startblock; 532 do_div(alow.ar_startext, tp->t_mountp->m_sb.sb_rextsize); 533 if (do_div(ahigh.ar_startext, tp->t_mountp->m_sb.sb_rextsize)) 534 ahigh.ar_startext++; 535 error = xfs_rtalloc_query_range(tp, &alow, &ahigh, 536 xfs_getfsmap_rtdev_rtbitmap_helper, info); 537 if (error) 538 goto err; 539 540 /* Report any gaps at the end of the rtbitmap */ 541 info->last = true; 542 error = xfs_getfsmap_rtdev_rtbitmap_helper(tp, &ahigh, info); 543 if (error) 544 goto err; 545 err: 546 xfs_iunlock(tp->t_mountp->m_rbmip, XFS_ILOCK_SHARED); 547 return error; 548 } 549 550 /* Execute a getfsmap query against the realtime device rtbitmap. */ 551 STATIC int 552 xfs_getfsmap_rtdev_rtbitmap( 553 struct xfs_trans *tp, 554 struct xfs_fsmap *keys, 555 struct xfs_getfsmap_info *info) 556 { 557 info->missing_owner = XFS_FMR_OWN_UNKNOWN; 558 return __xfs_getfsmap_rtdev(tp, keys, xfs_getfsmap_rtdev_rtbitmap_query, 559 info); 560 } 561 #endif /* CONFIG_XFS_RT */ 562 563 /* Execute a getfsmap query against the regular data device. */ 564 STATIC int 565 __xfs_getfsmap_datadev( 566 struct xfs_trans *tp, 567 struct xfs_fsmap *keys, 568 struct xfs_getfsmap_info *info, 569 int (*query_fn)(struct xfs_trans *, 570 struct xfs_getfsmap_info *, 571 struct xfs_btree_cur **, 572 void *), 573 void *priv) 574 { 575 struct xfs_mount *mp = tp->t_mountp; 576 struct xfs_perag *pag; 577 struct xfs_btree_cur *bt_cur = NULL; 578 xfs_fsblock_t start_fsb; 579 xfs_fsblock_t end_fsb; 580 xfs_agnumber_t start_ag; 581 xfs_agnumber_t end_ag; 582 xfs_daddr_t eofs; 583 int error = 0; 584 585 eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); 586 if (keys[0].fmr_physical >= eofs) 587 return 0; 588 if (keys[1].fmr_physical >= eofs) 589 keys[1].fmr_physical = eofs - 1; 590 start_fsb = XFS_DADDR_TO_FSB(mp, keys[0].fmr_physical); 591 end_fsb = XFS_DADDR_TO_FSB(mp, keys[1].fmr_physical); 592 593 /* 594 * Convert the fsmap low/high keys to AG based keys. Initialize 595 * low to the fsmap low key and max out the high key to the end 596 * of the AG. 597 */ 598 info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb); 599 info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); 600 error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); 601 if (error) 602 return error; 603 info->low.rm_blockcount = 0; 604 xfs_getfsmap_set_irec_flags(&info->low, &keys[0]); 605 606 info->high.rm_startblock = -1U; 607 info->high.rm_owner = ULLONG_MAX; 608 info->high.rm_offset = ULLONG_MAX; 609 info->high.rm_blockcount = 0; 610 info->high.rm_flags = XFS_RMAP_KEY_FLAGS | XFS_RMAP_REC_FLAGS; 611 612 start_ag = XFS_FSB_TO_AGNO(mp, start_fsb); 613 end_ag = XFS_FSB_TO_AGNO(mp, end_fsb); 614 615 for_each_perag_range(mp, start_ag, end_ag, pag) { 616 /* 617 * Set the AG high key from the fsmap high key if this 618 * is the last AG that we're querying. 619 */ 620 info->pag = pag; 621 if (pag->pag_agno == end_ag) { 622 info->high.rm_startblock = XFS_FSB_TO_AGBNO(mp, 623 end_fsb); 624 info->high.rm_offset = XFS_BB_TO_FSBT(mp, 625 keys[1].fmr_offset); 626 error = xfs_fsmap_owner_to_rmap(&info->high, &keys[1]); 627 if (error) 628 break; 629 xfs_getfsmap_set_irec_flags(&info->high, &keys[1]); 630 } 631 632 if (bt_cur) { 633 xfs_btree_del_cursor(bt_cur, XFS_BTREE_NOERROR); 634 bt_cur = NULL; 635 xfs_trans_brelse(tp, info->agf_bp); 636 info->agf_bp = NULL; 637 } 638 639 error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, 640 &info->agf_bp); 641 if (error) 642 break; 643 644 trace_xfs_fsmap_low_key(mp, info->dev, pag->pag_agno, 645 &info->low); 646 trace_xfs_fsmap_high_key(mp, info->dev, pag->pag_agno, 647 &info->high); 648 649 error = query_fn(tp, info, &bt_cur, priv); 650 if (error) 651 break; 652 653 /* 654 * Set the AG low key to the start of the AG prior to 655 * moving on to the next AG. 656 */ 657 if (pag->pag_agno == start_ag) { 658 info->low.rm_startblock = 0; 659 info->low.rm_owner = 0; 660 info->low.rm_offset = 0; 661 info->low.rm_flags = 0; 662 } 663 664 /* 665 * If this is the last AG, report any gap at the end of it 666 * before we drop the reference to the perag when the loop 667 * terminates. 668 */ 669 if (pag->pag_agno == end_ag) { 670 info->last = true; 671 error = query_fn(tp, info, &bt_cur, priv); 672 if (error) 673 break; 674 } 675 info->pag = NULL; 676 } 677 678 if (bt_cur) 679 xfs_btree_del_cursor(bt_cur, error < 0 ? XFS_BTREE_ERROR : 680 XFS_BTREE_NOERROR); 681 if (info->agf_bp) { 682 xfs_trans_brelse(tp, info->agf_bp); 683 info->agf_bp = NULL; 684 } 685 if (info->pag) { 686 xfs_perag_put(info->pag); 687 info->pag = NULL; 688 } else if (pag) { 689 /* loop termination case */ 690 xfs_perag_put(pag); 691 } 692 693 return error; 694 } 695 696 /* Actually query the rmap btree. */ 697 STATIC int 698 xfs_getfsmap_datadev_rmapbt_query( 699 struct xfs_trans *tp, 700 struct xfs_getfsmap_info *info, 701 struct xfs_btree_cur **curpp, 702 void *priv) 703 { 704 /* Report any gap at the end of the last AG. */ 705 if (info->last) 706 return xfs_getfsmap_datadev_helper(*curpp, &info->high, info); 707 708 /* Allocate cursor for this AG and query_range it. */ 709 *curpp = xfs_rmapbt_init_cursor(tp->t_mountp, tp, info->agf_bp, 710 info->pag); 711 return xfs_rmap_query_range(*curpp, &info->low, &info->high, 712 xfs_getfsmap_datadev_helper, info); 713 } 714 715 /* Execute a getfsmap query against the regular data device rmapbt. */ 716 STATIC int 717 xfs_getfsmap_datadev_rmapbt( 718 struct xfs_trans *tp, 719 struct xfs_fsmap *keys, 720 struct xfs_getfsmap_info *info) 721 { 722 info->missing_owner = XFS_FMR_OWN_FREE; 723 return __xfs_getfsmap_datadev(tp, keys, info, 724 xfs_getfsmap_datadev_rmapbt_query, NULL); 725 } 726 727 /* Actually query the bno btree. */ 728 STATIC int 729 xfs_getfsmap_datadev_bnobt_query( 730 struct xfs_trans *tp, 731 struct xfs_getfsmap_info *info, 732 struct xfs_btree_cur **curpp, 733 void *priv) 734 { 735 struct xfs_alloc_rec_incore *key = priv; 736 737 /* Report any gap at the end of the last AG. */ 738 if (info->last) 739 return xfs_getfsmap_datadev_bnobt_helper(*curpp, &key[1], info); 740 741 /* Allocate cursor for this AG and query_range it. */ 742 *curpp = xfs_allocbt_init_cursor(tp->t_mountp, tp, info->agf_bp, 743 info->pag, XFS_BTNUM_BNO); 744 key->ar_startblock = info->low.rm_startblock; 745 key[1].ar_startblock = info->high.rm_startblock; 746 return xfs_alloc_query_range(*curpp, key, &key[1], 747 xfs_getfsmap_datadev_bnobt_helper, info); 748 } 749 750 /* Execute a getfsmap query against the regular data device's bnobt. */ 751 STATIC int 752 xfs_getfsmap_datadev_bnobt( 753 struct xfs_trans *tp, 754 struct xfs_fsmap *keys, 755 struct xfs_getfsmap_info *info) 756 { 757 struct xfs_alloc_rec_incore akeys[2]; 758 759 info->missing_owner = XFS_FMR_OWN_UNKNOWN; 760 return __xfs_getfsmap_datadev(tp, keys, info, 761 xfs_getfsmap_datadev_bnobt_query, &akeys[0]); 762 } 763 764 /* Do we recognize the device? */ 765 STATIC bool 766 xfs_getfsmap_is_valid_device( 767 struct xfs_mount *mp, 768 struct xfs_fsmap *fm) 769 { 770 if (fm->fmr_device == 0 || fm->fmr_device == UINT_MAX || 771 fm->fmr_device == new_encode_dev(mp->m_ddev_targp->bt_dev)) 772 return true; 773 if (mp->m_logdev_targp && 774 fm->fmr_device == new_encode_dev(mp->m_logdev_targp->bt_dev)) 775 return true; 776 if (mp->m_rtdev_targp && 777 fm->fmr_device == new_encode_dev(mp->m_rtdev_targp->bt_dev)) 778 return true; 779 return false; 780 } 781 782 /* Ensure that the low key is less than the high key. */ 783 STATIC bool 784 xfs_getfsmap_check_keys( 785 struct xfs_fsmap *low_key, 786 struct xfs_fsmap *high_key) 787 { 788 if (low_key->fmr_device > high_key->fmr_device) 789 return false; 790 if (low_key->fmr_device < high_key->fmr_device) 791 return true; 792 793 if (low_key->fmr_physical > high_key->fmr_physical) 794 return false; 795 if (low_key->fmr_physical < high_key->fmr_physical) 796 return true; 797 798 if (low_key->fmr_owner > high_key->fmr_owner) 799 return false; 800 if (low_key->fmr_owner < high_key->fmr_owner) 801 return true; 802 803 if (low_key->fmr_offset > high_key->fmr_offset) 804 return false; 805 if (low_key->fmr_offset < high_key->fmr_offset) 806 return true; 807 808 return false; 809 } 810 811 /* 812 * There are only two devices if we didn't configure RT devices at build time. 813 */ 814 #ifdef CONFIG_XFS_RT 815 #define XFS_GETFSMAP_DEVS 3 816 #else 817 #define XFS_GETFSMAP_DEVS 2 818 #endif /* CONFIG_XFS_RT */ 819 820 /* 821 * Get filesystem's extents as described in head, and format for output. Fills 822 * in the supplied records array until there are no more reverse mappings to 823 * return or head.fmh_entries == head.fmh_count. In the second case, this 824 * function returns -ECANCELED to indicate that more records would have been 825 * returned. 826 * 827 * Key to Confusion 828 * ---------------- 829 * There are multiple levels of keys and counters at work here: 830 * xfs_fsmap_head.fmh_keys -- low and high fsmap keys passed in; 831 * these reflect fs-wide sector addrs. 832 * dkeys -- fmh_keys used to query each device; 833 * these are fmh_keys but w/ the low key 834 * bumped up by fmr_length. 835 * xfs_getfsmap_info.next_daddr -- next disk addr we expect to see; this 836 * is how we detect gaps in the fsmap 837 records and report them. 838 * xfs_getfsmap_info.low/high -- per-AG low/high keys computed from 839 * dkeys; used to query the metadata. 840 */ 841 int 842 xfs_getfsmap( 843 struct xfs_mount *mp, 844 struct xfs_fsmap_head *head, 845 struct fsmap *fsmap_recs) 846 { 847 struct xfs_trans *tp = NULL; 848 struct xfs_fsmap dkeys[2]; /* per-dev keys */ 849 struct xfs_getfsmap_dev handlers[XFS_GETFSMAP_DEVS]; 850 struct xfs_getfsmap_info info = { NULL }; 851 bool use_rmap; 852 int i; 853 int error = 0; 854 855 if (head->fmh_iflags & ~FMH_IF_VALID) 856 return -EINVAL; 857 if (!xfs_getfsmap_is_valid_device(mp, &head->fmh_keys[0]) || 858 !xfs_getfsmap_is_valid_device(mp, &head->fmh_keys[1])) 859 return -EINVAL; 860 861 use_rmap = capable(CAP_SYS_ADMIN) && 862 xfs_sb_version_hasrmapbt(&mp->m_sb); 863 head->fmh_entries = 0; 864 865 /* Set up our device handlers. */ 866 memset(handlers, 0, sizeof(handlers)); 867 handlers[0].dev = new_encode_dev(mp->m_ddev_targp->bt_dev); 868 if (use_rmap) 869 handlers[0].fn = xfs_getfsmap_datadev_rmapbt; 870 else 871 handlers[0].fn = xfs_getfsmap_datadev_bnobt; 872 if (mp->m_logdev_targp != mp->m_ddev_targp) { 873 handlers[1].dev = new_encode_dev(mp->m_logdev_targp->bt_dev); 874 handlers[1].fn = xfs_getfsmap_logdev; 875 } 876 #ifdef CONFIG_XFS_RT 877 if (mp->m_rtdev_targp) { 878 handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev); 879 handlers[2].fn = xfs_getfsmap_rtdev_rtbitmap; 880 } 881 #endif /* CONFIG_XFS_RT */ 882 883 xfs_sort(handlers, XFS_GETFSMAP_DEVS, sizeof(struct xfs_getfsmap_dev), 884 xfs_getfsmap_dev_compare); 885 886 /* 887 * To continue where we left off, we allow userspace to use the 888 * last mapping from a previous call as the low key of the next. 889 * This is identified by a non-zero length in the low key. We 890 * have to increment the low key in this scenario to ensure we 891 * don't return the same mapping again, and instead return the 892 * very next mapping. 893 * 894 * If the low key mapping refers to file data, the same physical 895 * blocks could be mapped to several other files/offsets. 896 * According to rmapbt record ordering, the minimal next 897 * possible record for the block range is the next starting 898 * offset in the same inode. Therefore, bump the file offset to 899 * continue the search appropriately. For all other low key 900 * mapping types (attr blocks, metadata), bump the physical 901 * offset as there can be no other mapping for the same physical 902 * block range. 903 */ 904 dkeys[0] = head->fmh_keys[0]; 905 if (dkeys[0].fmr_flags & (FMR_OF_SPECIAL_OWNER | FMR_OF_EXTENT_MAP)) { 906 dkeys[0].fmr_physical += dkeys[0].fmr_length; 907 dkeys[0].fmr_owner = 0; 908 if (dkeys[0].fmr_offset) 909 return -EINVAL; 910 } else 911 dkeys[0].fmr_offset += dkeys[0].fmr_length; 912 dkeys[0].fmr_length = 0; 913 memset(&dkeys[1], 0xFF, sizeof(struct xfs_fsmap)); 914 915 if (!xfs_getfsmap_check_keys(dkeys, &head->fmh_keys[1])) 916 return -EINVAL; 917 918 info.next_daddr = head->fmh_keys[0].fmr_physical + 919 head->fmh_keys[0].fmr_length; 920 info.fsmap_recs = fsmap_recs; 921 info.head = head; 922 923 /* For each device we support... */ 924 for (i = 0; i < XFS_GETFSMAP_DEVS; i++) { 925 /* Is this device within the range the user asked for? */ 926 if (!handlers[i].fn) 927 continue; 928 if (head->fmh_keys[0].fmr_device > handlers[i].dev) 929 continue; 930 if (head->fmh_keys[1].fmr_device < handlers[i].dev) 931 break; 932 933 /* 934 * If this device number matches the high key, we have 935 * to pass the high key to the handler to limit the 936 * query results. If the device number exceeds the 937 * low key, zero out the low key so that we get 938 * everything from the beginning. 939 */ 940 if (handlers[i].dev == head->fmh_keys[1].fmr_device) 941 dkeys[1] = head->fmh_keys[1]; 942 if (handlers[i].dev > head->fmh_keys[0].fmr_device) 943 memset(&dkeys[0], 0, sizeof(struct xfs_fsmap)); 944 945 /* 946 * Grab an empty transaction so that we can use its recursive 947 * buffer locking abilities to detect cycles in the rmapbt 948 * without deadlocking. 949 */ 950 error = xfs_trans_alloc_empty(mp, &tp); 951 if (error) 952 break; 953 954 info.dev = handlers[i].dev; 955 info.last = false; 956 info.pag = NULL; 957 error = handlers[i].fn(tp, dkeys, &info); 958 if (error) 959 break; 960 xfs_trans_cancel(tp); 961 tp = NULL; 962 info.next_daddr = 0; 963 } 964 965 if (tp) 966 xfs_trans_cancel(tp); 967 head->fmh_oflags = FMH_OF_DEV_T; 968 return error; 969 } 970