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