diff options
-rw-r--r-- | fs/ext3/super.c | 4 | ||||
-rw-r--r-- | fs/ext4/super.c | 8 | ||||
-rw-r--r-- | fs/libfs.c | 29 | ||||
-rw-r--r-- | 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 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 | } |
914 | EXPORT_SYMBOL(generic_file_fsync); | 914 | EXPORT_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 | */ | ||
925 | int 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 | } | ||
943 | EXPORT_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 | ||
2375 | extern int generic_file_fsync(struct file *, int); | 2375 | extern int generic_file_fsync(struct file *, int); |
2376 | 2376 | ||
2377 | extern int generic_check_addressable(unsigned, u64); | ||
2378 | |||
2377 | #ifdef CONFIG_MIGRATION | 2379 | #ifdef CONFIG_MIGRATION |
2378 | extern int buffer_migrate_page(struct address_space *, | 2380 | extern int buffer_migrate_page(struct address_space *, |
2379 | struct page *, struct page *); | 2381 | struct page *, struct page *); |