提交 3bdb8efd 编写于 作者: P Patrick J. LoPresti 提交者: Joel Becker

OCFS2: Allow huge (> 16 TiB) volumes to mount

The OCFS2 developers have already done all of the hard work to allow
volumes larger than 16 TiB.  But there is still a "sanity check" in
fs/ocfs2/super.c that prevents the mounting of such volumes, even when
the cluster size and journal options would allow it.

This patch replaces that sanity check with a more sophisticated one to
mount a huge volume provided that (a) it is addressable by the raw
word/address size of the system (borrowing a test from ext4); (b) the
volume is using JBD2; and (c) the JBD2_FEATURE_INCOMPAT_64BIT flag is
set on the journal.

I factored out the sanity check into its own function.  I also moved it
from ocfs2_initialize_super() down to ocfs2_check_volume(); any earlier,
and the journal will not have been initialized yet.

This patch is one of a pair, and it depends on the other ("JBD2: Allow
feature checks before journal recovery").

I have tested this patch on small volumes, huge volumes, and huge
volumes without 64-bit block support in the journal.  All of them appear
to work or to fail gracefully, as appropriate.
Signed-off-by: NPatrick LoPresti <lopresti@gmail.com>
Signed-off-by: NJoel Becker <joel.becker@oracle.com>
上级 1113e1b5
...@@ -1990,6 +1990,36 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu ...@@ -1990,6 +1990,36 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu
return 0; return 0;
} }
/* Make sure entire volume is addressable by our journal. Requires
osb_clusters_at_boot to be valid and for the journal to have been
initialized by ocfs2_journal_init(). */
static int ocfs2_journal_addressable(struct ocfs2_super *osb)
{
int status = 0;
u64 max_block =
ocfs2_clusters_to_blocks(osb->sb,
osb->osb_clusters_at_boot) - 1;
/* 32-bit block number is always OK. */
if (max_block <= (u32)~0ULL)
goto out;
/* Volume is "huge", so see if our journal is new enough to
support it. */
if (!(OCFS2_HAS_COMPAT_FEATURE(osb->sb,
OCFS2_FEATURE_COMPAT_JBD2_SB) &&
jbd2_journal_check_used_features(osb->journal->j_journal, 0, 0,
JBD2_FEATURE_INCOMPAT_64BIT))) {
mlog(ML_ERROR, "The journal cannot address the entire volume. "
"Enable the 'block64' journal option with tunefs.ocfs2");
status = -EFBIG;
goto out;
}
out:
return status;
}
static int ocfs2_initialize_super(struct super_block *sb, static int ocfs2_initialize_super(struct super_block *sb,
struct buffer_head *bh, struct buffer_head *bh,
int sector_size, int sector_size,
...@@ -2002,6 +2032,7 @@ static int ocfs2_initialize_super(struct super_block *sb, ...@@ -2002,6 +2032,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
struct ocfs2_journal *journal; struct ocfs2_journal *journal;
__le32 uuid_net_key; __le32 uuid_net_key;
struct ocfs2_super *osb; struct ocfs2_super *osb;
u64 total_blocks;
mlog_entry_void(); mlog_entry_void();
...@@ -2214,11 +2245,15 @@ static int ocfs2_initialize_super(struct super_block *sb, ...@@ -2214,11 +2245,15 @@ static int ocfs2_initialize_super(struct super_block *sb,
goto bail; goto bail;
} }
if (ocfs2_clusters_to_blocks(osb->sb, le32_to_cpu(di->i_clusters) - 1) total_blocks = ocfs2_clusters_to_blocks(osb->sb,
> (u32)~0UL) { le32_to_cpu(di->i_clusters));
mlog(ML_ERROR, "Volume might try to write to blocks beyond "
"what jbd can address in 32 bits.\n"); status = generic_check_addressable(osb->sb->s_blocksize_bits,
status = -EINVAL; total_blocks);
if (status) {
mlog(ML_ERROR, "Volume too large "
"to mount safely on this system");
status = -EFBIG;
goto bail; goto bail;
} }
...@@ -2380,6 +2415,12 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) ...@@ -2380,6 +2415,12 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
goto finally; goto finally;
} }
/* Now that journal has been initialized, check to make sure
entire volume is addressable. */
status = ocfs2_journal_addressable(osb);
if (status)
goto finally;
/* If the journal was unmounted cleanly then we don't want to /* If the journal was unmounted cleanly then we don't want to
* recover anything. Otherwise, journal_load will do that * recover anything. Otherwise, journal_load will do that
* dirty work for us :) */ * dirty work for us :) */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册