aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c92
1 files changed, 66 insertions, 26 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index e8e310c05097..2b0ba3581656 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -336,6 +336,14 @@ xfs_mount_validate_sb(
336 return XFS_ERROR(EWRONGFS); 336 return XFS_ERROR(EWRONGFS);
337 } 337 }
338 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
339 /* 347 /*
340 * Version 5 superblock feature mask validation. Reject combinations the 348 * Version 5 superblock feature mask validation. Reject combinations the
341 * kernel cannot support up front before checking anything else. For 349 * kernel cannot support up front before checking anything else. For
@@ -561,6 +569,18 @@ out_unwind:
561 return error; 569 return error;
562} 570}
563 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
564void 584void
565xfs_sb_from_disk( 585xfs_sb_from_disk(
566 struct xfs_sb *to, 586 struct xfs_sb *to,
@@ -622,6 +642,35 @@ xfs_sb_from_disk(
622 to->sb_lsn = be64_to_cpu(from->sb_lsn); 642 to->sb_lsn = be64_to_cpu(from->sb_lsn);
623} 643}
624 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
625/* 674/*
626 * Copy in core superblock to ondisk one. 675 * Copy in core superblock to ondisk one.
627 * 676 *
@@ -643,6 +692,7 @@ xfs_sb_to_disk(
643 if (!fields) 692 if (!fields)
644 return; 693 return;
645 694
695 xfs_sb_quota_to_disk(to, from, &fields);
646 while (fields) { 696 while (fields) {
647 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); 697 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
648 first = xfs_sb_info[f].offset; 698 first = xfs_sb_info[f].offset;
@@ -835,6 +885,7 @@ reread:
835 */ 885 */
836 xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp)); 886 xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
837 887
888 xfs_sb_quota_from_disk(&mp->m_sb);
838 /* 889 /*
839 * We must be able to do sector-sized and sector-aligned IO. 890 * We must be able to do sector-sized and sector-aligned IO.
840 */ 891 */
@@ -987,42 +1038,27 @@ xfs_update_alignment(xfs_mount_t *mp)
987 */ 1038 */
988 if ((BBTOB(mp->m_dalign) & mp->m_blockmask) || 1039 if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
989 (BBTOB(mp->m_swidth) & mp->m_blockmask)) { 1040 (BBTOB(mp->m_swidth) & mp->m_blockmask)) {
990 if (mp->m_flags & XFS_MOUNT_RETERR) { 1041 xfs_warn(mp,
991 xfs_warn(mp, "alignment check failed: " 1042 "alignment check failed: sunit/swidth vs. blocksize(%d)",
992 "(sunit/swidth vs. blocksize)"); 1043 sbp->sb_blocksize);
993 return XFS_ERROR(EINVAL); 1044 return XFS_ERROR(EINVAL);
994 }
995 mp->m_dalign = mp->m_swidth = 0;
996 } else { 1045 } else {
997 /* 1046 /*
998 * Convert the stripe unit and width to FSBs. 1047 * Convert the stripe unit and width to FSBs.
999 */ 1048 */
1000 mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); 1049 mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
1001 if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) { 1050 if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {
1002 if (mp->m_flags & XFS_MOUNT_RETERR) {
1003 xfs_warn(mp, "alignment check failed: "
1004 "(sunit/swidth vs. ag size)");
1005 return XFS_ERROR(EINVAL);
1006 }
1007 xfs_warn(mp, 1051 xfs_warn(mp,
1008 "stripe alignment turned off: sunit(%d)/swidth(%d) " 1052 "alignment check failed: sunit/swidth vs. agsize(%d)",
1009 "incompatible with agsize(%d)", 1053 sbp->sb_agblocks);
1010 mp->m_dalign, mp->m_swidth, 1054 return XFS_ERROR(EINVAL);
1011 sbp->sb_agblocks);
1012
1013 mp->m_dalign = 0;
1014 mp->m_swidth = 0;
1015 } else if (mp->m_dalign) { 1055 } else if (mp->m_dalign) {
1016 mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); 1056 mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
1017 } else { 1057 } else {
1018 if (mp->m_flags & XFS_MOUNT_RETERR) { 1058 xfs_warn(mp,
1019 xfs_warn(mp, "alignment check failed: " 1059 "alignment check failed: sunit(%d) less than bsize(%d)",
1020 "sunit(%d) less than bsize(%d)", 1060 mp->m_dalign, sbp->sb_blocksize);
1021 mp->m_dalign, 1061 return XFS_ERROR(EINVAL);
1022 mp->m_blockmask +1);
1023 return XFS_ERROR(EINVAL);
1024 }
1025 mp->m_swidth = 0;
1026 } 1062 }
1027 } 1063 }
1028 1064
@@ -1039,6 +1075,10 @@ xfs_update_alignment(xfs_mount_t *mp)
1039 sbp->sb_width = mp->m_swidth; 1075 sbp->sb_width = mp->m_swidth;
1040 mp->m_update_flags |= XFS_SB_WIDTH; 1076 mp->m_update_flags |= XFS_SB_WIDTH;
1041 } 1077 }
1078 } else {
1079 xfs_warn(mp,
1080 "cannot change alignment: superblock does not support data alignment");
1081 return XFS_ERROR(EINVAL);
1042 } 1082 }
1043 } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && 1083 } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
1044 xfs_sb_version_hasdalign(&mp->m_sb)) { 1084 xfs_sb_version_hasdalign(&mp->m_sb)) {