diff options
author | Jie Liu <jeff.liu@oracle.com> | 2013-08-12 06:50:03 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2013-08-12 18:50:35 -0400 |
commit | 3e7b91cf8c19d89e55df5f05e3010446dbdaba77 (patch) | |
tree | 312bb2f9b7b503bb0fce0d156c18ff40dab89cba | |
parent | 5a96a94547fe345467c2ab2ec51cb3fade355bd9 (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.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 47 |
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); |