xfs_mount.c (31881d74b6dd1a6c530cff61248def4f2da38bee) | xfs_mount.c (83e782e1a1cc0159888e58e14dfc8f3289663338) |
---|---|
1/* 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * --- 300 unchanged lines hidden (view full) --- 309 310/* 311 * Check the validity of the SB found. 312 */ 313STATIC int 314xfs_mount_validate_sb( 315 xfs_mount_t *mp, 316 xfs_sb_t *sbp, | 1/* 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * --- 300 unchanged lines hidden (view full) --- 309 310/* 311 * Check the validity of the SB found. 312 */ 313STATIC int 314xfs_mount_validate_sb( 315 xfs_mount_t *mp, 316 xfs_sb_t *sbp, |
317 bool check_inprogress) | 317 bool check_inprogress, 318 bool check_version) |
318{ 319 320 /* 321 * If the log device and data device have the 322 * same device number, the log is internal. 323 * Consequently, the sb_logstart should be non-zero. If 324 * we have a zero sb_logstart in this case, we may be trying to mount 325 * a volume filesystem in a non-volume manner. --- 4 unchanged lines hidden (view full) --- 330 } 331 332 333 if (!xfs_sb_good_version(sbp)) { 334 xfs_warn(mp, "bad version"); 335 return XFS_ERROR(EWRONGFS); 336 } 337 | 319{ 320 321 /* 322 * If the log device and data device have the 323 * same device number, the log is internal. 324 * Consequently, the sb_logstart should be non-zero. If 325 * we have a zero sb_logstart in this case, we may be trying to mount 326 * a volume filesystem in a non-volume manner. --- 4 unchanged lines hidden (view full) --- 331 } 332 333 334 if (!xfs_sb_good_version(sbp)) { 335 xfs_warn(mp, "bad version"); 336 return XFS_ERROR(EWRONGFS); 337 } 338 |
339 if ((sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) && 340 (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD | 341 XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))) { 342 xfs_notice(mp, 343"Super block has XFS_OQUOTA bits along with XFS_PQUOTA and/or XFS_GQUOTA bits.\n"); 344 return XFS_ERROR(EFSCORRUPTED); 345 } 346 |
|
338 /* 339 * Version 5 superblock feature mask validation. Reject combinations the | 347 /* 348 * Version 5 superblock feature mask validation. Reject combinations the |
340 * kernel cannot support up front before checking anything else. | 349 * kernel cannot support up front before checking anything else. For 350 * write validation, we don't need to check feature masks. |
341 */ | 351 */ |
342 if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { | 352 if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { |
343 xfs_alert(mp, 344"Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" 345"Use of these features in this kernel is at your own risk!"); 346 347 if (xfs_sb_has_compat_feature(sbp, 348 XFS_SB_FEAT_COMPAT_UNKNOWN)) { 349 xfs_warn(mp, 350"Superblock has unknown compatible features (0x%x) enabled.\n" --- 203 unchanged lines hidden (view full) --- 554 kmem_free(pag); 555 for (; index > first_initialised; index--) { 556 pag = radix_tree_delete(&mp->m_perag_tree, index); 557 kmem_free(pag); 558 } 559 return error; 560} 561 | 353 xfs_alert(mp, 354"Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" 355"Use of these features in this kernel is at your own risk!"); 356 357 if (xfs_sb_has_compat_feature(sbp, 358 XFS_SB_FEAT_COMPAT_UNKNOWN)) { 359 xfs_warn(mp, 360"Superblock has unknown compatible features (0x%x) enabled.\n" --- 203 unchanged lines hidden (view full) --- 564 kmem_free(pag); 565 for (; index > first_initialised; index--) { 566 pag = radix_tree_delete(&mp->m_perag_tree, index); 567 kmem_free(pag); 568 } 569 return error; 570} 571 |
572static void 573xfs_sb_quota_from_disk(struct xfs_sb *sbp) 574{ 575 if (sbp->sb_qflags & XFS_OQUOTA_ENFD) 576 sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ? 577 XFS_PQUOTA_ENFD : XFS_GQUOTA_ENFD; 578 if (sbp->sb_qflags & XFS_OQUOTA_CHKD) 579 sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ? 580 XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD; 581 sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD); 582} 583 |
|
562void 563xfs_sb_from_disk( 564 struct xfs_sb *to, 565 xfs_dsb_t *from) 566{ 567 to->sb_magicnum = be32_to_cpu(from->sb_magicnum); 568 to->sb_blocksize = be32_to_cpu(from->sb_blocksize); 569 to->sb_dblocks = be64_to_cpu(from->sb_dblocks); --- 45 unchanged lines hidden (view full) --- 615 to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat); 616 to->sb_features_log_incompat = 617 be32_to_cpu(from->sb_features_log_incompat); 618 to->sb_pad = 0; 619 to->sb_pquotino = be64_to_cpu(from->sb_pquotino); 620 to->sb_lsn = be64_to_cpu(from->sb_lsn); 621} 622 | 584void 585xfs_sb_from_disk( 586 struct xfs_sb *to, 587 xfs_dsb_t *from) 588{ 589 to->sb_magicnum = be32_to_cpu(from->sb_magicnum); 590 to->sb_blocksize = be32_to_cpu(from->sb_blocksize); 591 to->sb_dblocks = be64_to_cpu(from->sb_dblocks); --- 45 unchanged lines hidden (view full) --- 637 to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat); 638 to->sb_features_log_incompat = 639 be32_to_cpu(from->sb_features_log_incompat); 640 to->sb_pad = 0; 641 to->sb_pquotino = be64_to_cpu(from->sb_pquotino); 642 to->sb_lsn = be64_to_cpu(from->sb_lsn); 643} 644 |
645static inline void 646xfs_sb_quota_to_disk( 647 xfs_dsb_t *to, 648 xfs_sb_t *from, 649 __int64_t *fields) 650{ 651 __uint16_t qflags = from->sb_qflags; 652 653 if (*fields & XFS_SB_QFLAGS) { 654 /* 655 * The in-core version of sb_qflags do not have 656 * XFS_OQUOTA_* flags, whereas the on-disk version 657 * does. So, convert incore XFS_{PG}QUOTA_* flags 658 * to on-disk XFS_OQUOTA_* flags. 659 */ 660 qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD | 661 XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD); 662 663 if (from->sb_qflags & 664 (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD)) 665 qflags |= XFS_OQUOTA_ENFD; 666 if (from->sb_qflags & 667 (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) 668 qflags |= XFS_OQUOTA_CHKD; 669 to->sb_qflags = cpu_to_be16(qflags); 670 *fields &= ~XFS_SB_QFLAGS; 671 } 672} 673 |
|
623/* 624 * Copy in core superblock to ondisk one. 625 * 626 * The fields argument is mask of superblock fields to copy. 627 */ 628void 629xfs_sb_to_disk( 630 xfs_dsb_t *to, --- 5 unchanged lines hidden (view full) --- 636 xfs_sb_field_t f; 637 int first; 638 int size; 639 640 ASSERT(fields); 641 if (!fields) 642 return; 643 | 674/* 675 * Copy in core superblock to ondisk one. 676 * 677 * The fields argument is mask of superblock fields to copy. 678 */ 679void 680xfs_sb_to_disk( 681 xfs_dsb_t *to, --- 5 unchanged lines hidden (view full) --- 687 xfs_sb_field_t f; 688 int first; 689 int size; 690 691 ASSERT(fields); 692 if (!fields) 693 return; 694 |
695 xfs_sb_quota_to_disk(to, from, &fields); |
|
644 while (fields) { 645 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); 646 first = xfs_sb_info[f].offset; 647 size = xfs_sb_info[f + 1].offset - first; 648 649 ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); 650 651 if (size == 1 || xfs_sb_info[f].type == 1) { --- 18 unchanged lines hidden (view full) --- 670 } 671 672 fields &= ~(1LL << f); 673 } 674} 675 676static int 677xfs_sb_verify( | 696 while (fields) { 697 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); 698 first = xfs_sb_info[f].offset; 699 size = xfs_sb_info[f + 1].offset - first; 700 701 ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); 702 703 if (size == 1 || xfs_sb_info[f].type == 1) { --- 18 unchanged lines hidden (view full) --- 722 } 723 724 fields &= ~(1LL << f); 725 } 726} 727 728static int 729xfs_sb_verify( |
678 struct xfs_buf *bp) | 730 struct xfs_buf *bp, 731 bool check_version) |
679{ 680 struct xfs_mount *mp = bp->b_target->bt_mount; 681 struct xfs_sb sb; 682 683 xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp)); 684 685 /* 686 * Only check the in progress field for the primary superblock as 687 * mkfs.xfs doesn't clear it from secondary superblocks. 688 */ | 732{ 733 struct xfs_mount *mp = bp->b_target->bt_mount; 734 struct xfs_sb sb; 735 736 xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp)); 737 738 /* 739 * Only check the in progress field for the primary superblock as 740 * mkfs.xfs doesn't clear it from secondary superblocks. 741 */ |
689 return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR); | 742 return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, 743 check_version); |
690} 691 692/* 693 * If the superblock has the CRC feature bit set or the CRC field is non-null, 694 * check that the CRC is valid. We check the CRC field is non-null because a 695 * single bit error could clear the feature bit and unused parts of the 696 * superblock are supposed to be zero. Hence a non-null crc field indicates that 697 * we've potentially lost a feature bit and we should check it anyway. --- 16 unchanged lines hidden (view full) --- 714 dsb->sb_crc != 0)) { 715 716 if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize), 717 offsetof(struct xfs_sb, sb_crc))) { 718 error = EFSCORRUPTED; 719 goto out_error; 720 } 721 } | 744} 745 746/* 747 * If the superblock has the CRC feature bit set or the CRC field is non-null, 748 * check that the CRC is valid. We check the CRC field is non-null because a 749 * single bit error could clear the feature bit and unused parts of the 750 * superblock are supposed to be zero. Hence a non-null crc field indicates that 751 * we've potentially lost a feature bit and we should check it anyway. --- 16 unchanged lines hidden (view full) --- 768 dsb->sb_crc != 0)) { 769 770 if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize), 771 offsetof(struct xfs_sb, sb_crc))) { 772 error = EFSCORRUPTED; 773 goto out_error; 774 } 775 } |
722 error = xfs_sb_verify(bp); | 776 error = xfs_sb_verify(bp, true); |
723 724out_error: 725 if (error) { 726 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); 727 xfs_buf_ioerror(bp, error); 728 } 729} 730 --- 22 unchanged lines hidden (view full) --- 753static void 754xfs_sb_write_verify( 755 struct xfs_buf *bp) 756{ 757 struct xfs_mount *mp = bp->b_target->bt_mount; 758 struct xfs_buf_log_item *bip = bp->b_fspriv; 759 int error; 760 | 777 778out_error: 779 if (error) { 780 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); 781 xfs_buf_ioerror(bp, error); 782 } 783} 784 --- 22 unchanged lines hidden (view full) --- 807static void 808xfs_sb_write_verify( 809 struct xfs_buf *bp) 810{ 811 struct xfs_mount *mp = bp->b_target->bt_mount; 812 struct xfs_buf_log_item *bip = bp->b_fspriv; 813 int error; 814 |
761 error = xfs_sb_verify(bp); | 815 error = xfs_sb_verify(bp, false); |
762 if (error) { 763 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); 764 xfs_buf_ioerror(bp, error); 765 return; 766 } 767 768 if (!xfs_sb_version_hascrc(&mp->m_sb)) 769 return; --- 56 unchanged lines hidden (view full) --- 826 goto release_buf; 827 } 828 829 /* 830 * Initialize the mount structure from the superblock. 831 */ 832 xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp)); 833 | 816 if (error) { 817 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); 818 xfs_buf_ioerror(bp, error); 819 return; 820 } 821 822 if (!xfs_sb_version_hascrc(&mp->m_sb)) 823 return; --- 56 unchanged lines hidden (view full) --- 880 goto release_buf; 881 } 882 883 /* 884 * Initialize the mount structure from the superblock. 885 */ 886 xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp)); 887 |
888 xfs_sb_quota_from_disk(&mp->m_sb); |
|
834 /* 835 * We must be able to do sector-sized and sector-aligned IO. 836 */ 837 if (sector_size > sbp->sb_sectsize) { 838 if (loud) 839 xfs_warn(mp, "device supports %u byte sectors (not %u)", 840 sector_size, sbp->sb_sectsize); 841 error = ENOSYS; --- 136 unchanged lines hidden (view full) --- 978 979 if (mp->m_dalign) { 980 /* 981 * If stripe unit and stripe width are not multiples 982 * of the fs blocksize turn off alignment. 983 */ 984 if ((BBTOB(mp->m_dalign) & mp->m_blockmask) || 985 (BBTOB(mp->m_swidth) & mp->m_blockmask)) { | 889 /* 890 * We must be able to do sector-sized and sector-aligned IO. 891 */ 892 if (sector_size > sbp->sb_sectsize) { 893 if (loud) 894 xfs_warn(mp, "device supports %u byte sectors (not %u)", 895 sector_size, sbp->sb_sectsize); 896 error = ENOSYS; --- 136 unchanged lines hidden (view full) --- 1033 1034 if (mp->m_dalign) { 1035 /* 1036 * If stripe unit and stripe width are not multiples 1037 * of the fs blocksize turn off alignment. 1038 */ 1039 if ((BBTOB(mp->m_dalign) & mp->m_blockmask) || 1040 (BBTOB(mp->m_swidth) & mp->m_blockmask)) { |
986 if (mp->m_flags & XFS_MOUNT_RETERR) { 987 xfs_warn(mp, "alignment check failed: " 988 "(sunit/swidth vs. blocksize)"); 989 return XFS_ERROR(EINVAL); 990 } 991 mp->m_dalign = mp->m_swidth = 0; | 1041 xfs_warn(mp, 1042 "alignment check failed: sunit/swidth vs. blocksize(%d)", 1043 sbp->sb_blocksize); 1044 return XFS_ERROR(EINVAL); |
992 } else { 993 /* 994 * Convert the stripe unit and width to FSBs. 995 */ 996 mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); 997 if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) { | 1045 } else { 1046 /* 1047 * Convert the stripe unit and width to FSBs. 1048 */ 1049 mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); 1050 if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) { |
998 if (mp->m_flags & XFS_MOUNT_RETERR) { 999 xfs_warn(mp, "alignment check failed: " 1000 "(sunit/swidth vs. ag size)"); 1001 return XFS_ERROR(EINVAL); 1002 } | |
1003 xfs_warn(mp, | 1051 xfs_warn(mp, |
1004 "stripe alignment turned off: sunit(%d)/swidth(%d) " 1005 "incompatible with agsize(%d)", 1006 mp->m_dalign, mp->m_swidth, 1007 sbp->sb_agblocks); 1008 1009 mp->m_dalign = 0; 1010 mp->m_swidth = 0; | 1052 "alignment check failed: sunit/swidth vs. agsize(%d)", 1053 sbp->sb_agblocks); 1054 return XFS_ERROR(EINVAL); |
1011 } else if (mp->m_dalign) { 1012 mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); 1013 } else { | 1055 } else if (mp->m_dalign) { 1056 mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); 1057 } else { |
1014 if (mp->m_flags & XFS_MOUNT_RETERR) { 1015 xfs_warn(mp, "alignment check failed: " 1016 "sunit(%d) less than bsize(%d)", 1017 mp->m_dalign, 1018 mp->m_blockmask +1); 1019 return XFS_ERROR(EINVAL); 1020 } 1021 mp->m_swidth = 0; | 1058 xfs_warn(mp, 1059 "alignment check failed: sunit(%d) less than bsize(%d)", 1060 mp->m_dalign, sbp->sb_blocksize); 1061 return XFS_ERROR(EINVAL); |
1022 } 1023 } 1024 1025 /* 1026 * Update superblock with new values 1027 * and log changes 1028 */ 1029 if (xfs_sb_version_hasdalign(sbp)) { 1030 if (sbp->sb_unit != mp->m_dalign) { 1031 sbp->sb_unit = mp->m_dalign; 1032 mp->m_update_flags |= XFS_SB_UNIT; 1033 } 1034 if (sbp->sb_width != mp->m_swidth) { 1035 sbp->sb_width = mp->m_swidth; 1036 mp->m_update_flags |= XFS_SB_WIDTH; 1037 } | 1062 } 1063 } 1064 1065 /* 1066 * Update superblock with new values 1067 * and log changes 1068 */ 1069 if (xfs_sb_version_hasdalign(sbp)) { 1070 if (sbp->sb_unit != mp->m_dalign) { 1071 sbp->sb_unit = mp->m_dalign; 1072 mp->m_update_flags |= XFS_SB_UNIT; 1073 } 1074 if (sbp->sb_width != mp->m_swidth) { 1075 sbp->sb_width = mp->m_swidth; 1076 mp->m_update_flags |= XFS_SB_WIDTH; 1077 } |
1078 } else { 1079 xfs_warn(mp, 1080 "cannot change alignment: superblock does not support data alignment"); 1081 return XFS_ERROR(EINVAL); |
|
1038 } 1039 } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && 1040 xfs_sb_version_hasdalign(&mp->m_sb)) { 1041 mp->m_dalign = sbp->sb_unit; 1042 mp->m_swidth = sbp->sb_width; 1043 } 1044 1045 return 0; --- 1612 unchanged lines hidden --- | 1082 } 1083 } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && 1084 xfs_sb_version_hasdalign(&mp->m_sb)) { 1085 mp->m_dalign = sbp->sb_unit; 1086 mp->m_swidth = sbp->sb_width; 1087 } 1088 1089 return 0; --- 1612 unchanged lines hidden --- |