You can add my: Acked-by: Andreas Dilger <adilger@xxxxxxxxx> On 2010-08-12, at 16:29, Joel Becker wrote: > On Thu, Aug 12, 2010 at 03:32:27PM -0600, Andreas Dilger wrote: >>> If I change the BUG_ON()s to -EINVAL, does that work? Or do you >>> have some way you'd like to allow non-pagecache filesystems to use this >>> as well? >> >> That's probably fine for now. If anyone complains, we can always change it later, since they can't possibly depend on this function yet... > > How's this: > >> From f988b04c58039ae9a65fea537656088ea56a8072 Mon Sep 17 00:00:00 2001 >> From: Patrick J. LoPresti <lopresti@xxxxxxxxx> > Date: Thu, 22 Jul 2010 15:03:41 -0700 > Subject: [PATCH] ext3/ext4: Factor out disk addressability check > > As part of adding support for OCFS2 to mount huge volumes, we need to > check that the sector_t and page cache of the system are capable of > addressing the entire volume. > > An identical check already appears in ext3 and ext4. This patch moves > the addressability check into its own function in fs/libfs.c and > modifies ext3 and ext4 to invoke it. > > [Edited to -EINVAL instead of BUG_ON() for bad blocksize_bits -- Joel] > > Signed-off-by: Patrick LoPresti <lopresti@xxxxxxxxx> > Cc: linux-ext4@xxxxxxxxxxxxxxx > Signed-off-by: Joel Becker <joel.becker@xxxxxxxxxx> > --- > fs/ext3/super.c | 4 ++-- > fs/ext4/super.c | 8 +++----- > fs/libfs.c | 29 +++++++++++++++++++++++++++++ > include/linux/fs.h | 2 ++ > 4 files changed, 36 insertions(+), 7 deletions(-) > > diff --git a/fs/ext3/super.c b/fs/ext3/super.c > index 6c953bb..d0643db 100644 > --- a/fs/ext3/super.c > +++ b/fs/ext3/super.c > @@ -1862,8 +1862,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) > goto failed_mount; > } > > - if (le32_to_cpu(es->s_blocks_count) > > - (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { > + if (generic_check_addressable(sb->s_blocksize_bits, > + le32_to_cpu(es->s_blocks_count))) { > ext3_msg(sb, KERN_ERR, > "error: filesystem is too large to mount safely"); > if (sizeof(sector_t) < 8) > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index e72d323..e03a7d2 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -2706,15 +2706,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) > * Test whether we have more sectors than will fit in sector_t, > * and whether the max offset is addressable by the page cache. > */ > - if ((ext4_blocks_count(es) > > - (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) || > - (ext4_blocks_count(es) > > - (pgoff_t)(~0ULL) >> (PAGE_CACHE_SHIFT - sb->s_blocksize_bits))) { > + ret = generic_check_addressable(sb->s_blocksize_bits, > + ext4_blocks_count(es)); > + if (ret) { > ext4_msg(sb, KERN_ERR, "filesystem" > " too large to mount safely on this system"); > if (sizeof(sector_t) < 8) > ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); > - ret = -EFBIG; > goto failed_mount; > } > > diff --git a/fs/libfs.c b/fs/libfs.c > index dcaf972..f099566 100644 > --- a/fs/libfs.c > +++ b/fs/libfs.c > @@ -955,6 +955,35 @@ int generic_file_fsync(struct file *file, int datasync) > } > EXPORT_SYMBOL(generic_file_fsync); > > +/** > + * generic_check_addressable - Check addressability of file system > + * @blocksize_bits: log of file system block size > + * @num_blocks: number of blocks in file system > + * > + * Determine whether a file system with @num_blocks blocks (and a > + * block size of 2**@blocksize_bits) is addressable by the sector_t > + * and page cache of the system. Return 0 if so and -EFBIG otherwise. > + */ > +int generic_check_addressable(unsigned blocksize_bits, u64 num_blocks) > +{ > + u64 last_fs_block = num_blocks - 1; > + > + if (unlikely(num_blocks == 0)) > + return 0; > + > + if ((blocksize_bits < 9) || (blocksize_bits > PAGE_CACHE_SHIFT)) > + return -EINVAL; > + > + if ((last_fs_block > > + (sector_t)(~0ULL) >> (blocksize_bits - 9)) || > + (last_fs_block > > + (pgoff_t)(~0ULL) >> (PAGE_CACHE_SHIFT - blocksize_bits))) { > + return -EFBIG; > + } > + return 0; > +} > +EXPORT_SYMBOL(generic_check_addressable); > + > /* > * No-op implementation of ->fsync for in-memory filesystems. > */ > diff --git a/include/linux/fs.h b/include/linux/fs.h > index e5106e4..7644248 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -2414,6 +2414,8 @@ extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, > > extern int generic_file_fsync(struct file *, int); > > +extern int generic_check_addressable(unsigned, u64); > + > #ifdef CONFIG_MIGRATION > extern int buffer_migrate_page(struct address_space *, > struct page *, struct page *); > -- > 1.7.1 > > > -- > > "Friends may come and go, but enemies accumulate." > - Thomas Jones > > Joel Becker > Consulting Software Developer > Oracle > E-mail: joel.becker@xxxxxxxxxx > Phone: (650) 506-8127 > -- > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html Cheers, Andreas -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html