diff options
author | Christoph Hellwig <hch@tuxera.com> | 2011-09-15 10:48:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-09-15 09:03:17 -0700 |
commit | f1fcd9f0e96d12498afb5543107f560f196cfcf3 (patch) | |
tree | 0444192f838dc8a71b0f6d1270d979a337c6ef6f /fs | |
parent | f588c960fcaa6fa8bf82930bb819c9aca4eb9347 (diff) | |
download | lwn-f1fcd9f0e96d12498afb5543107f560f196cfcf3.tar.gz lwn-f1fcd9f0e96d12498afb5543107f560f196cfcf3.zip |
hfsplus: fix filesystem size checks
generic_check_addressable can't deal with hfsplus's larger than page
size allocation blocks, so simply opencode the checks that we actually
need in hfsplus_fill_super.
Signed-off-by: Christoph Hellwig <hch@tuxera.com>
Reported-by: Pavel Ivanov <paivanof@gmail.com>
Tested-by: Pavel Ivanov <paivanof@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/hfsplus/super.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index cadbb8c81887..d24a9b666a23 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -344,6 +344,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) struct inode *root, *inode; struct qstr str; struct nls_table *nls = NULL; + u64 last_fs_block, last_fs_page; int err; err = -EINVAL; @@ -399,9 +400,13 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) if (!sbi->rsrc_clump_blocks) sbi->rsrc_clump_blocks = 1; - err = generic_check_addressable(sbi->alloc_blksz_shift, - sbi->total_blocks); - if (err) { + err = -EFBIG; + last_fs_block = sbi->total_blocks - 1; + last_fs_page = (last_fs_block << sbi->alloc_blksz_shift) >> + PAGE_CACHE_SHIFT; + + if ((last_fs_block > (sector_t)(~0ULL) >> (sbi->alloc_blksz_shift - 9)) || + (last_fs_page > (pgoff_t)(~0ULL))) { printk(KERN_ERR "hfs: filesystem size too large.\n"); goto out_free_vhdr; } |