aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJie Liu <jeff.liu@oracle.com>2013-08-12 06:50:03 -0400
committerBen Myers <bpm@sgi.com>2013-08-12 18:50:35 -0400
commit3e7b91cf8c19d89e55df5f05e3010446dbdaba77 (patch)
tree312bb2f9b7b503bb0fce0d156c18ff40dab89cba
parent5a96a94547fe345467c2ab2ec51cb3fade355bd9 (diff)
xfs: Validate log space at mount time
Validate log space during log mount stage, the underlying function will drop a warning message via syslog in critical level if the log space is too small or too large. [ dchinner: For CRC enable filesystems, abort the mounting of the filesystem as mkfs should never make a log too small for the given filesystem configuration. ] [ dchinner: make a note of the fact that the log size limits in block counts are in units of filesystem blocks, not basic blocks. ] Signed-off-by: Jie Liu <jeff.liu@oracle.com> Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
-rw-r--r--fs/xfs/xfs_fs.h4
-rw-r--r--fs/xfs/xfs_log.c47
2 files changed, 49 insertions, 2 deletions
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 74b24b2ecd07..53e33c26f53e 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -240,7 +240,9 @@ typedef struct xfs_fsop_resblks {
240 240
241 241
242/* 242/*
243 * Minimum and maximum sizes need for growth checks 243 * Minimum and maximum sizes need for growth checks.
244 *
245 * Block counts are in units of filesystem blocks, not basic blocks.
244 */ 246 */
245#define XFS_MIN_AG_BLOCKS 64 247#define XFS_MIN_AG_BLOCKS 64
246#define XFS_MIN_LOG_BLOCKS 512ULL 248#define XFS_MIN_LOG_BLOCKS 512ULL
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 704f0959e9c6..b5703ccd533e 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -614,7 +614,8 @@ xfs_log_mount(
614 xfs_daddr_t blk_offset, 614 xfs_daddr_t blk_offset,
615 int num_bblks) 615 int num_bblks)
616{ 616{
617 int error; 617 int error = 0;
618 int min_logfsbs;
618 619
619 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) 620 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
620 xfs_notice(mp, "Mounting Filesystem"); 621 xfs_notice(mp, "Mounting Filesystem");
@@ -631,6 +632,50 @@ xfs_log_mount(
631 } 632 }
632 633
633 /* 634 /*
635 * Validate the given log space and drop a critical message via syslog
636 * if the log size is too small that would lead to some unexpected
637 * situations in transaction log space reservation stage.
638 *
639 * Note: we can't just reject the mount if the validation fails. This
640 * would mean that people would have to downgrade their kernel just to
641 * remedy the situation as there is no way to grow the log (short of
642 * black magic surgery with xfs_db).
643 *
644 * We can, however, reject mounts for CRC format filesystems, as the
645 * mkfs binary being used to make the filesystem should never create a
646 * filesystem with a log that is too small.
647 */
648 min_logfsbs = xfs_log_calc_minimum_size(mp);
649
650 if (mp->m_sb.sb_logblocks < min_logfsbs) {
651 xfs_warn(mp,
652 "Log size %d blocks too small, minimum size is %d blocks",
653 mp->m_sb.sb_logblocks, min_logfsbs);
654 error = EINVAL;
655 } else if (mp->m_sb.sb_logblocks > XFS_MAX_LOG_BLOCKS) {
656 xfs_warn(mp,
657 "Log size %d blocks too large, maximum size is %lld blocks",
658 mp->m_sb.sb_logblocks, XFS_MAX_LOG_BLOCKS);
659 error = EINVAL;
660 } else if (XFS_FSB_TO_B(mp, mp->m_sb.sb_logblocks) > XFS_MAX_LOG_BYTES) {
661 xfs_warn(mp,
662 "log size %lld bytes too large, maximum size is %lld bytes",
663 XFS_FSB_TO_B(mp, mp->m_sb.sb_logblocks),
664 XFS_MAX_LOG_BYTES);
665 error = EINVAL;
666 }
667 if (error) {
668 if (xfs_sb_version_hascrc(&mp->m_sb)) {
669 xfs_crit(mp, "AAIEEE! Log failed size checks. Abort!");
670 ASSERT(0);
671 goto out_free_log;
672 }
673 xfs_crit(mp,
674"Log size out of supported range. Continuing onwards, but if log hangs are\n"
675"experienced then please report this message in the bug report.");
676 }
677
678 /*
634 * Initialize the AIL now we have a log. 679 * Initialize the AIL now we have a log.
635 */ 680 */
636 error = xfs_trans_ail_init(mp); 681 error = xfs_trans_ail_init(mp);