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 ---