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 :) */ |
