diff options
-rw-r--r-- | fs/ocfs2/super.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index fa1be1b304d1..47415398d56a 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -1990,6 +1990,36 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu | |||
1990 | return 0; | 1990 | return 0; |
1991 | } | 1991 | } |
1992 | 1992 | ||
1993 | /* Make sure entire volume is addressable by our journal. Requires | ||
1994 | osb_clusters_at_boot to be valid and for the journal to have been | ||
1995 | initialized by ocfs2_journal_init(). */ | ||
1996 | static int ocfs2_journal_addressable(struct ocfs2_super *osb) | ||
1997 | { | ||
1998 | int status = 0; | ||
1999 | u64 max_block = | ||
2000 | ocfs2_clusters_to_blocks(osb->sb, | ||
2001 | osb->osb_clusters_at_boot) - 1; | ||
2002 | |||
2003 | /* 32-bit block number is always OK. */ | ||
2004 | if (max_block <= (u32)~0ULL) | ||
2005 | goto out; | ||
2006 | |||
2007 | /* Volume is "huge", so see if our journal is new enough to | ||
2008 | support it. */ | ||
2009 | if (!(OCFS2_HAS_COMPAT_FEATURE(osb->sb, | ||
2010 | OCFS2_FEATURE_COMPAT_JBD2_SB) && | ||
2011 | jbd2_journal_check_used_features(osb->journal->j_journal, 0, 0, | ||
2012 | JBD2_FEATURE_INCOMPAT_64BIT))) { | ||
2013 | mlog(ML_ERROR, "The journal cannot address the entire volume. " | ||
2014 | "Enable the 'block64' journal option with tunefs.ocfs2"); | ||
2015 | status = -EFBIG; | ||
2016 | goto out; | ||
2017 | } | ||
2018 | |||
2019 | out: | ||
2020 | return status; | ||
2021 | } | ||
2022 | |||
1993 | static int ocfs2_initialize_super(struct super_block *sb, | 2023 | static int ocfs2_initialize_super(struct super_block *sb, |
1994 | struct buffer_head *bh, | 2024 | struct buffer_head *bh, |
1995 | int sector_size, | 2025 | int sector_size, |
@@ -2002,6 +2032,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
2002 | struct ocfs2_journal *journal; | 2032 | struct ocfs2_journal *journal; |
2003 | __le32 uuid_net_key; | 2033 | __le32 uuid_net_key; |
2004 | struct ocfs2_super *osb; | 2034 | struct ocfs2_super *osb; |
2035 | u64 total_blocks; | ||
2005 | 2036 | ||
2006 | mlog_entry_void(); | 2037 | mlog_entry_void(); |
2007 | 2038 | ||
@@ -2214,11 +2245,15 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
2214 | goto bail; | 2245 | goto bail; |
2215 | } | 2246 | } |
2216 | 2247 | ||
2217 | if (ocfs2_clusters_to_blocks(osb->sb, le32_to_cpu(di->i_clusters) - 1) | 2248 | total_blocks = ocfs2_clusters_to_blocks(osb->sb, |
2218 | > (u32)~0UL) { | 2249 | le32_to_cpu(di->i_clusters)); |
2219 | mlog(ML_ERROR, "Volume might try to write to blocks beyond " | 2250 | |
2220 | "what jbd can address in 32 bits.\n"); | 2251 | status = generic_check_addressable(osb->sb->s_blocksize_bits, |
2221 | status = -EINVAL; | 2252 | total_blocks); |
2253 | if (status) { | ||
2254 | mlog(ML_ERROR, "Volume too large " | ||
2255 | "to mount safely on this system"); | ||
2256 | status = -EFBIG; | ||
2222 | goto bail; | 2257 | goto bail; |
2223 | } | 2258 | } |
2224 | 2259 | ||
@@ -2380,6 +2415,12 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) | |||
2380 | goto finally; | 2415 | goto finally; |
2381 | } | 2416 | } |
2382 | 2417 | ||
2418 | /* Now that journal has been initialized, check to make sure | ||
2419 | entire volume is addressable. */ | ||
2420 | status = ocfs2_journal_addressable(osb); | ||
2421 | if (status) | ||
2422 | goto finally; | ||
2423 | |||
2383 | /* If the journal was unmounted cleanly then we don't want to | 2424 | /* If the journal was unmounted cleanly then we don't want to |
2384 | * recover anything. Otherwise, journal_load will do that | 2425 | * recover anything. Otherwise, journal_load will do that |
2385 | * dirty work for us :) */ | 2426 | * dirty work for us :) */ |