| .. | .. |
|---|
| 12 | 12 | #include "xfs_bit.h" |
|---|
| 13 | 13 | #include "xfs_sb.h" |
|---|
| 14 | 14 | #include "xfs_mount.h" |
|---|
| 15 | | -#include "xfs_defer.h" |
|---|
| 16 | | -#include "xfs_inode.h" |
|---|
| 17 | 15 | #include "xfs_ialloc.h" |
|---|
| 18 | 16 | #include "xfs_alloc.h" |
|---|
| 19 | 17 | #include "xfs_error.h" |
|---|
| 20 | 18 | #include "xfs_trace.h" |
|---|
| 21 | | -#include "xfs_cksum.h" |
|---|
| 22 | 19 | #include "xfs_trans.h" |
|---|
| 23 | 20 | #include "xfs_buf_item.h" |
|---|
| 24 | 21 | #include "xfs_bmap_btree.h" |
|---|
| 25 | 22 | #include "xfs_alloc_btree.h" |
|---|
| 26 | | -#include "xfs_ialloc_btree.h" |
|---|
| 27 | 23 | #include "xfs_log.h" |
|---|
| 28 | 24 | #include "xfs_rmap_btree.h" |
|---|
| 29 | | -#include "xfs_bmap.h" |
|---|
| 30 | 25 | #include "xfs_refcount_btree.h" |
|---|
| 31 | 26 | #include "xfs_da_format.h" |
|---|
| 32 | | -#include "xfs_da_btree.h" |
|---|
| 27 | +#include "xfs_health.h" |
|---|
| 33 | 28 | |
|---|
| 34 | 29 | /* |
|---|
| 35 | 30 | * Physical superblock buffer manipulations. Shared with libxfs in userspace. |
|---|
| .. | .. |
|---|
| 225 | 220 | struct xfs_buf *bp, |
|---|
| 226 | 221 | struct xfs_sb *sbp) |
|---|
| 227 | 222 | { |
|---|
| 223 | + struct xfs_dsb *dsb = bp->b_addr; |
|---|
| 228 | 224 | uint32_t agcount = 0; |
|---|
| 229 | 225 | uint32_t rem; |
|---|
| 230 | 226 | |
|---|
| 231 | | - if (sbp->sb_magicnum != XFS_SB_MAGIC) { |
|---|
| 227 | + if (!xfs_verify_magic(bp, dsb->sb_magicnum)) { |
|---|
| 232 | 228 | xfs_warn(mp, "bad magic number"); |
|---|
| 233 | 229 | return -EWRONGFS; |
|---|
| 234 | 230 | } |
|---|
| .. | .. |
|---|
| 247 | 243 | } else if (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD | |
|---|
| 248 | 244 | XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) { |
|---|
| 249 | 245 | xfs_notice(mp, |
|---|
| 250 | | -"Superblock earlier than Version 5 has XFS_[PQ]UOTA_{ENFD|CHKD} bits."); |
|---|
| 246 | +"Superblock earlier than Version 5 has XFS_{P|G}QUOTA_{ENFD|CHKD} bits."); |
|---|
| 251 | 247 | return -EFSCORRUPTED; |
|---|
| 252 | 248 | } |
|---|
| 253 | 249 | |
|---|
| .. | .. |
|---|
| 330 | 326 | sbp->sb_shared_vn != 0)) { |
|---|
| 331 | 327 | xfs_notice(mp, "SB sanity check failed"); |
|---|
| 332 | 328 | return -EFSCORRUPTED; |
|---|
| 329 | + } |
|---|
| 330 | + |
|---|
| 331 | + /* Validate the realtime geometry; stolen from xfs_repair */ |
|---|
| 332 | + if (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE || |
|---|
| 333 | + sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) { |
|---|
| 334 | + xfs_notice(mp, |
|---|
| 335 | + "realtime extent sanity check failed"); |
|---|
| 336 | + return -EFSCORRUPTED; |
|---|
| 337 | + } |
|---|
| 338 | + |
|---|
| 339 | + if (sbp->sb_rblocks == 0) { |
|---|
| 340 | + if (sbp->sb_rextents != 0 || sbp->sb_rbmblocks != 0 || |
|---|
| 341 | + sbp->sb_rextslog != 0 || sbp->sb_frextents != 0) { |
|---|
| 342 | + xfs_notice(mp, |
|---|
| 343 | + "realtime zeroed geometry check failed"); |
|---|
| 344 | + return -EFSCORRUPTED; |
|---|
| 345 | + } |
|---|
| 346 | + } else { |
|---|
| 347 | + uint64_t rexts; |
|---|
| 348 | + uint64_t rbmblocks; |
|---|
| 349 | + |
|---|
| 350 | + rexts = div_u64(sbp->sb_rblocks, sbp->sb_rextsize); |
|---|
| 351 | + rbmblocks = howmany_64(sbp->sb_rextents, |
|---|
| 352 | + NBBY * sbp->sb_blocksize); |
|---|
| 353 | + |
|---|
| 354 | + if (sbp->sb_rextents != rexts || |
|---|
| 355 | + sbp->sb_rextslog != xfs_highbit32(sbp->sb_rextents) || |
|---|
| 356 | + sbp->sb_rbmblocks != rbmblocks) { |
|---|
| 357 | + xfs_notice(mp, |
|---|
| 358 | + "realtime geometry sanity check failed"); |
|---|
| 359 | + return -EFSCORRUPTED; |
|---|
| 360 | + } |
|---|
| 333 | 361 | } |
|---|
| 334 | 362 | |
|---|
| 335 | 363 | if (sbp->sb_unit) { |
|---|
| .. | .. |
|---|
| 572 | 600 | * disk. If neither are active, we should NULL the inode. |
|---|
| 573 | 601 | * |
|---|
| 574 | 602 | * In all cases, the separate pquotino must remain 0 because it |
|---|
| 575 | | - * it beyond the "end" of the valid non-pquotino superblock. |
|---|
| 603 | + * is beyond the "end" of the valid non-pquotino superblock. |
|---|
| 576 | 604 | */ |
|---|
| 577 | 605 | if (from->sb_qflags & XFS_GQUOTA_ACCT) |
|---|
| 578 | 606 | to->sb_gquotino = cpu_to_be64(from->sb_gquotino); |
|---|
| .. | .. |
|---|
| 684 | 712 | struct xfs_buf *bp) |
|---|
| 685 | 713 | { |
|---|
| 686 | 714 | struct xfs_sb sb; |
|---|
| 687 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 688 | | - struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); |
|---|
| 715 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 716 | + struct xfs_dsb *dsb = bp->b_addr; |
|---|
| 689 | 717 | int error; |
|---|
| 690 | 718 | |
|---|
| 691 | 719 | /* |
|---|
| .. | .. |
|---|
| 711 | 739 | * Check all the superblock fields. Don't byteswap the xquota flags |
|---|
| 712 | 740 | * because _verify_common checks the on-disk values. |
|---|
| 713 | 741 | */ |
|---|
| 714 | | - __xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp), false); |
|---|
| 742 | + __xfs_sb_from_disk(&sb, dsb, false); |
|---|
| 715 | 743 | error = xfs_validate_sb_common(mp, bp, &sb); |
|---|
| 716 | 744 | if (error) |
|---|
| 717 | 745 | goto out_error; |
|---|
| .. | .. |
|---|
| 734 | 762 | xfs_sb_quiet_read_verify( |
|---|
| 735 | 763 | struct xfs_buf *bp) |
|---|
| 736 | 764 | { |
|---|
| 737 | | - struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); |
|---|
| 765 | + struct xfs_dsb *dsb = bp->b_addr; |
|---|
| 738 | 766 | |
|---|
| 739 | 767 | if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) { |
|---|
| 740 | 768 | /* XFS filesystem, verify noisily! */ |
|---|
| .. | .. |
|---|
| 750 | 778 | struct xfs_buf *bp) |
|---|
| 751 | 779 | { |
|---|
| 752 | 780 | struct xfs_sb sb; |
|---|
| 753 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 781 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 754 | 782 | struct xfs_buf_log_item *bip = bp->b_log_item; |
|---|
| 783 | + struct xfs_dsb *dsb = bp->b_addr; |
|---|
| 755 | 784 | int error; |
|---|
| 756 | 785 | |
|---|
| 757 | 786 | /* |
|---|
| 758 | 787 | * Check all the superblock fields. Don't byteswap the xquota flags |
|---|
| 759 | 788 | * because _verify_common checks the on-disk values. |
|---|
| 760 | 789 | */ |
|---|
| 761 | | - __xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp), false); |
|---|
| 790 | + __xfs_sb_from_disk(&sb, dsb, false); |
|---|
| 762 | 791 | error = xfs_validate_sb_common(mp, bp, &sb); |
|---|
| 763 | 792 | if (error) |
|---|
| 764 | 793 | goto out_error; |
|---|
| .. | .. |
|---|
| 770 | 799 | return; |
|---|
| 771 | 800 | |
|---|
| 772 | 801 | if (bip) |
|---|
| 773 | | - XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn); |
|---|
| 802 | + dsb->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn); |
|---|
| 774 | 803 | |
|---|
| 775 | 804 | xfs_buf_update_cksum(bp, XFS_SB_CRC_OFF); |
|---|
| 776 | 805 | return; |
|---|
| .. | .. |
|---|
| 781 | 810 | |
|---|
| 782 | 811 | const struct xfs_buf_ops xfs_sb_buf_ops = { |
|---|
| 783 | 812 | .name = "xfs_sb", |
|---|
| 813 | + .magic = { cpu_to_be32(XFS_SB_MAGIC), cpu_to_be32(XFS_SB_MAGIC) }, |
|---|
| 784 | 814 | .verify_read = xfs_sb_read_verify, |
|---|
| 785 | 815 | .verify_write = xfs_sb_write_verify, |
|---|
| 786 | 816 | }; |
|---|
| 787 | 817 | |
|---|
| 788 | 818 | const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { |
|---|
| 789 | 819 | .name = "xfs_sb_quiet", |
|---|
| 820 | + .magic = { cpu_to_be32(XFS_SB_MAGIC), cpu_to_be32(XFS_SB_MAGIC) }, |
|---|
| 790 | 821 | .verify_read = xfs_sb_quiet_read_verify, |
|---|
| 791 | 822 | .verify_write = xfs_sb_write_verify, |
|---|
| 792 | 823 | }; |
|---|
| .. | .. |
|---|
| 796 | 827 | * |
|---|
| 797 | 828 | * Mount initialization code establishing various mount |
|---|
| 798 | 829 | * fields from the superblock associated with the given |
|---|
| 799 | | - * mount structure |
|---|
| 830 | + * mount structure. |
|---|
| 831 | + * |
|---|
| 832 | + * Inode geometry are calculated in xfs_ialloc_setup_geometry. |
|---|
| 800 | 833 | */ |
|---|
| 801 | 834 | void |
|---|
| 802 | 835 | xfs_sb_mount_common( |
|---|
| 803 | | - struct xfs_mount *mp, |
|---|
| 804 | | - struct xfs_sb *sbp) |
|---|
| 836 | + struct xfs_mount *mp, |
|---|
| 837 | + struct xfs_sb *sbp) |
|---|
| 805 | 838 | { |
|---|
| 806 | 839 | mp->m_agfrotor = mp->m_agirotor = 0; |
|---|
| 807 | 840 | mp->m_maxagi = mp->m_sb.sb_agcount; |
|---|
| .. | .. |
|---|
| 809 | 842 | mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; |
|---|
| 810 | 843 | mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; |
|---|
| 811 | 844 | mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; |
|---|
| 812 | | - mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; |
|---|
| 813 | 845 | mp->m_blockmask = sbp->sb_blocksize - 1; |
|---|
| 814 | 846 | mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; |
|---|
| 815 | 847 | mp->m_blockwmask = mp->m_blockwsize - 1; |
|---|
| .. | .. |
|---|
| 818 | 850 | mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); |
|---|
| 819 | 851 | mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; |
|---|
| 820 | 852 | mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2; |
|---|
| 821 | | - |
|---|
| 822 | | - mp->m_inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); |
|---|
| 823 | | - mp->m_inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); |
|---|
| 824 | | - mp->m_inobt_mnr[0] = mp->m_inobt_mxr[0] / 2; |
|---|
| 825 | | - mp->m_inobt_mnr[1] = mp->m_inobt_mxr[1] / 2; |
|---|
| 826 | 853 | |
|---|
| 827 | 854 | mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1); |
|---|
| 828 | 855 | mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0); |
|---|
| .. | .. |
|---|
| 840 | 867 | mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2; |
|---|
| 841 | 868 | |
|---|
| 842 | 869 | mp->m_bsize = XFS_FSB_TO_BB(mp, 1); |
|---|
| 843 | | - mp->m_ialloc_inos = max_t(uint16_t, XFS_INODES_PER_CHUNK, |
|---|
| 844 | | - sbp->sb_inopblock); |
|---|
| 845 | | - mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; |
|---|
| 846 | | - |
|---|
| 847 | | - if (sbp->sb_spino_align) |
|---|
| 848 | | - mp->m_ialloc_min_blks = sbp->sb_spino_align; |
|---|
| 849 | | - else |
|---|
| 850 | | - mp->m_ialloc_min_blks = mp->m_ialloc_blks; |
|---|
| 851 | 870 | mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); |
|---|
| 852 | 871 | mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp); |
|---|
| 853 | 872 | } |
|---|
| .. | .. |
|---|
| 874 | 893 | uint64_t bfreelst = 0; |
|---|
| 875 | 894 | uint64_t btree = 0; |
|---|
| 876 | 895 | uint64_t fdblocks; |
|---|
| 877 | | - int error; |
|---|
| 896 | + int error = 0; |
|---|
| 878 | 897 | |
|---|
| 879 | 898 | for (index = 0; index < agcount; index++) { |
|---|
| 880 | 899 | /* |
|---|
| .. | .. |
|---|
| 902 | 921 | /* |
|---|
| 903 | 922 | * If the new summary counts are obviously incorrect, fail the |
|---|
| 904 | 923 | * mount operation because that implies the AGFs are also corrupt. |
|---|
| 905 | | - * Clear BAD_SUMMARY so that we don't unmount with a dirty log, which |
|---|
| 924 | + * Clear FS_COUNTERS so that we don't unmount with a dirty log, which |
|---|
| 906 | 925 | * will prevent xfs_repair from fixing anything. |
|---|
| 907 | 926 | */ |
|---|
| 908 | 927 | if (fdblocks > sbp->sb_dblocks || ifree > ialloc) { |
|---|
| .. | .. |
|---|
| 920 | 939 | |
|---|
| 921 | 940 | xfs_reinit_percpu_counters(mp); |
|---|
| 922 | 941 | out: |
|---|
| 923 | | - mp->m_flags &= ~XFS_MOUNT_BAD_SUMMARY; |
|---|
| 942 | + xfs_fs_mark_healthy(mp, XFS_SICK_FS_COUNTERS); |
|---|
| 924 | 943 | return error; |
|---|
| 925 | 944 | } |
|---|
| 926 | 945 | |
|---|
| .. | .. |
|---|
| 935 | 954 | struct xfs_trans *tp) |
|---|
| 936 | 955 | { |
|---|
| 937 | 956 | struct xfs_mount *mp = tp->t_mountp; |
|---|
| 938 | | - struct xfs_buf *bp = xfs_trans_getsb(tp, mp, 0); |
|---|
| 957 | + struct xfs_buf *bp = xfs_trans_getsb(tp); |
|---|
| 939 | 958 | |
|---|
| 940 | | - mp->m_sb.sb_icount = percpu_counter_sum(&mp->m_icount); |
|---|
| 941 | | - mp->m_sb.sb_ifree = percpu_counter_sum(&mp->m_ifree); |
|---|
| 942 | | - mp->m_sb.sb_fdblocks = percpu_counter_sum(&mp->m_fdblocks); |
|---|
| 959 | + /* |
|---|
| 960 | + * Lazy sb counters don't update the in-core superblock so do that now. |
|---|
| 961 | + * If this is at unmount, the counters will be exactly correct, but at |
|---|
| 962 | + * any other time they will only be ballpark correct because of |
|---|
| 963 | + * reservations that have been taken out percpu counters. If we have an |
|---|
| 964 | + * unclean shutdown, this will be corrected by log recovery rebuilding |
|---|
| 965 | + * the counters from the AGF block counts. |
|---|
| 966 | + */ |
|---|
| 967 | + if (xfs_sb_version_haslazysbcount(&mp->m_sb)) { |
|---|
| 968 | + mp->m_sb.sb_icount = percpu_counter_sum(&mp->m_icount); |
|---|
| 969 | + mp->m_sb.sb_ifree = percpu_counter_sum(&mp->m_ifree); |
|---|
| 970 | + mp->m_sb.sb_fdblocks = percpu_counter_sum(&mp->m_fdblocks); |
|---|
| 971 | + } |
|---|
| 943 | 972 | |
|---|
| 944 | | - xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); |
|---|
| 973 | + xfs_sb_to_disk(bp->b_addr, &mp->m_sb); |
|---|
| 945 | 974 | xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); |
|---|
| 946 | | - xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb)); |
|---|
| 975 | + xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb) - 1); |
|---|
| 947 | 976 | } |
|---|
| 948 | 977 | |
|---|
| 949 | 978 | /* |
|---|
| .. | .. |
|---|
| 999 | 1028 | for (agno = 1; agno < mp->m_sb.sb_agcount; agno++) { |
|---|
| 1000 | 1029 | struct xfs_buf *bp; |
|---|
| 1001 | 1030 | |
|---|
| 1002 | | - bp = xfs_buf_get(mp->m_ddev_targp, |
|---|
| 1031 | + error = xfs_buf_get(mp->m_ddev_targp, |
|---|
| 1003 | 1032 | XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), |
|---|
| 1004 | | - XFS_FSS_TO_BB(mp, 1), 0); |
|---|
| 1033 | + XFS_FSS_TO_BB(mp, 1), &bp); |
|---|
| 1005 | 1034 | /* |
|---|
| 1006 | 1035 | * If we get an error reading or writing alternate superblocks, |
|---|
| 1007 | 1036 | * continue. xfs_repair chooses the "best" superblock based |
|---|
| .. | .. |
|---|
| 1009 | 1038 | * superblocks un-updated than updated, and xfs_repair may |
|---|
| 1010 | 1039 | * pick them over the properly-updated primary. |
|---|
| 1011 | 1040 | */ |
|---|
| 1012 | | - if (!bp) { |
|---|
| 1041 | + if (error) { |
|---|
| 1013 | 1042 | xfs_warn(mp, |
|---|
| 1014 | 1043 | "error allocating secondary superblock for ag %d", |
|---|
| 1015 | 1044 | agno); |
|---|
| 1016 | 1045 | if (!saved_error) |
|---|
| 1017 | | - saved_error = -ENOMEM; |
|---|
| 1046 | + saved_error = error; |
|---|
| 1018 | 1047 | continue; |
|---|
| 1019 | 1048 | } |
|---|
| 1020 | 1049 | |
|---|
| 1021 | 1050 | bp->b_ops = &xfs_sb_buf_ops; |
|---|
| 1022 | 1051 | xfs_buf_oneshot(bp); |
|---|
| 1023 | 1052 | xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); |
|---|
| 1024 | | - xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); |
|---|
| 1053 | + xfs_sb_to_disk(bp->b_addr, &mp->m_sb); |
|---|
| 1025 | 1054 | xfs_buf_delwri_queue(bp, &buffer_list); |
|---|
| 1026 | 1055 | xfs_buf_relse(bp); |
|---|
| 1027 | 1056 | |
|---|
| .. | .. |
|---|
| 1065 | 1094 | if (error) |
|---|
| 1066 | 1095 | return error; |
|---|
| 1067 | 1096 | |
|---|
| 1068 | | - bp = xfs_trans_getsb(tp, mp, 0); |
|---|
| 1097 | + bp = xfs_trans_getsb(tp); |
|---|
| 1069 | 1098 | xfs_log_sb(tp); |
|---|
| 1070 | 1099 | xfs_trans_bhold(tp, bp); |
|---|
| 1071 | 1100 | xfs_trans_set_sync(tp); |
|---|
| .. | .. |
|---|
| 1081 | 1110 | return error; |
|---|
| 1082 | 1111 | } |
|---|
| 1083 | 1112 | |
|---|
| 1084 | | -int |
|---|
| 1113 | +void |
|---|
| 1085 | 1114 | xfs_fs_geometry( |
|---|
| 1086 | 1115 | struct xfs_sb *sbp, |
|---|
| 1087 | 1116 | struct xfs_fsop_geom *geo, |
|---|
| .. | .. |
|---|
| 1105 | 1134 | memcpy(geo->uuid, &sbp->sb_uuid, sizeof(sbp->sb_uuid)); |
|---|
| 1106 | 1135 | |
|---|
| 1107 | 1136 | if (struct_version < 2) |
|---|
| 1108 | | - return 0; |
|---|
| 1137 | + return; |
|---|
| 1109 | 1138 | |
|---|
| 1110 | 1139 | geo->sunit = sbp->sb_unit; |
|---|
| 1111 | 1140 | geo->swidth = sbp->sb_width; |
|---|
| 1112 | 1141 | |
|---|
| 1113 | 1142 | if (struct_version < 3) |
|---|
| 1114 | | - return 0; |
|---|
| 1143 | + return; |
|---|
| 1115 | 1144 | |
|---|
| 1116 | 1145 | geo->version = XFS_FSOP_GEOM_VERSION; |
|---|
| 1117 | 1146 | geo->flags = XFS_FSOP_GEOM_FLAGS_NLINK | |
|---|
| 1118 | | - XFS_FSOP_GEOM_FLAGS_DIRV2; |
|---|
| 1147 | + XFS_FSOP_GEOM_FLAGS_DIRV2 | |
|---|
| 1148 | + XFS_FSOP_GEOM_FLAGS_EXTFLG; |
|---|
| 1119 | 1149 | if (xfs_sb_version_hasattr(sbp)) |
|---|
| 1120 | 1150 | geo->flags |= XFS_FSOP_GEOM_FLAGS_ATTR; |
|---|
| 1121 | 1151 | if (xfs_sb_version_hasquota(sbp)) |
|---|
| .. | .. |
|---|
| 1124 | 1154 | geo->flags |= XFS_FSOP_GEOM_FLAGS_IALIGN; |
|---|
| 1125 | 1155 | if (xfs_sb_version_hasdalign(sbp)) |
|---|
| 1126 | 1156 | geo->flags |= XFS_FSOP_GEOM_FLAGS_DALIGN; |
|---|
| 1127 | | - if (xfs_sb_version_hasextflgbit(sbp)) |
|---|
| 1128 | | - geo->flags |= XFS_FSOP_GEOM_FLAGS_EXTFLG; |
|---|
| 1129 | 1157 | if (xfs_sb_version_hassector(sbp)) |
|---|
| 1130 | 1158 | geo->flags |= XFS_FSOP_GEOM_FLAGS_SECTOR; |
|---|
| 1131 | 1159 | if (xfs_sb_version_hasasciici(sbp)) |
|---|
| .. | .. |
|---|
| 1148 | 1176 | geo->flags |= XFS_FSOP_GEOM_FLAGS_RMAPBT; |
|---|
| 1149 | 1177 | if (xfs_sb_version_hasreflink(sbp)) |
|---|
| 1150 | 1178 | geo->flags |= XFS_FSOP_GEOM_FLAGS_REFLINK; |
|---|
| 1179 | + if (xfs_sb_version_hasbigtime(sbp)) |
|---|
| 1180 | + geo->flags |= XFS_FSOP_GEOM_FLAGS_BIGTIME; |
|---|
| 1151 | 1181 | if (xfs_sb_version_hassector(sbp)) |
|---|
| 1152 | 1182 | geo->logsectsize = sbp->sb_logsectsize; |
|---|
| 1153 | 1183 | else |
|---|
| .. | .. |
|---|
| 1156 | 1186 | geo->dirblocksize = xfs_dir2_dirblock_bytes(sbp); |
|---|
| 1157 | 1187 | |
|---|
| 1158 | 1188 | if (struct_version < 4) |
|---|
| 1159 | | - return 0; |
|---|
| 1189 | + return; |
|---|
| 1160 | 1190 | |
|---|
| 1161 | 1191 | if (xfs_sb_version_haslogv2(sbp)) |
|---|
| 1162 | 1192 | geo->flags |= XFS_FSOP_GEOM_FLAGS_LOGV2; |
|---|
| 1163 | 1193 | |
|---|
| 1164 | 1194 | geo->logsunit = sbp->sb_logsunit; |
|---|
| 1165 | 1195 | |
|---|
| 1166 | | - return 0; |
|---|
| 1196 | + if (struct_version < 5) |
|---|
| 1197 | + return; |
|---|
| 1198 | + |
|---|
| 1199 | + geo->version = XFS_FSOP_GEOM_VERSION_V5; |
|---|
| 1167 | 1200 | } |
|---|
| 1168 | 1201 | |
|---|
| 1169 | 1202 | /* Read a secondary superblock. */ |
|---|
| .. | .. |
|---|
| 1197 | 1230 | struct xfs_buf **bpp) |
|---|
| 1198 | 1231 | { |
|---|
| 1199 | 1232 | struct xfs_buf *bp; |
|---|
| 1233 | + int error; |
|---|
| 1200 | 1234 | |
|---|
| 1201 | 1235 | ASSERT(agno != 0 && agno != NULLAGNUMBER); |
|---|
| 1202 | | - bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, |
|---|
| 1236 | + error = xfs_trans_get_buf(tp, mp->m_ddev_targp, |
|---|
| 1203 | 1237 | XFS_AG_DADDR(mp, agno, XFS_SB_BLOCK(mp)), |
|---|
| 1204 | | - XFS_FSS_TO_BB(mp, 1), 0); |
|---|
| 1205 | | - if (!bp) |
|---|
| 1206 | | - return -ENOMEM; |
|---|
| 1238 | + XFS_FSS_TO_BB(mp, 1), 0, &bp); |
|---|
| 1239 | + if (error) |
|---|
| 1240 | + return error; |
|---|
| 1207 | 1241 | bp->b_ops = &xfs_sb_buf_ops; |
|---|
| 1208 | 1242 | xfs_buf_oneshot(bp); |
|---|
| 1209 | 1243 | *bpp = bp; |
|---|