| .. | .. |
|---|
| 12 | 12 | #include "xfs_bit.h" |
|---|
| 13 | 13 | #include "xfs_sb.h" |
|---|
| 14 | 14 | #include "xfs_mount.h" |
|---|
| 15 | | -#include "xfs_defer.h" |
|---|
| 16 | 15 | #include "xfs_inode.h" |
|---|
| 17 | 16 | #include "xfs_btree.h" |
|---|
| 18 | 17 | #include "xfs_ialloc.h" |
|---|
| 19 | 18 | #include "xfs_ialloc_btree.h" |
|---|
| 20 | 19 | #include "xfs_alloc.h" |
|---|
| 21 | | -#include "xfs_rtalloc.h" |
|---|
| 22 | 20 | #include "xfs_errortag.h" |
|---|
| 23 | 21 | #include "xfs_error.h" |
|---|
| 24 | 22 | #include "xfs_bmap.h" |
|---|
| 25 | | -#include "xfs_cksum.h" |
|---|
| 26 | 23 | #include "xfs_trans.h" |
|---|
| 27 | 24 | #include "xfs_buf_item.h" |
|---|
| 28 | 25 | #include "xfs_icreate_item.h" |
|---|
| .. | .. |
|---|
| 30 | 27 | #include "xfs_trace.h" |
|---|
| 31 | 28 | #include "xfs_log.h" |
|---|
| 32 | 29 | #include "xfs_rmap.h" |
|---|
| 33 | | - |
|---|
| 34 | | - |
|---|
| 35 | | -/* |
|---|
| 36 | | - * Allocation group level functions. |
|---|
| 37 | | - */ |
|---|
| 38 | | -int |
|---|
| 39 | | -xfs_ialloc_cluster_alignment( |
|---|
| 40 | | - struct xfs_mount *mp) |
|---|
| 41 | | -{ |
|---|
| 42 | | - if (xfs_sb_version_hasalign(&mp->m_sb) && |
|---|
| 43 | | - mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp)) |
|---|
| 44 | | - return mp->m_sb.sb_inoalignmt; |
|---|
| 45 | | - return 1; |
|---|
| 46 | | -} |
|---|
| 47 | 30 | |
|---|
| 48 | 31 | /* |
|---|
| 49 | 32 | * Lookup a record by ino in the btree given by cur. |
|---|
| .. | .. |
|---|
| 122 | 105 | int *stat) |
|---|
| 123 | 106 | { |
|---|
| 124 | 107 | struct xfs_mount *mp = cur->bc_mp; |
|---|
| 125 | | - xfs_agnumber_t agno = cur->bc_private.a.agno; |
|---|
| 108 | + xfs_agnumber_t agno = cur->bc_ag.agno; |
|---|
| 126 | 109 | union xfs_btree_rec *rec; |
|---|
| 127 | 110 | int error; |
|---|
| 128 | 111 | uint64_t realfree; |
|---|
| .. | .. |
|---|
| 194 | 177 | xfs_btnum_t btnum) |
|---|
| 195 | 178 | { |
|---|
| 196 | 179 | struct xfs_btree_cur *cur; |
|---|
| 197 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
|---|
| 180 | + struct xfs_agi *agi = agbp->b_addr; |
|---|
| 198 | 181 | xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); |
|---|
| 199 | 182 | xfs_agino_t thisino; |
|---|
| 200 | 183 | int i; |
|---|
| .. | .. |
|---|
| 288 | 271 | { |
|---|
| 289 | 272 | struct xfs_buf *fbuf; |
|---|
| 290 | 273 | struct xfs_dinode *free; |
|---|
| 291 | | - int nbufs, blks_per_cluster, inodes_per_cluster; |
|---|
| 274 | + int nbufs; |
|---|
| 292 | 275 | int version; |
|---|
| 293 | 276 | int i, j; |
|---|
| 294 | 277 | xfs_daddr_t d; |
|---|
| 295 | 278 | xfs_ino_t ino = 0; |
|---|
| 279 | + int error; |
|---|
| 296 | 280 | |
|---|
| 297 | 281 | /* |
|---|
| 298 | 282 | * Loop over the new block(s), filling in the inodes. For small block |
|---|
| 299 | 283 | * sizes, manipulate the inodes in buffers which are multiples of the |
|---|
| 300 | 284 | * blocks size. |
|---|
| 301 | 285 | */ |
|---|
| 302 | | - blks_per_cluster = xfs_icluster_size_fsb(mp); |
|---|
| 303 | | - inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog; |
|---|
| 304 | | - nbufs = length / blks_per_cluster; |
|---|
| 286 | + nbufs = length / M_IGEO(mp)->blocks_per_cluster; |
|---|
| 305 | 287 | |
|---|
| 306 | 288 | /* |
|---|
| 307 | 289 | * Figure out what version number to use in the inodes we create. If |
|---|
| .. | .. |
|---|
| 312 | 294 | * |
|---|
| 313 | 295 | * For v3 inodes, we also need to write the inode number into the inode, |
|---|
| 314 | 296 | * so calculate the first inode number of the chunk here as |
|---|
| 315 | | - * XFS_OFFBNO_TO_AGINO() only works within a filesystem block, not |
|---|
| 297 | + * XFS_AGB_TO_AGINO() only works within a filesystem block, not |
|---|
| 316 | 298 | * across multiple filesystem blocks (such as a cluster) and so cannot |
|---|
| 317 | 299 | * be used in the cluster buffer loop below. |
|---|
| 318 | 300 | * |
|---|
| .. | .. |
|---|
| 322 | 304 | * That means for v3 inode we log the entire buffer rather than just the |
|---|
| 323 | 305 | * inode cores. |
|---|
| 324 | 306 | */ |
|---|
| 325 | | - if (xfs_sb_version_hascrc(&mp->m_sb)) { |
|---|
| 307 | + if (xfs_sb_version_has_v3inode(&mp->m_sb)) { |
|---|
| 326 | 308 | version = 3; |
|---|
| 327 | | - ino = XFS_AGINO_TO_INO(mp, agno, |
|---|
| 328 | | - XFS_OFFBNO_TO_AGINO(mp, agbno, 0)); |
|---|
| 309 | + ino = XFS_AGINO_TO_INO(mp, agno, XFS_AGB_TO_AGINO(mp, agbno)); |
|---|
| 329 | 310 | |
|---|
| 330 | 311 | /* |
|---|
| 331 | 312 | * log the initialisation that is about to take place as an |
|---|
| .. | .. |
|---|
| 345 | 326 | /* |
|---|
| 346 | 327 | * Get the block. |
|---|
| 347 | 328 | */ |
|---|
| 348 | | - d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster)); |
|---|
| 349 | | - fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, |
|---|
| 350 | | - mp->m_bsize * blks_per_cluster, |
|---|
| 351 | | - XBF_UNMAPPED); |
|---|
| 352 | | - if (!fbuf) |
|---|
| 353 | | - return -ENOMEM; |
|---|
| 329 | + d = XFS_AGB_TO_DADDR(mp, agno, agbno + |
|---|
| 330 | + (j * M_IGEO(mp)->blocks_per_cluster)); |
|---|
| 331 | + error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, |
|---|
| 332 | + mp->m_bsize * M_IGEO(mp)->blocks_per_cluster, |
|---|
| 333 | + XBF_UNMAPPED, &fbuf); |
|---|
| 334 | + if (error) |
|---|
| 335 | + return error; |
|---|
| 354 | 336 | |
|---|
| 355 | 337 | /* Initialize the inode buffers and log them appropriately. */ |
|---|
| 356 | 338 | fbuf->b_ops = &xfs_inode_buf_ops; |
|---|
| 357 | 339 | xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length)); |
|---|
| 358 | | - for (i = 0; i < inodes_per_cluster; i++) { |
|---|
| 340 | + for (i = 0; i < M_IGEO(mp)->inodes_per_cluster; i++) { |
|---|
| 359 | 341 | int ioffset = i << mp->m_sb.sb_inodelog; |
|---|
| 360 | | - uint isize = xfs_dinode_size(version); |
|---|
| 342 | + uint isize = XFS_DINODE_SIZE(&mp->m_sb); |
|---|
| 361 | 343 | |
|---|
| 362 | 344 | free = xfs_make_iptr(mp, fbuf, i); |
|---|
| 363 | 345 | free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); |
|---|
| .. | .. |
|---|
| 445 | 427 | return; |
|---|
| 446 | 428 | |
|---|
| 447 | 429 | /* calculate the inode offset and align startino */ |
|---|
| 448 | | - offset = mod << mp->m_sb.sb_inopblog; |
|---|
| 430 | + offset = XFS_AGB_TO_AGINO(mp, mod); |
|---|
| 449 | 431 | *startino -= offset; |
|---|
| 450 | 432 | |
|---|
| 451 | 433 | /* |
|---|
| .. | .. |
|---|
| 543 | 525 | bool merge) /* merge or replace */ |
|---|
| 544 | 526 | { |
|---|
| 545 | 527 | struct xfs_btree_cur *cur; |
|---|
| 546 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
|---|
| 528 | + struct xfs_agi *agi = agbp->b_addr; |
|---|
| 547 | 529 | xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); |
|---|
| 548 | 530 | int error; |
|---|
| 549 | 531 | int i; |
|---|
| .. | .. |
|---|
| 562 | 544 | nrec->ir_free, &i); |
|---|
| 563 | 545 | if (error) |
|---|
| 564 | 546 | goto error; |
|---|
| 565 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error); |
|---|
| 547 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 548 | + error = -EFSCORRUPTED; |
|---|
| 549 | + goto error; |
|---|
| 550 | + } |
|---|
| 566 | 551 | |
|---|
| 567 | 552 | goto out; |
|---|
| 568 | 553 | } |
|---|
| .. | .. |
|---|
| 575 | 560 | error = xfs_inobt_get_rec(cur, &rec, &i); |
|---|
| 576 | 561 | if (error) |
|---|
| 577 | 562 | goto error; |
|---|
| 578 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error); |
|---|
| 579 | | - XFS_WANT_CORRUPTED_GOTO(mp, |
|---|
| 580 | | - rec.ir_startino == nrec->ir_startino, |
|---|
| 581 | | - error); |
|---|
| 563 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 564 | + error = -EFSCORRUPTED; |
|---|
| 565 | + goto error; |
|---|
| 566 | + } |
|---|
| 567 | + if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) { |
|---|
| 568 | + error = -EFSCORRUPTED; |
|---|
| 569 | + goto error; |
|---|
| 570 | + } |
|---|
| 582 | 571 | |
|---|
| 583 | 572 | /* |
|---|
| 584 | 573 | * This should never fail. If we have coexisting records that |
|---|
| 585 | 574 | * cannot merge, something is seriously wrong. |
|---|
| 586 | 575 | */ |
|---|
| 587 | | - XFS_WANT_CORRUPTED_GOTO(mp, __xfs_inobt_can_merge(nrec, &rec), |
|---|
| 588 | | - error); |
|---|
| 576 | + if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) { |
|---|
| 577 | + error = -EFSCORRUPTED; |
|---|
| 578 | + goto error; |
|---|
| 579 | + } |
|---|
| 589 | 580 | |
|---|
| 590 | 581 | trace_xfs_irec_merge_pre(mp, agno, rec.ir_startino, |
|---|
| 591 | 582 | rec.ir_holemask, nrec->ir_startino, |
|---|
| .. | .. |
|---|
| 618 | 609 | * Allocate new inodes in the allocation group specified by agbp. |
|---|
| 619 | 610 | * Return 0 for success, else error code. |
|---|
| 620 | 611 | */ |
|---|
| 621 | | -STATIC int /* error code or 0 */ |
|---|
| 612 | +STATIC int |
|---|
| 622 | 613 | xfs_ialloc_ag_alloc( |
|---|
| 623 | | - xfs_trans_t *tp, /* transaction pointer */ |
|---|
| 624 | | - xfs_buf_t *agbp, /* alloc group buffer */ |
|---|
| 625 | | - int *alloc) |
|---|
| 614 | + struct xfs_trans *tp, |
|---|
| 615 | + struct xfs_buf *agbp, |
|---|
| 616 | + int *alloc) |
|---|
| 626 | 617 | { |
|---|
| 627 | | - xfs_agi_t *agi; /* allocation group header */ |
|---|
| 628 | | - xfs_alloc_arg_t args; /* allocation argument structure */ |
|---|
| 629 | | - xfs_agnumber_t agno; |
|---|
| 630 | | - int error; |
|---|
| 631 | | - xfs_agino_t newino; /* new first inode's number */ |
|---|
| 632 | | - xfs_agino_t newlen; /* new number of inodes */ |
|---|
| 633 | | - int isaligned = 0; /* inode allocation at stripe unit */ |
|---|
| 634 | | - /* boundary */ |
|---|
| 635 | | - uint16_t allocmask = (uint16_t) -1; /* init. to full chunk */ |
|---|
| 618 | + struct xfs_agi *agi; |
|---|
| 619 | + struct xfs_alloc_arg args; |
|---|
| 620 | + xfs_agnumber_t agno; |
|---|
| 621 | + int error; |
|---|
| 622 | + xfs_agino_t newino; /* new first inode's number */ |
|---|
| 623 | + xfs_agino_t newlen; /* new number of inodes */ |
|---|
| 624 | + int isaligned = 0; /* inode allocation at stripe */ |
|---|
| 625 | + /* unit boundary */ |
|---|
| 626 | + /* init. to full chunk */ |
|---|
| 627 | + uint16_t allocmask = (uint16_t) -1; |
|---|
| 636 | 628 | struct xfs_inobt_rec_incore rec; |
|---|
| 637 | | - struct xfs_perag *pag; |
|---|
| 638 | | - int do_sparse = 0; |
|---|
| 629 | + struct xfs_perag *pag; |
|---|
| 630 | + struct xfs_ino_geometry *igeo = M_IGEO(tp->t_mountp); |
|---|
| 631 | + int do_sparse = 0; |
|---|
| 639 | 632 | |
|---|
| 640 | 633 | memset(&args, 0, sizeof(args)); |
|---|
| 641 | 634 | args.tp = tp; |
|---|
| 642 | 635 | args.mp = tp->t_mountp; |
|---|
| 643 | 636 | args.fsbno = NULLFSBLOCK; |
|---|
| 644 | | - xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_INODES); |
|---|
| 637 | + args.oinfo = XFS_RMAP_OINFO_INODES; |
|---|
| 645 | 638 | |
|---|
| 646 | 639 | #ifdef DEBUG |
|---|
| 647 | 640 | /* randomly do sparse inode allocations */ |
|---|
| 648 | 641 | if (xfs_sb_version_hassparseinodes(&tp->t_mountp->m_sb) && |
|---|
| 649 | | - args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks) |
|---|
| 642 | + igeo->ialloc_min_blks < igeo->ialloc_blks) |
|---|
| 650 | 643 | do_sparse = prandom_u32() & 1; |
|---|
| 651 | 644 | #endif |
|---|
| 652 | 645 | |
|---|
| .. | .. |
|---|
| 654 | 647 | * Locking will ensure that we don't have two callers in here |
|---|
| 655 | 648 | * at one time. |
|---|
| 656 | 649 | */ |
|---|
| 657 | | - newlen = args.mp->m_ialloc_inos; |
|---|
| 658 | | - if (args.mp->m_maxicount && |
|---|
| 650 | + newlen = igeo->ialloc_inos; |
|---|
| 651 | + if (igeo->maxicount && |
|---|
| 659 | 652 | percpu_counter_read_positive(&args.mp->m_icount) + newlen > |
|---|
| 660 | | - args.mp->m_maxicount) |
|---|
| 653 | + igeo->maxicount) |
|---|
| 661 | 654 | return -ENOSPC; |
|---|
| 662 | | - args.minlen = args.maxlen = args.mp->m_ialloc_blks; |
|---|
| 655 | + args.minlen = args.maxlen = igeo->ialloc_blks; |
|---|
| 663 | 656 | /* |
|---|
| 664 | 657 | * First try to allocate inodes contiguous with the last-allocated |
|---|
| 665 | 658 | * chunk of inodes. If the filesystem is striped, this will fill |
|---|
| 666 | 659 | * an entire stripe unit with inodes. |
|---|
| 667 | 660 | */ |
|---|
| 668 | | - agi = XFS_BUF_TO_AGI(agbp); |
|---|
| 661 | + agi = agbp->b_addr; |
|---|
| 669 | 662 | newino = be32_to_cpu(agi->agi_newino); |
|---|
| 670 | 663 | agno = be32_to_cpu(agi->agi_seqno); |
|---|
| 671 | 664 | args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) + |
|---|
| 672 | | - args.mp->m_ialloc_blks; |
|---|
| 665 | + igeo->ialloc_blks; |
|---|
| 673 | 666 | if (do_sparse) |
|---|
| 674 | 667 | goto sparse_alloc; |
|---|
| 675 | 668 | if (likely(newino != NULLAGINO && |
|---|
| .. | .. |
|---|
| 692 | 685 | * but not to use them in the actual exact allocation. |
|---|
| 693 | 686 | */ |
|---|
| 694 | 687 | args.alignment = 1; |
|---|
| 695 | | - args.minalignslop = xfs_ialloc_cluster_alignment(args.mp) - 1; |
|---|
| 688 | + args.minalignslop = igeo->cluster_align - 1; |
|---|
| 696 | 689 | |
|---|
| 697 | 690 | /* Allow space for the inode btree to split. */ |
|---|
| 698 | | - args.minleft = args.mp->m_in_maxlevels - 1; |
|---|
| 691 | + args.minleft = igeo->inobt_maxlevels; |
|---|
| 699 | 692 | if ((error = xfs_alloc_vextent(&args))) |
|---|
| 700 | 693 | return error; |
|---|
| 701 | 694 | |
|---|
| .. | .. |
|---|
| 722 | 715 | * pieces, so don't need alignment anyway. |
|---|
| 723 | 716 | */ |
|---|
| 724 | 717 | isaligned = 0; |
|---|
| 725 | | - if (args.mp->m_sinoalign) { |
|---|
| 718 | + if (igeo->ialloc_align) { |
|---|
| 726 | 719 | ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); |
|---|
| 727 | 720 | args.alignment = args.mp->m_dalign; |
|---|
| 728 | 721 | isaligned = 1; |
|---|
| 729 | 722 | } else |
|---|
| 730 | | - args.alignment = xfs_ialloc_cluster_alignment(args.mp); |
|---|
| 723 | + args.alignment = igeo->cluster_align; |
|---|
| 731 | 724 | /* |
|---|
| 732 | 725 | * Need to figure out where to allocate the inode blocks. |
|---|
| 733 | 726 | * Ideally they should be spaced out through the a.g. |
|---|
| .. | .. |
|---|
| 743 | 736 | /* |
|---|
| 744 | 737 | * Allow space for the inode btree to split. |
|---|
| 745 | 738 | */ |
|---|
| 746 | | - args.minleft = args.mp->m_in_maxlevels - 1; |
|---|
| 739 | + args.minleft = igeo->inobt_maxlevels; |
|---|
| 747 | 740 | if ((error = xfs_alloc_vextent(&args))) |
|---|
| 748 | 741 | return error; |
|---|
| 749 | 742 | } |
|---|
| .. | .. |
|---|
| 756 | 749 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
|---|
| 757 | 750 | args.agbno = be32_to_cpu(agi->agi_root); |
|---|
| 758 | 751 | args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); |
|---|
| 759 | | - args.alignment = xfs_ialloc_cluster_alignment(args.mp); |
|---|
| 752 | + args.alignment = igeo->cluster_align; |
|---|
| 760 | 753 | if ((error = xfs_alloc_vextent(&args))) |
|---|
| 761 | 754 | return error; |
|---|
| 762 | 755 | } |
|---|
| .. | .. |
|---|
| 766 | 759 | * the sparse allocation length is smaller than a full chunk. |
|---|
| 767 | 760 | */ |
|---|
| 768 | 761 | if (xfs_sb_version_hassparseinodes(&args.mp->m_sb) && |
|---|
| 769 | | - args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks && |
|---|
| 762 | + igeo->ialloc_min_blks < igeo->ialloc_blks && |
|---|
| 770 | 763 | args.fsbno == NULLFSBLOCK) { |
|---|
| 771 | 764 | sparse_alloc: |
|---|
| 772 | 765 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
|---|
| .. | .. |
|---|
| 775 | 768 | args.alignment = args.mp->m_sb.sb_spino_align; |
|---|
| 776 | 769 | args.prod = 1; |
|---|
| 777 | 770 | |
|---|
| 778 | | - args.minlen = args.mp->m_ialloc_min_blks; |
|---|
| 771 | + args.minlen = igeo->ialloc_min_blks; |
|---|
| 779 | 772 | args.maxlen = args.minlen; |
|---|
| 780 | 773 | |
|---|
| 781 | 774 | /* |
|---|
| .. | .. |
|---|
| 791 | 784 | args.min_agbno = args.mp->m_sb.sb_inoalignmt; |
|---|
| 792 | 785 | args.max_agbno = round_down(args.mp->m_sb.sb_agblocks, |
|---|
| 793 | 786 | args.mp->m_sb.sb_inoalignmt) - |
|---|
| 794 | | - args.mp->m_ialloc_blks; |
|---|
| 787 | + igeo->ialloc_blks; |
|---|
| 795 | 788 | |
|---|
| 796 | 789 | error = xfs_alloc_vextent(&args); |
|---|
| 797 | 790 | if (error) |
|---|
| 798 | 791 | return error; |
|---|
| 799 | 792 | |
|---|
| 800 | | - newlen = args.len << args.mp->m_sb.sb_inopblog; |
|---|
| 793 | + newlen = XFS_AGB_TO_AGINO(args.mp, args.len); |
|---|
| 801 | 794 | ASSERT(newlen <= XFS_INODES_PER_CHUNK); |
|---|
| 802 | 795 | allocmask = (1 << (newlen / XFS_INODES_PER_HOLEMASK_BIT)) - 1; |
|---|
| 803 | 796 | } |
|---|
| .. | .. |
|---|
| 825 | 818 | /* |
|---|
| 826 | 819 | * Convert the results. |
|---|
| 827 | 820 | */ |
|---|
| 828 | | - newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0); |
|---|
| 821 | + newino = XFS_AGB_TO_AGINO(args.mp, args.agbno); |
|---|
| 829 | 822 | |
|---|
| 830 | 823 | if (xfs_inobt_issparse(~allocmask)) { |
|---|
| 831 | 824 | /* |
|---|
| .. | .. |
|---|
| 895 | 888 | */ |
|---|
| 896 | 889 | be32_add_cpu(&agi->agi_count, newlen); |
|---|
| 897 | 890 | be32_add_cpu(&agi->agi_freecount, newlen); |
|---|
| 898 | | - pag = xfs_perag_get(args.mp, agno); |
|---|
| 891 | + pag = agbp->b_pag; |
|---|
| 899 | 892 | pag->pagi_freecount += newlen; |
|---|
| 900 | 893 | pag->pagi_count += newlen; |
|---|
| 901 | | - xfs_perag_put(pag); |
|---|
| 902 | 894 | agi->agi_newino = cpu_to_be32(newino); |
|---|
| 903 | 895 | |
|---|
| 904 | 896 | /* |
|---|
| .. | .. |
|---|
| 1008 | 1000 | * space needed for alignment of inode chunks when checking the |
|---|
| 1009 | 1001 | * longest contiguous free space in the AG - this prevents us |
|---|
| 1010 | 1002 | * from getting ENOSPC because we have free space larger than |
|---|
| 1011 | | - * m_ialloc_blks but alignment constraints prevent us from using |
|---|
| 1003 | + * ialloc_blks but alignment constraints prevent us from using |
|---|
| 1012 | 1004 | * it. |
|---|
| 1013 | 1005 | * |
|---|
| 1014 | 1006 | * If we can't find an AG with space for full alignment slack to |
|---|
| .. | .. |
|---|
| 1017 | 1009 | * if we fail allocation due to alignment issues then it is most |
|---|
| 1018 | 1010 | * likely a real ENOSPC condition. |
|---|
| 1019 | 1011 | */ |
|---|
| 1020 | | - ineed = mp->m_ialloc_min_blks; |
|---|
| 1012 | + ineed = M_IGEO(mp)->ialloc_min_blks; |
|---|
| 1021 | 1013 | if (flags && ineed > 1) |
|---|
| 1022 | | - ineed += xfs_ialloc_cluster_alignment(mp); |
|---|
| 1014 | + ineed += M_IGEO(mp)->cluster_align; |
|---|
| 1023 | 1015 | longest = pag->pagf_longest; |
|---|
| 1024 | 1016 | if (!longest) |
|---|
| 1025 | 1017 | longest = pag->pagf_flcount > 0; |
|---|
| .. | .. |
|---|
| 1073 | 1065 | error = xfs_inobt_get_rec(cur, rec, &i); |
|---|
| 1074 | 1066 | if (error) |
|---|
| 1075 | 1067 | return error; |
|---|
| 1076 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
|---|
| 1068 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) |
|---|
| 1069 | + return -EFSCORRUPTED; |
|---|
| 1077 | 1070 | } |
|---|
| 1078 | 1071 | |
|---|
| 1079 | 1072 | return 0; |
|---|
| .. | .. |
|---|
| 1097 | 1090 | error = xfs_inobt_get_rec(cur, rec, &i); |
|---|
| 1098 | 1091 | if (error) |
|---|
| 1099 | 1092 | return error; |
|---|
| 1100 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
|---|
| 1093 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) |
|---|
| 1094 | + return -EFSCORRUPTED; |
|---|
| 1101 | 1095 | } |
|---|
| 1102 | 1096 | |
|---|
| 1103 | 1097 | return 0; |
|---|
| .. | .. |
|---|
| 1135 | 1129 | xfs_ino_t *inop) |
|---|
| 1136 | 1130 | { |
|---|
| 1137 | 1131 | struct xfs_mount *mp = tp->t_mountp; |
|---|
| 1138 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
|---|
| 1132 | + struct xfs_agi *agi = agbp->b_addr; |
|---|
| 1139 | 1133 | xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); |
|---|
| 1140 | 1134 | xfs_agnumber_t pagno = XFS_INO_TO_AGNO(mp, parent); |
|---|
| 1141 | 1135 | xfs_agino_t pagino = XFS_INO_TO_AGINO(mp, parent); |
|---|
| 1142 | | - struct xfs_perag *pag; |
|---|
| 1136 | + struct xfs_perag *pag = agbp->b_pag; |
|---|
| 1143 | 1137 | struct xfs_btree_cur *cur, *tcur; |
|---|
| 1144 | 1138 | struct xfs_inobt_rec_incore rec, trec; |
|---|
| 1145 | 1139 | xfs_ino_t ino; |
|---|
| .. | .. |
|---|
| 1147 | 1141 | int offset; |
|---|
| 1148 | 1142 | int i, j; |
|---|
| 1149 | 1143 | int searchdistance = 10; |
|---|
| 1150 | | - |
|---|
| 1151 | | - pag = xfs_perag_get(mp, agno); |
|---|
| 1152 | 1144 | |
|---|
| 1153 | 1145 | ASSERT(pag->pagi_init); |
|---|
| 1154 | 1146 | ASSERT(pag->pagi_inodeok); |
|---|
| .. | .. |
|---|
| 1177 | 1169 | error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); |
|---|
| 1178 | 1170 | if (error) |
|---|
| 1179 | 1171 | goto error0; |
|---|
| 1180 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
|---|
| 1172 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 1173 | + error = -EFSCORRUPTED; |
|---|
| 1174 | + goto error0; |
|---|
| 1175 | + } |
|---|
| 1181 | 1176 | |
|---|
| 1182 | 1177 | error = xfs_inobt_get_rec(cur, &rec, &j); |
|---|
| 1183 | 1178 | if (error) |
|---|
| 1184 | 1179 | goto error0; |
|---|
| 1185 | | - XFS_WANT_CORRUPTED_GOTO(mp, j == 1, error0); |
|---|
| 1180 | + if (XFS_IS_CORRUPT(mp, j != 1)) { |
|---|
| 1181 | + error = -EFSCORRUPTED; |
|---|
| 1182 | + goto error0; |
|---|
| 1183 | + } |
|---|
| 1186 | 1184 | |
|---|
| 1187 | 1185 | if (rec.ir_freecount > 0) { |
|---|
| 1188 | 1186 | /* |
|---|
| .. | .. |
|---|
| 1337 | 1335 | error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); |
|---|
| 1338 | 1336 | if (error) |
|---|
| 1339 | 1337 | goto error0; |
|---|
| 1340 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
|---|
| 1338 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 1339 | + error = -EFSCORRUPTED; |
|---|
| 1340 | + goto error0; |
|---|
| 1341 | + } |
|---|
| 1341 | 1342 | |
|---|
| 1342 | 1343 | for (;;) { |
|---|
| 1343 | 1344 | error = xfs_inobt_get_rec(cur, &rec, &i); |
|---|
| 1344 | 1345 | if (error) |
|---|
| 1345 | 1346 | goto error0; |
|---|
| 1346 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
|---|
| 1347 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 1348 | + error = -EFSCORRUPTED; |
|---|
| 1349 | + goto error0; |
|---|
| 1350 | + } |
|---|
| 1347 | 1351 | if (rec.ir_freecount > 0) |
|---|
| 1348 | 1352 | break; |
|---|
| 1349 | 1353 | error = xfs_btree_increment(cur, 0, &i); |
|---|
| 1350 | 1354 | if (error) |
|---|
| 1351 | 1355 | goto error0; |
|---|
| 1352 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
|---|
| 1356 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 1357 | + error = -EFSCORRUPTED; |
|---|
| 1358 | + goto error0; |
|---|
| 1359 | + } |
|---|
| 1353 | 1360 | } |
|---|
| 1354 | 1361 | |
|---|
| 1355 | 1362 | alloc_inode: |
|---|
| .. | .. |
|---|
| 1374 | 1381 | |
|---|
| 1375 | 1382 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); |
|---|
| 1376 | 1383 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1); |
|---|
| 1377 | | - xfs_perag_put(pag); |
|---|
| 1378 | 1384 | *inop = ino; |
|---|
| 1379 | 1385 | return 0; |
|---|
| 1380 | 1386 | error1: |
|---|
| 1381 | 1387 | xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); |
|---|
| 1382 | 1388 | error0: |
|---|
| 1383 | 1389 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
|---|
| 1384 | | - xfs_perag_put(pag); |
|---|
| 1385 | 1390 | return error; |
|---|
| 1386 | 1391 | } |
|---|
| 1387 | 1392 | |
|---|
| .. | .. |
|---|
| 1409 | 1414 | error = xfs_inobt_get_rec(lcur, rec, &i); |
|---|
| 1410 | 1415 | if (error) |
|---|
| 1411 | 1416 | return error; |
|---|
| 1412 | | - XFS_WANT_CORRUPTED_RETURN(lcur->bc_mp, i == 1); |
|---|
| 1417 | + if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1)) |
|---|
| 1418 | + return -EFSCORRUPTED; |
|---|
| 1413 | 1419 | |
|---|
| 1414 | 1420 | /* |
|---|
| 1415 | 1421 | * See if we've landed in the parent inode record. The finobt |
|---|
| .. | .. |
|---|
| 1432 | 1438 | error = xfs_inobt_get_rec(rcur, &rrec, &j); |
|---|
| 1433 | 1439 | if (error) |
|---|
| 1434 | 1440 | goto error_rcur; |
|---|
| 1435 | | - XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, j == 1, error_rcur); |
|---|
| 1441 | + if (XFS_IS_CORRUPT(lcur->bc_mp, j != 1)) { |
|---|
| 1442 | + error = -EFSCORRUPTED; |
|---|
| 1443 | + goto error_rcur; |
|---|
| 1444 | + } |
|---|
| 1436 | 1445 | } |
|---|
| 1437 | 1446 | |
|---|
| 1438 | | - XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, i == 1 || j == 1, error_rcur); |
|---|
| 1447 | + if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1 && j != 1)) { |
|---|
| 1448 | + error = -EFSCORRUPTED; |
|---|
| 1449 | + goto error_rcur; |
|---|
| 1450 | + } |
|---|
| 1439 | 1451 | if (i == 1 && j == 1) { |
|---|
| 1440 | 1452 | /* |
|---|
| 1441 | 1453 | * Both the left and right records are valid. Choose the closer |
|---|
| .. | .. |
|---|
| 1488 | 1500 | error = xfs_inobt_get_rec(cur, rec, &i); |
|---|
| 1489 | 1501 | if (error) |
|---|
| 1490 | 1502 | return error; |
|---|
| 1491 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
|---|
| 1503 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) |
|---|
| 1504 | + return -EFSCORRUPTED; |
|---|
| 1492 | 1505 | return 0; |
|---|
| 1493 | 1506 | } |
|---|
| 1494 | 1507 | } |
|---|
| .. | .. |
|---|
| 1499 | 1512 | error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); |
|---|
| 1500 | 1513 | if (error) |
|---|
| 1501 | 1514 | return error; |
|---|
| 1502 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
|---|
| 1515 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) |
|---|
| 1516 | + return -EFSCORRUPTED; |
|---|
| 1503 | 1517 | |
|---|
| 1504 | 1518 | error = xfs_inobt_get_rec(cur, rec, &i); |
|---|
| 1505 | 1519 | if (error) |
|---|
| 1506 | 1520 | return error; |
|---|
| 1507 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
|---|
| 1521 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) |
|---|
| 1522 | + return -EFSCORRUPTED; |
|---|
| 1508 | 1523 | |
|---|
| 1509 | 1524 | return 0; |
|---|
| 1510 | 1525 | } |
|---|
| .. | .. |
|---|
| 1526 | 1541 | error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i); |
|---|
| 1527 | 1542 | if (error) |
|---|
| 1528 | 1543 | return error; |
|---|
| 1529 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
|---|
| 1544 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) |
|---|
| 1545 | + return -EFSCORRUPTED; |
|---|
| 1530 | 1546 | |
|---|
| 1531 | 1547 | error = xfs_inobt_get_rec(cur, &rec, &i); |
|---|
| 1532 | 1548 | if (error) |
|---|
| 1533 | 1549 | return error; |
|---|
| 1534 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
|---|
| 1550 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) |
|---|
| 1551 | + return -EFSCORRUPTED; |
|---|
| 1535 | 1552 | ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) % |
|---|
| 1536 | 1553 | XFS_INODES_PER_CHUNK) == 0); |
|---|
| 1537 | 1554 | |
|---|
| 1538 | 1555 | rec.ir_free &= ~XFS_INOBT_MASK(offset); |
|---|
| 1539 | 1556 | rec.ir_freecount--; |
|---|
| 1540 | 1557 | |
|---|
| 1541 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, (rec.ir_free == frec->ir_free) && |
|---|
| 1542 | | - (rec.ir_freecount == frec->ir_freecount)); |
|---|
| 1558 | + if (XFS_IS_CORRUPT(cur->bc_mp, |
|---|
| 1559 | + rec.ir_free != frec->ir_free || |
|---|
| 1560 | + rec.ir_freecount != frec->ir_freecount)) |
|---|
| 1561 | + return -EFSCORRUPTED; |
|---|
| 1543 | 1562 | |
|---|
| 1544 | 1563 | return xfs_inobt_update(cur, &rec); |
|---|
| 1545 | 1564 | } |
|---|
| .. | .. |
|---|
| 1559 | 1578 | xfs_ino_t *inop) |
|---|
| 1560 | 1579 | { |
|---|
| 1561 | 1580 | struct xfs_mount *mp = tp->t_mountp; |
|---|
| 1562 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
|---|
| 1581 | + struct xfs_agi *agi = agbp->b_addr; |
|---|
| 1563 | 1582 | xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); |
|---|
| 1564 | 1583 | xfs_agnumber_t pagno = XFS_INO_TO_AGNO(mp, parent); |
|---|
| 1565 | 1584 | xfs_agino_t pagino = XFS_INO_TO_AGINO(mp, parent); |
|---|
| 1566 | | - struct xfs_perag *pag; |
|---|
| 1567 | 1585 | struct xfs_btree_cur *cur; /* finobt cursor */ |
|---|
| 1568 | 1586 | struct xfs_btree_cur *icur; /* inobt cursor */ |
|---|
| 1569 | 1587 | struct xfs_inobt_rec_incore rec; |
|---|
| .. | .. |
|---|
| 1574 | 1592 | |
|---|
| 1575 | 1593 | if (!xfs_sb_version_hasfinobt(&mp->m_sb)) |
|---|
| 1576 | 1594 | return xfs_dialloc_ag_inobt(tp, agbp, parent, inop); |
|---|
| 1577 | | - |
|---|
| 1578 | | - pag = xfs_perag_get(mp, agno); |
|---|
| 1579 | 1595 | |
|---|
| 1580 | 1596 | /* |
|---|
| 1581 | 1597 | * If pagino is 0 (this is the root inode allocation) use newino. |
|---|
| .. | .. |
|---|
| 1643 | 1659 | */ |
|---|
| 1644 | 1660 | be32_add_cpu(&agi->agi_freecount, -1); |
|---|
| 1645 | 1661 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); |
|---|
| 1646 | | - pag->pagi_freecount--; |
|---|
| 1662 | + agbp->b_pag->pagi_freecount--; |
|---|
| 1647 | 1663 | |
|---|
| 1648 | 1664 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1); |
|---|
| 1649 | 1665 | |
|---|
| .. | .. |
|---|
| 1656 | 1672 | |
|---|
| 1657 | 1673 | xfs_btree_del_cursor(icur, XFS_BTREE_NOERROR); |
|---|
| 1658 | 1674 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); |
|---|
| 1659 | | - xfs_perag_put(pag); |
|---|
| 1660 | 1675 | *inop = ino; |
|---|
| 1661 | 1676 | return 0; |
|---|
| 1662 | 1677 | |
|---|
| .. | .. |
|---|
| 1664 | 1679 | xfs_btree_del_cursor(icur, XFS_BTREE_ERROR); |
|---|
| 1665 | 1680 | error_cur: |
|---|
| 1666 | 1681 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
|---|
| 1667 | | - xfs_perag_put(pag); |
|---|
| 1668 | 1682 | return error; |
|---|
| 1669 | 1683 | } |
|---|
| 1670 | 1684 | |
|---|
| .. | .. |
|---|
| 1705 | 1719 | int noroom = 0; |
|---|
| 1706 | 1720 | xfs_agnumber_t start_agno; |
|---|
| 1707 | 1721 | struct xfs_perag *pag; |
|---|
| 1722 | + struct xfs_ino_geometry *igeo = M_IGEO(mp); |
|---|
| 1708 | 1723 | int okalloc = 1; |
|---|
| 1709 | 1724 | |
|---|
| 1710 | 1725 | if (*IO_agbp) { |
|---|
| .. | .. |
|---|
| 1735 | 1750 | * Read rough value of mp->m_icount by percpu_counter_read_positive, |
|---|
| 1736 | 1751 | * which will sacrifice the preciseness but improve the performance. |
|---|
| 1737 | 1752 | */ |
|---|
| 1738 | | - if (mp->m_maxicount && |
|---|
| 1739 | | - percpu_counter_read_positive(&mp->m_icount) + mp->m_ialloc_inos |
|---|
| 1740 | | - > mp->m_maxicount) { |
|---|
| 1753 | + if (igeo->maxicount && |
|---|
| 1754 | + percpu_counter_read_positive(&mp->m_icount) + igeo->ialloc_inos |
|---|
| 1755 | + > igeo->maxicount) { |
|---|
| 1741 | 1756 | noroom = 1; |
|---|
| 1742 | 1757 | okalloc = 0; |
|---|
| 1743 | 1758 | } |
|---|
| .. | .. |
|---|
| 1849 | 1864 | int nextbit; |
|---|
| 1850 | 1865 | xfs_agblock_t agbno; |
|---|
| 1851 | 1866 | int contigblk; |
|---|
| 1852 | | - struct xfs_owner_info oinfo; |
|---|
| 1853 | 1867 | DECLARE_BITMAP(holemask, XFS_INOBT_HOLEMASK_BITS); |
|---|
| 1854 | | - xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); |
|---|
| 1855 | 1868 | |
|---|
| 1856 | 1869 | if (!xfs_inobt_issparse(rec->ir_holemask)) { |
|---|
| 1857 | 1870 | /* not sparse, calculate extent info directly */ |
|---|
| 1858 | 1871 | xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, sagbno), |
|---|
| 1859 | | - mp->m_ialloc_blks, &oinfo); |
|---|
| 1872 | + M_IGEO(mp)->ialloc_blks, |
|---|
| 1873 | + &XFS_RMAP_OINFO_INODES); |
|---|
| 1860 | 1874 | return; |
|---|
| 1861 | 1875 | } |
|---|
| 1862 | 1876 | |
|---|
| .. | .. |
|---|
| 1900 | 1914 | ASSERT(agbno % mp->m_sb.sb_spino_align == 0); |
|---|
| 1901 | 1915 | ASSERT(contigblk % mp->m_sb.sb_spino_align == 0); |
|---|
| 1902 | 1916 | xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, agbno), |
|---|
| 1903 | | - contigblk, &oinfo); |
|---|
| 1917 | + contigblk, &XFS_RMAP_OINFO_INODES); |
|---|
| 1904 | 1918 | |
|---|
| 1905 | 1919 | /* reset range to current bit and carry on... */ |
|---|
| 1906 | 1920 | startidx = endidx = nextbit; |
|---|
| .. | .. |
|---|
| 1919 | 1933 | struct xfs_icluster *xic, |
|---|
| 1920 | 1934 | struct xfs_inobt_rec_incore *orec) |
|---|
| 1921 | 1935 | { |
|---|
| 1922 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
|---|
| 1936 | + struct xfs_agi *agi = agbp->b_addr; |
|---|
| 1923 | 1937 | xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); |
|---|
| 1924 | | - struct xfs_perag *pag; |
|---|
| 1925 | 1938 | struct xfs_btree_cur *cur; |
|---|
| 1926 | 1939 | struct xfs_inobt_rec_incore rec; |
|---|
| 1927 | 1940 | int ilen; |
|---|
| .. | .. |
|---|
| 1949 | 1962 | __func__, error); |
|---|
| 1950 | 1963 | goto error0; |
|---|
| 1951 | 1964 | } |
|---|
| 1952 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
|---|
| 1965 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 1966 | + error = -EFSCORRUPTED; |
|---|
| 1967 | + goto error0; |
|---|
| 1968 | + } |
|---|
| 1953 | 1969 | error = xfs_inobt_get_rec(cur, &rec, &i); |
|---|
| 1954 | 1970 | if (error) { |
|---|
| 1955 | 1971 | xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.", |
|---|
| 1956 | 1972 | __func__, error); |
|---|
| 1957 | 1973 | goto error0; |
|---|
| 1958 | 1974 | } |
|---|
| 1959 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
|---|
| 1975 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 1976 | + error = -EFSCORRUPTED; |
|---|
| 1977 | + goto error0; |
|---|
| 1978 | + } |
|---|
| 1960 | 1979 | /* |
|---|
| 1961 | 1980 | * Get the offset in the inode chunk. |
|---|
| 1962 | 1981 | */ |
|---|
| .. | .. |
|---|
| 1977 | 1996 | if (!(mp->m_flags & XFS_MOUNT_IKEEP) && |
|---|
| 1978 | 1997 | rec.ir_free == XFS_INOBT_ALL_FREE && |
|---|
| 1979 | 1998 | mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) { |
|---|
| 1999 | + struct xfs_perag *pag = agbp->b_pag; |
|---|
| 2000 | + |
|---|
| 1980 | 2001 | xic->deleted = true; |
|---|
| 1981 | 2002 | xic->first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino); |
|---|
| 1982 | 2003 | xic->alloc = xfs_inobt_irec_to_allocmask(&rec); |
|---|
| .. | .. |
|---|
| 1990 | 2011 | be32_add_cpu(&agi->agi_count, -ilen); |
|---|
| 1991 | 2012 | be32_add_cpu(&agi->agi_freecount, -(ilen - 1)); |
|---|
| 1992 | 2013 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT); |
|---|
| 1993 | | - pag = xfs_perag_get(mp, agno); |
|---|
| 1994 | 2014 | pag->pagi_freecount -= ilen - 1; |
|---|
| 1995 | 2015 | pag->pagi_count -= ilen; |
|---|
| 1996 | | - xfs_perag_put(pag); |
|---|
| 1997 | 2016 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen); |
|---|
| 1998 | 2017 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1)); |
|---|
| 1999 | 2018 | |
|---|
| .. | .. |
|---|
| 2019 | 2038 | */ |
|---|
| 2020 | 2039 | be32_add_cpu(&agi->agi_freecount, 1); |
|---|
| 2021 | 2040 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); |
|---|
| 2022 | | - pag = xfs_perag_get(mp, agno); |
|---|
| 2023 | | - pag->pagi_freecount++; |
|---|
| 2024 | | - xfs_perag_put(pag); |
|---|
| 2041 | + agbp->b_pag->pagi_freecount++; |
|---|
| 2025 | 2042 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1); |
|---|
| 2026 | 2043 | } |
|---|
| 2027 | 2044 | |
|---|
| .. | .. |
|---|
| 2049 | 2066 | xfs_agino_t agino, |
|---|
| 2050 | 2067 | struct xfs_inobt_rec_incore *ibtrec) /* inobt record */ |
|---|
| 2051 | 2068 | { |
|---|
| 2052 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
|---|
| 2069 | + struct xfs_agi *agi = agbp->b_addr; |
|---|
| 2053 | 2070 | xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); |
|---|
| 2054 | 2071 | struct xfs_btree_cur *cur; |
|---|
| 2055 | 2072 | struct xfs_inobt_rec_incore rec; |
|---|
| .. | .. |
|---|
| 2068 | 2085 | * freed an inode in a previously fully allocated chunk. If not, |
|---|
| 2069 | 2086 | * something is out of sync. |
|---|
| 2070 | 2087 | */ |
|---|
| 2071 | | - XFS_WANT_CORRUPTED_GOTO(mp, ibtrec->ir_freecount == 1, error); |
|---|
| 2088 | + if (XFS_IS_CORRUPT(mp, ibtrec->ir_freecount != 1)) { |
|---|
| 2089 | + error = -EFSCORRUPTED; |
|---|
| 2090 | + goto error; |
|---|
| 2091 | + } |
|---|
| 2072 | 2092 | |
|---|
| 2073 | 2093 | error = xfs_inobt_insert_rec(cur, ibtrec->ir_holemask, |
|---|
| 2074 | 2094 | ibtrec->ir_count, |
|---|
| .. | .. |
|---|
| 2091 | 2111 | error = xfs_inobt_get_rec(cur, &rec, &i); |
|---|
| 2092 | 2112 | if (error) |
|---|
| 2093 | 2113 | goto error; |
|---|
| 2094 | | - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error); |
|---|
| 2114 | + if (XFS_IS_CORRUPT(mp, i != 1)) { |
|---|
| 2115 | + error = -EFSCORRUPTED; |
|---|
| 2116 | + goto error; |
|---|
| 2117 | + } |
|---|
| 2095 | 2118 | |
|---|
| 2096 | 2119 | rec.ir_free |= XFS_INOBT_MASK(offset); |
|---|
| 2097 | 2120 | rec.ir_freecount++; |
|---|
| 2098 | 2121 | |
|---|
| 2099 | | - XFS_WANT_CORRUPTED_GOTO(mp, (rec.ir_free == ibtrec->ir_free) && |
|---|
| 2100 | | - (rec.ir_freecount == ibtrec->ir_freecount), |
|---|
| 2101 | | - error); |
|---|
| 2122 | + if (XFS_IS_CORRUPT(mp, |
|---|
| 2123 | + rec.ir_free != ibtrec->ir_free || |
|---|
| 2124 | + rec.ir_freecount != ibtrec->ir_freecount)) { |
|---|
| 2125 | + error = -EFSCORRUPTED; |
|---|
| 2126 | + goto error; |
|---|
| 2127 | + } |
|---|
| 2102 | 2128 | |
|---|
| 2103 | 2129 | /* |
|---|
| 2104 | 2130 | * The content of inobt records should always match between the inobt |
|---|
| .. | .. |
|---|
| 2265 | 2291 | |
|---|
| 2266 | 2292 | /* check that the returned record contains the required inode */ |
|---|
| 2267 | 2293 | if (rec.ir_startino > agino || |
|---|
| 2268 | | - rec.ir_startino + mp->m_ialloc_inos <= agino) |
|---|
| 2294 | + rec.ir_startino + M_IGEO(mp)->ialloc_inos <= agino) |
|---|
| 2269 | 2295 | return -EINVAL; |
|---|
| 2270 | 2296 | |
|---|
| 2271 | 2297 | /* for untrusted inodes check it is allocated first */ |
|---|
| .. | .. |
|---|
| 2292 | 2318 | xfs_agblock_t agbno; /* block number of inode in the alloc group */ |
|---|
| 2293 | 2319 | xfs_agino_t agino; /* inode number within alloc group */ |
|---|
| 2294 | 2320 | xfs_agnumber_t agno; /* allocation group number */ |
|---|
| 2295 | | - int blks_per_cluster; /* num blocks per inode cluster */ |
|---|
| 2296 | 2321 | xfs_agblock_t chunk_agbno; /* first block in inode chunk */ |
|---|
| 2297 | 2322 | xfs_agblock_t cluster_agbno; /* first block in inode cluster */ |
|---|
| 2298 | 2323 | int error; /* error code */ |
|---|
| .. | .. |
|---|
| 2338 | 2363 | return -EINVAL; |
|---|
| 2339 | 2364 | } |
|---|
| 2340 | 2365 | |
|---|
| 2341 | | - blks_per_cluster = xfs_icluster_size_fsb(mp); |
|---|
| 2342 | | - |
|---|
| 2343 | 2366 | /* |
|---|
| 2344 | 2367 | * For bulkstat and handle lookups, we have an untrusted inode number |
|---|
| 2345 | 2368 | * that we have to verify is valid. We cannot do this just by reading |
|---|
| .. | .. |
|---|
| 2359 | 2382 | * If the inode cluster size is the same as the blocksize or |
|---|
| 2360 | 2383 | * smaller we get to the buffer by simple arithmetics. |
|---|
| 2361 | 2384 | */ |
|---|
| 2362 | | - if (blks_per_cluster == 1) { |
|---|
| 2385 | + if (M_IGEO(mp)->blocks_per_cluster == 1) { |
|---|
| 2363 | 2386 | offset = XFS_INO_TO_OFFSET(mp, ino); |
|---|
| 2364 | 2387 | ASSERT(offset < mp->m_sb.sb_inopblock); |
|---|
| 2365 | 2388 | |
|---|
| .. | .. |
|---|
| 2375 | 2398 | * find the location. Otherwise we have to do a btree |
|---|
| 2376 | 2399 | * lookup to find the location. |
|---|
| 2377 | 2400 | */ |
|---|
| 2378 | | - if (mp->m_inoalign_mask) { |
|---|
| 2379 | | - offset_agbno = agbno & mp->m_inoalign_mask; |
|---|
| 2401 | + if (M_IGEO(mp)->inoalign_mask) { |
|---|
| 2402 | + offset_agbno = agbno & M_IGEO(mp)->inoalign_mask; |
|---|
| 2380 | 2403 | chunk_agbno = agbno - offset_agbno; |
|---|
| 2381 | 2404 | } else { |
|---|
| 2382 | 2405 | error = xfs_imap_lookup(mp, tp, agno, agino, agbno, |
|---|
| .. | .. |
|---|
| 2388 | 2411 | out_map: |
|---|
| 2389 | 2412 | ASSERT(agbno >= chunk_agbno); |
|---|
| 2390 | 2413 | cluster_agbno = chunk_agbno + |
|---|
| 2391 | | - ((offset_agbno / blks_per_cluster) * blks_per_cluster); |
|---|
| 2414 | + ((offset_agbno / M_IGEO(mp)->blocks_per_cluster) * |
|---|
| 2415 | + M_IGEO(mp)->blocks_per_cluster); |
|---|
| 2392 | 2416 | offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) + |
|---|
| 2393 | 2417 | XFS_INO_TO_OFFSET(mp, ino); |
|---|
| 2394 | 2418 | |
|---|
| 2395 | 2419 | imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno); |
|---|
| 2396 | | - imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); |
|---|
| 2420 | + imap->im_len = XFS_FSB_TO_BB(mp, M_IGEO(mp)->blocks_per_cluster); |
|---|
| 2397 | 2421 | imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog); |
|---|
| 2398 | 2422 | |
|---|
| 2399 | 2423 | /* |
|---|
| .. | .. |
|---|
| 2412 | 2436 | return -EINVAL; |
|---|
| 2413 | 2437 | } |
|---|
| 2414 | 2438 | return 0; |
|---|
| 2415 | | -} |
|---|
| 2416 | | - |
|---|
| 2417 | | -/* |
|---|
| 2418 | | - * Compute and fill in value of m_in_maxlevels. |
|---|
| 2419 | | - */ |
|---|
| 2420 | | -void |
|---|
| 2421 | | -xfs_ialloc_compute_maxlevels( |
|---|
| 2422 | | - xfs_mount_t *mp) /* file system mount structure */ |
|---|
| 2423 | | -{ |
|---|
| 2424 | | - uint inodes; |
|---|
| 2425 | | - |
|---|
| 2426 | | - inodes = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG; |
|---|
| 2427 | | - mp->m_in_maxlevels = xfs_btree_compute_maxlevels(mp->m_inobt_mnr, |
|---|
| 2428 | | - inodes); |
|---|
| 2429 | 2439 | } |
|---|
| 2430 | 2440 | |
|---|
| 2431 | 2441 | /* |
|---|
| .. | .. |
|---|
| 2463 | 2473 | offsetof(xfs_agi_t, agi_unlinked), |
|---|
| 2464 | 2474 | offsetof(xfs_agi_t, agi_free_root), |
|---|
| 2465 | 2475 | offsetof(xfs_agi_t, agi_free_level), |
|---|
| 2476 | + offsetof(xfs_agi_t, agi_iblocks), |
|---|
| 2466 | 2477 | sizeof(xfs_agi_t) |
|---|
| 2467 | 2478 | }; |
|---|
| 2468 | 2479 | #ifdef DEBUG |
|---|
| 2469 | | - xfs_agi_t *agi; /* allocation group header */ |
|---|
| 2480 | + struct xfs_agi *agi = bp->b_addr; |
|---|
| 2470 | 2481 | |
|---|
| 2471 | | - agi = XFS_BUF_TO_AGI(bp); |
|---|
| 2472 | 2482 | ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); |
|---|
| 2473 | 2483 | #endif |
|---|
| 2474 | 2484 | |
|---|
| .. | .. |
|---|
| 2499 | 2509 | xfs_agi_verify( |
|---|
| 2500 | 2510 | struct xfs_buf *bp) |
|---|
| 2501 | 2511 | { |
|---|
| 2502 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 2503 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(bp); |
|---|
| 2512 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 2513 | + struct xfs_agi *agi = bp->b_addr; |
|---|
| 2504 | 2514 | int i; |
|---|
| 2505 | 2515 | |
|---|
| 2506 | 2516 | if (xfs_sb_version_hascrc(&mp->m_sb)) { |
|---|
| 2507 | 2517 | if (!uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) |
|---|
| 2508 | 2518 | return __this_address; |
|---|
| 2509 | | - if (!xfs_log_check_lsn(mp, |
|---|
| 2510 | | - be64_to_cpu(XFS_BUF_TO_AGI(bp)->agi_lsn))) |
|---|
| 2519 | + if (!xfs_log_check_lsn(mp, be64_to_cpu(agi->agi_lsn))) |
|---|
| 2511 | 2520 | return __this_address; |
|---|
| 2512 | 2521 | } |
|---|
| 2513 | 2522 | |
|---|
| 2514 | 2523 | /* |
|---|
| 2515 | 2524 | * Validate the magic number of the agi block. |
|---|
| 2516 | 2525 | */ |
|---|
| 2517 | | - if (agi->agi_magicnum != cpu_to_be32(XFS_AGI_MAGIC)) |
|---|
| 2526 | + if (!xfs_verify_magic(bp, agi->agi_magicnum)) |
|---|
| 2518 | 2527 | return __this_address; |
|---|
| 2519 | 2528 | if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) |
|---|
| 2520 | 2529 | return __this_address; |
|---|
| .. | .. |
|---|
| 2551 | 2560 | xfs_agi_read_verify( |
|---|
| 2552 | 2561 | struct xfs_buf *bp) |
|---|
| 2553 | 2562 | { |
|---|
| 2554 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 2563 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 2555 | 2564 | xfs_failaddr_t fa; |
|---|
| 2556 | 2565 | |
|---|
| 2557 | 2566 | if (xfs_sb_version_hascrc(&mp->m_sb) && |
|---|
| .. | .. |
|---|
| 2568 | 2577 | xfs_agi_write_verify( |
|---|
| 2569 | 2578 | struct xfs_buf *bp) |
|---|
| 2570 | 2579 | { |
|---|
| 2571 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 2580 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 2572 | 2581 | struct xfs_buf_log_item *bip = bp->b_log_item; |
|---|
| 2582 | + struct xfs_agi *agi = bp->b_addr; |
|---|
| 2573 | 2583 | xfs_failaddr_t fa; |
|---|
| 2574 | 2584 | |
|---|
| 2575 | 2585 | fa = xfs_agi_verify(bp); |
|---|
| .. | .. |
|---|
| 2582 | 2592 | return; |
|---|
| 2583 | 2593 | |
|---|
| 2584 | 2594 | if (bip) |
|---|
| 2585 | | - XFS_BUF_TO_AGI(bp)->agi_lsn = cpu_to_be64(bip->bli_item.li_lsn); |
|---|
| 2595 | + agi->agi_lsn = cpu_to_be64(bip->bli_item.li_lsn); |
|---|
| 2586 | 2596 | xfs_buf_update_cksum(bp, XFS_AGI_CRC_OFF); |
|---|
| 2587 | 2597 | } |
|---|
| 2588 | 2598 | |
|---|
| 2589 | 2599 | const struct xfs_buf_ops xfs_agi_buf_ops = { |
|---|
| 2590 | 2600 | .name = "xfs_agi", |
|---|
| 2601 | + .magic = { cpu_to_be32(XFS_AGI_MAGIC), cpu_to_be32(XFS_AGI_MAGIC) }, |
|---|
| 2591 | 2602 | .verify_read = xfs_agi_read_verify, |
|---|
| 2592 | 2603 | .verify_write = xfs_agi_write_verify, |
|---|
| 2593 | 2604 | .verify_struct = xfs_agi_verify, |
|---|
| .. | .. |
|---|
| 2637 | 2648 | if (error) |
|---|
| 2638 | 2649 | return error; |
|---|
| 2639 | 2650 | |
|---|
| 2640 | | - agi = XFS_BUF_TO_AGI(*bpp); |
|---|
| 2641 | | - pag = xfs_perag_get(mp, agno); |
|---|
| 2651 | + agi = (*bpp)->b_addr; |
|---|
| 2652 | + pag = (*bpp)->b_pag; |
|---|
| 2642 | 2653 | if (!pag->pagi_init) { |
|---|
| 2643 | 2654 | pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); |
|---|
| 2644 | 2655 | pag->pagi_count = be32_to_cpu(agi->agi_count); |
|---|
| .. | .. |
|---|
| 2651 | 2662 | */ |
|---|
| 2652 | 2663 | ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || |
|---|
| 2653 | 2664 | XFS_FORCED_SHUTDOWN(mp)); |
|---|
| 2654 | | - xfs_perag_put(pag); |
|---|
| 2655 | 2665 | return 0; |
|---|
| 2656 | 2666 | } |
|---|
| 2657 | 2667 | |
|---|
| .. | .. |
|---|
| 2726 | 2736 | xfs_agino_t low; |
|---|
| 2727 | 2737 | xfs_agino_t high; |
|---|
| 2728 | 2738 | |
|---|
| 2729 | | - low = XFS_OFFBNO_TO_AGINO(cur->bc_mp, bno, 0); |
|---|
| 2730 | | - high = XFS_OFFBNO_TO_AGINO(cur->bc_mp, bno + len, 0) - 1; |
|---|
| 2739 | + low = XFS_AGB_TO_AGINO(cur->bc_mp, bno); |
|---|
| 2740 | + high = XFS_AGB_TO_AGINO(cur->bc_mp, bno + len) - 1; |
|---|
| 2731 | 2741 | |
|---|
| 2732 | 2742 | return xfs_ialloc_has_inode_record(cur, low, high, exists); |
|---|
| 2733 | 2743 | } |
|---|
| .. | .. |
|---|
| 2773 | 2783 | *freecount = ci.freecount; |
|---|
| 2774 | 2784 | return 0; |
|---|
| 2775 | 2785 | } |
|---|
| 2786 | + |
|---|
| 2787 | +/* |
|---|
| 2788 | + * Initialize inode-related geometry information. |
|---|
| 2789 | + * |
|---|
| 2790 | + * Compute the inode btree min and max levels and set maxicount. |
|---|
| 2791 | + * |
|---|
| 2792 | + * Set the inode cluster size. This may still be overridden by the file |
|---|
| 2793 | + * system block size if it is larger than the chosen cluster size. |
|---|
| 2794 | + * |
|---|
| 2795 | + * For v5 filesystems, scale the cluster size with the inode size to keep a |
|---|
| 2796 | + * constant ratio of inode per cluster buffer, but only if mkfs has set the |
|---|
| 2797 | + * inode alignment value appropriately for larger cluster sizes. |
|---|
| 2798 | + * |
|---|
| 2799 | + * Then compute the inode cluster alignment information. |
|---|
| 2800 | + */ |
|---|
| 2801 | +void |
|---|
| 2802 | +xfs_ialloc_setup_geometry( |
|---|
| 2803 | + struct xfs_mount *mp) |
|---|
| 2804 | +{ |
|---|
| 2805 | + struct xfs_sb *sbp = &mp->m_sb; |
|---|
| 2806 | + struct xfs_ino_geometry *igeo = M_IGEO(mp); |
|---|
| 2807 | + uint64_t icount; |
|---|
| 2808 | + uint inodes; |
|---|
| 2809 | + |
|---|
| 2810 | + igeo->new_diflags2 = 0; |
|---|
| 2811 | + if (xfs_sb_version_hasbigtime(&mp->m_sb)) |
|---|
| 2812 | + igeo->new_diflags2 |= XFS_DIFLAG2_BIGTIME; |
|---|
| 2813 | + |
|---|
| 2814 | + /* Compute inode btree geometry. */ |
|---|
| 2815 | + igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog; |
|---|
| 2816 | + igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); |
|---|
| 2817 | + igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); |
|---|
| 2818 | + igeo->inobt_mnr[0] = igeo->inobt_mxr[0] / 2; |
|---|
| 2819 | + igeo->inobt_mnr[1] = igeo->inobt_mxr[1] / 2; |
|---|
| 2820 | + |
|---|
| 2821 | + igeo->ialloc_inos = max_t(uint16_t, XFS_INODES_PER_CHUNK, |
|---|
| 2822 | + sbp->sb_inopblock); |
|---|
| 2823 | + igeo->ialloc_blks = igeo->ialloc_inos >> sbp->sb_inopblog; |
|---|
| 2824 | + |
|---|
| 2825 | + if (sbp->sb_spino_align) |
|---|
| 2826 | + igeo->ialloc_min_blks = sbp->sb_spino_align; |
|---|
| 2827 | + else |
|---|
| 2828 | + igeo->ialloc_min_blks = igeo->ialloc_blks; |
|---|
| 2829 | + |
|---|
| 2830 | + /* Compute and fill in value of m_ino_geo.inobt_maxlevels. */ |
|---|
| 2831 | + inodes = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG; |
|---|
| 2832 | + igeo->inobt_maxlevels = xfs_btree_compute_maxlevels(igeo->inobt_mnr, |
|---|
| 2833 | + inodes); |
|---|
| 2834 | + |
|---|
| 2835 | + /* |
|---|
| 2836 | + * Set the maximum inode count for this filesystem, being careful not |
|---|
| 2837 | + * to use obviously garbage sb_inopblog/sb_inopblock values. Regular |
|---|
| 2838 | + * users should never get here due to failing sb verification, but |
|---|
| 2839 | + * certain users (xfs_db) need to be usable even with corrupt metadata. |
|---|
| 2840 | + */ |
|---|
| 2841 | + if (sbp->sb_imax_pct && igeo->ialloc_blks) { |
|---|
| 2842 | + /* |
|---|
| 2843 | + * Make sure the maximum inode count is a multiple |
|---|
| 2844 | + * of the units we allocate inodes in. |
|---|
| 2845 | + */ |
|---|
| 2846 | + icount = sbp->sb_dblocks * sbp->sb_imax_pct; |
|---|
| 2847 | + do_div(icount, 100); |
|---|
| 2848 | + do_div(icount, igeo->ialloc_blks); |
|---|
| 2849 | + igeo->maxicount = XFS_FSB_TO_INO(mp, |
|---|
| 2850 | + icount * igeo->ialloc_blks); |
|---|
| 2851 | + } else { |
|---|
| 2852 | + igeo->maxicount = 0; |
|---|
| 2853 | + } |
|---|
| 2854 | + |
|---|
| 2855 | + /* |
|---|
| 2856 | + * Compute the desired size of an inode cluster buffer size, which |
|---|
| 2857 | + * starts at 8K and (on v5 filesystems) scales up with larger inode |
|---|
| 2858 | + * sizes. |
|---|
| 2859 | + * |
|---|
| 2860 | + * Preserve the desired inode cluster size because the sparse inodes |
|---|
| 2861 | + * feature uses that desired size (not the actual size) to compute the |
|---|
| 2862 | + * sparse inode alignment. The mount code validates this value, so we |
|---|
| 2863 | + * cannot change the behavior. |
|---|
| 2864 | + */ |
|---|
| 2865 | + igeo->inode_cluster_size_raw = XFS_INODE_BIG_CLUSTER_SIZE; |
|---|
| 2866 | + if (xfs_sb_version_has_v3inode(&mp->m_sb)) { |
|---|
| 2867 | + int new_size = igeo->inode_cluster_size_raw; |
|---|
| 2868 | + |
|---|
| 2869 | + new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE; |
|---|
| 2870 | + if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size)) |
|---|
| 2871 | + igeo->inode_cluster_size_raw = new_size; |
|---|
| 2872 | + } |
|---|
| 2873 | + |
|---|
| 2874 | + /* Calculate inode cluster ratios. */ |
|---|
| 2875 | + if (igeo->inode_cluster_size_raw > mp->m_sb.sb_blocksize) |
|---|
| 2876 | + igeo->blocks_per_cluster = XFS_B_TO_FSBT(mp, |
|---|
| 2877 | + igeo->inode_cluster_size_raw); |
|---|
| 2878 | + else |
|---|
| 2879 | + igeo->blocks_per_cluster = 1; |
|---|
| 2880 | + igeo->inode_cluster_size = XFS_FSB_TO_B(mp, igeo->blocks_per_cluster); |
|---|
| 2881 | + igeo->inodes_per_cluster = XFS_FSB_TO_INO(mp, igeo->blocks_per_cluster); |
|---|
| 2882 | + |
|---|
| 2883 | + /* Calculate inode cluster alignment. */ |
|---|
| 2884 | + if (xfs_sb_version_hasalign(&mp->m_sb) && |
|---|
| 2885 | + mp->m_sb.sb_inoalignmt >= igeo->blocks_per_cluster) |
|---|
| 2886 | + igeo->cluster_align = mp->m_sb.sb_inoalignmt; |
|---|
| 2887 | + else |
|---|
| 2888 | + igeo->cluster_align = 1; |
|---|
| 2889 | + igeo->inoalign_mask = igeo->cluster_align - 1; |
|---|
| 2890 | + igeo->cluster_align_inodes = XFS_FSB_TO_INO(mp, igeo->cluster_align); |
|---|
| 2891 | + |
|---|
| 2892 | + /* |
|---|
| 2893 | + * If we are using stripe alignment, check whether |
|---|
| 2894 | + * the stripe unit is a multiple of the inode alignment |
|---|
| 2895 | + */ |
|---|
| 2896 | + if (mp->m_dalign && igeo->inoalign_mask && |
|---|
| 2897 | + !(mp->m_dalign & igeo->inoalign_mask)) |
|---|
| 2898 | + igeo->ialloc_align = mp->m_dalign; |
|---|
| 2899 | + else |
|---|
| 2900 | + igeo->ialloc_align = 0; |
|---|
| 2901 | +} |
|---|
| 2902 | + |
|---|
| 2903 | +/* Compute the location of the root directory inode that is laid out by mkfs. */ |
|---|
| 2904 | +xfs_ino_t |
|---|
| 2905 | +xfs_ialloc_calc_rootino( |
|---|
| 2906 | + struct xfs_mount *mp, |
|---|
| 2907 | + int sunit) |
|---|
| 2908 | +{ |
|---|
| 2909 | + struct xfs_ino_geometry *igeo = M_IGEO(mp); |
|---|
| 2910 | + xfs_agblock_t first_bno; |
|---|
| 2911 | + |
|---|
| 2912 | + /* |
|---|
| 2913 | + * Pre-calculate the geometry of AG 0. We know what it looks like |
|---|
| 2914 | + * because libxfs knows how to create allocation groups now. |
|---|
| 2915 | + * |
|---|
| 2916 | + * first_bno is the first block in which mkfs could possibly have |
|---|
| 2917 | + * allocated the root directory inode, once we factor in the metadata |
|---|
| 2918 | + * that mkfs formats before it. Namely, the four AG headers... |
|---|
| 2919 | + */ |
|---|
| 2920 | + first_bno = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize); |
|---|
| 2921 | + |
|---|
| 2922 | + /* ...the two free space btree roots... */ |
|---|
| 2923 | + first_bno += 2; |
|---|
| 2924 | + |
|---|
| 2925 | + /* ...the inode btree root... */ |
|---|
| 2926 | + first_bno += 1; |
|---|
| 2927 | + |
|---|
| 2928 | + /* ...the initial AGFL... */ |
|---|
| 2929 | + first_bno += xfs_alloc_min_freelist(mp, NULL); |
|---|
| 2930 | + |
|---|
| 2931 | + /* ...the free inode btree root... */ |
|---|
| 2932 | + if (xfs_sb_version_hasfinobt(&mp->m_sb)) |
|---|
| 2933 | + first_bno++; |
|---|
| 2934 | + |
|---|
| 2935 | + /* ...the reverse mapping btree root... */ |
|---|
| 2936 | + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) |
|---|
| 2937 | + first_bno++; |
|---|
| 2938 | + |
|---|
| 2939 | + /* ...the reference count btree... */ |
|---|
| 2940 | + if (xfs_sb_version_hasreflink(&mp->m_sb)) |
|---|
| 2941 | + first_bno++; |
|---|
| 2942 | + |
|---|
| 2943 | + /* |
|---|
| 2944 | + * ...and the log, if it is allocated in the first allocation group. |
|---|
| 2945 | + * |
|---|
| 2946 | + * This can happen with filesystems that only have a single |
|---|
| 2947 | + * allocation group, or very odd geometries created by old mkfs |
|---|
| 2948 | + * versions on very small filesystems. |
|---|
| 2949 | + */ |
|---|
| 2950 | + if (mp->m_sb.sb_logstart && |
|---|
| 2951 | + XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == 0) |
|---|
| 2952 | + first_bno += mp->m_sb.sb_logblocks; |
|---|
| 2953 | + |
|---|
| 2954 | + /* |
|---|
| 2955 | + * Now round first_bno up to whatever allocation alignment is given |
|---|
| 2956 | + * by the filesystem or was passed in. |
|---|
| 2957 | + */ |
|---|
| 2958 | + if (xfs_sb_version_hasdalign(&mp->m_sb) && igeo->ialloc_align > 0) |
|---|
| 2959 | + first_bno = roundup(first_bno, sunit); |
|---|
| 2960 | + else if (xfs_sb_version_hasalign(&mp->m_sb) && |
|---|
| 2961 | + mp->m_sb.sb_inoalignmt > 1) |
|---|
| 2962 | + first_bno = roundup(first_bno, mp->m_sb.sb_inoalignmt); |
|---|
| 2963 | + |
|---|
| 2964 | + return XFS_AGINO_TO_INO(mp, 0, XFS_AGB_TO_AGINO(mp, first_bno)); |
|---|
| 2965 | +} |
|---|