aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext3/super.c4
-rw-r--r--fs/ext4/super.c8
-rw-r--r--fs/libfs.c29
-rw-r--r--include/linux/fs.h2
4 files changed, 36 insertions, 7 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 5dbf4dba03c4..a367dd044280 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1849,8 +1849,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1849 goto failed_mount; 1849 goto failed_mount;
1850 } 1850 }
1851 1851
1852 if (le32_to_cpu(es->s_blocks_count) > 1852 if (generic_check_addressable(sb->s_blocksize_bits,
1853 (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { 1853 le32_to_cpu(es->s_blocks_count))) {
1854 ext3_msg(sb, KERN_ERR, 1854 ext3_msg(sb, KERN_ERR,
1855 "error: filesystem is too large to mount safely"); 1855 "error: filesystem is too large to mount safely");
1856 if (sizeof(sector_t) < 8) 1856 if (sizeof(sector_t) < 8)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 26147746c272..7f47c366bf15 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2831,15 +2831,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2831 * Test whether we have more sectors than will fit in sector_t, 2831 * Test whether we have more sectors than will fit in sector_t,
2832 * and whether the max offset is addressable by the page cache. 2832 * and whether the max offset is addressable by the page cache.
2833 */ 2833 */
2834 if ((ext4_blocks_count(es) > 2834 ret = generic_check_addressable(sb->s_blocksize_bits,
2835 (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) || 2835 ext4_blocks_count(es));
2836 (ext4_blocks_count(es) > 2836 if (ret) {
2837 (pgoff_t)(~0ULL) >> (PAGE_CACHE_SHIFT - sb->s_blocksize_bits))) {
2838 ext4_msg(sb, KERN_ERR, "filesystem" 2837 ext4_msg(sb, KERN_ERR, "filesystem"
2839 " too large to mount safely on this system"); 2838 " too large to mount safely on this system");
2840 if (sizeof(sector_t) < 8) 2839 if (sizeof(sector_t) < 8)
2841 ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); 2840 ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled");
2842 ret = -EFBIG;
2843 goto failed_mount; 2841 goto failed_mount;
2844 } 2842 }
2845 2843
diff --git a/fs/libfs.c b/fs/libfs.c
index 0a9da95317f7..8debe7b33769 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -913,6 +913,35 @@ int generic_file_fsync(struct file *file, int datasync)
913} 913}
914EXPORT_SYMBOL(generic_file_fsync); 914EXPORT_SYMBOL(generic_file_fsync);
915 915
916/**
917 * generic_check_addressable - Check addressability of file system
918 * @blocksize_bits: log of file system block size
919 * @num_blocks: number of blocks in file system
920 *
921 * Determine whether a file system with @num_blocks blocks (and a
922 * block size of 2**@blocksize_bits) is addressable by the sector_t
923 * and page cache of the system. Return 0 if so and -EFBIG otherwise.
924 */
925int generic_check_addressable(unsigned blocksize_bits, u64 num_blocks)
926{
927 u64 last_fs_block = num_blocks - 1;
928
929 if (unlikely(num_blocks == 0))
930 return 0;
931
932 if ((blocksize_bits < 9) || (blocksize_bits > PAGE_CACHE_SHIFT))
933 return -EINVAL;
934
935 if ((last_fs_block >
936 (sector_t)(~0ULL) >> (blocksize_bits - 9)) ||
937 (last_fs_block >
938 (pgoff_t)(~0ULL) >> (PAGE_CACHE_SHIFT - blocksize_bits))) {
939 return -EFBIG;
940 }
941 return 0;
942}
943EXPORT_SYMBOL(generic_check_addressable);
944
916/* 945/*
917 * No-op implementation of ->fsync for in-memory filesystems. 946 * No-op implementation of ->fsync for in-memory filesystems.
918 */ 947 */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 76041b614758..1a759f40ab9e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2374,6 +2374,8 @@ extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
2374 2374
2375extern int generic_file_fsync(struct file *, int); 2375extern int generic_file_fsync(struct file *, int);
2376 2376
2377extern int generic_check_addressable(unsigned, u64);
2378
2377#ifdef CONFIG_MIGRATION 2379#ifdef CONFIG_MIGRATION
2378extern int buffer_migrate_page(struct address_space *, 2380extern int buffer_migrate_page(struct address_space *,
2379 struct page *, struct page *); 2381 struct page *, struct page *);