[Ocfs2-devel] Large (> 16TiB) volumes revisited
Patrick J. LoPresti
lopresti at gmail.com
Thu Jun 24 16:53:21 PDT 2010
Well, the good news is I am testing my patch.
The bad news is that it crashes in jbd2_journal_check_used_features().
I think the problem is that ocfs2_initialize_super() is called
relatively early in ocfs2_fill_super(). Only later does it call
ocfs2_mount_volume(), which calls ocfs2_check_volume(), which finally
calls ocfs2_journal_init()... Which sets up the data structure that I
need to check.
I can move ocfs2_check_addressable() to ocfs2_check_volume() after it
calls ocfs2_journal_init(); arguably, this even makes sense ("check
volume"). But then I am not sure how to get hold of the ocfs2_dinode
pointer that is used to compute the cluster and block count.
Suggestions?
- Pat
On Thu, Jun 24, 2010 at 9:53 AM, Patrick J. LoPresti <lopresti at gmail.com> wrote:
> On Wed, Jun 23, 2010 at 5:55 PM, Joel Becker <Joel.Becker at oracle.com> wrote:
>> These don't need to be const. Sure, they don't change, but
>> you're not signifying anything special with them (like passing them to a
>> subfunction or something).
>
> Well, I am signifying that I do not intend to change them... "const"
> is just a compile-time assertion, and like all compile-time
> assertions, it has no effect on the generated code. So the only
> issues are readability and maintainability. In my experience, using
> "const" consistently helps with both. But I know it is not really the
> Linux Way.
>
>> And you don't really need the clusters temporary.
>
> Here again, the generated code is identical, so the question is human
> consumption. I find that factoring out sub-expressions and giving
> them meaningful names makes code easier to read and to understand.
> (Not to mention taking two lines instead of three.) For example, I
> believe my version is less likely to wind up with the "-1" in the
> wrong place. :-)
>
> But your house = your rules. Updated patch follows. I will try to
> find time to test today or tomorrow.
>
> Thanks!
>
> - Pat
>
>
> diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
> index 0eaa929..d32c800 100644
> --- a/fs/ocfs2/super.c
> +++ b/fs/ocfs2/super.c
> @@ -1991,6 +1991,46 @@ static int ocfs2_setup_osb_uuid(struct
> ocfs2_super *osb, const unsigned char *uu
> return 0;
> }
>
> +/* Check to make sure entire volume is addressable on this system. */
> +static int ocfs2_check_addressable(struct ocfs2_super *osb,
> + struct ocfs2_dinode *di)
> +{
> + int status = 0;
> + u64 max_block =
> + ocfs2_clusters_to_blocks(osb->sb,
> + le32_to_cpu(di->i_clusters)) - 1;
> +
> + /* Absolute addressability check (borrowed from ext4/super.c) */
> + if ((max_block >
> + (sector_t)(~0LL) >> (osb->sb->s_blocksize_bits - 9)) ||
> + (max_block > (pgoff_t)(~0LL) >> (PAGE_CACHE_SHIFT -
> + osb->sb->s_blocksize_bits))) {
> + mlog(ML_ERROR, "Volume too large "
> + "to mount safely on this system");
> + status = -EFBIG;
> + goto out;
> + }
> +
> + /* 32-bit block number is always OK. */
> + if (max_block <= (u32)~0UL)
> + 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,
> struct buffer_head *bh,
> int sector_size,
> @@ -2215,13 +2255,9 @@ static int ocfs2_initialize_super(struct super_block *sb,
> goto bail;
> }
>
> - if (ocfs2_clusters_to_blocks(osb->sb, le32_to_cpu(di->i_clusters) - 1)
> - > (u32)~0UL) {
> - mlog(ML_ERROR, "Volume might try to write to blocks beyond "
> - "what jbd can address in 32 bits.\n");
> - status = -EINVAL;
> + status = ocfs2_check_addressable(osb, di);
> + if (status)
> goto bail;
> - }
>
> if (ocfs2_setup_osb_uuid(osb, di->id2.i_super.s_uuid,
> sizeof(di->id2.i_super.s_uuid))) {
>
More information about the Ocfs2-devel
mailing list