set_blocksize is changed to allow to specify a blocksize larger than a page. If that occurs then we switch the device to use compound pages. Signed-off-by: Christoph Lameter --- fs/block_dev.c | 22 +++++++++++++++------- fs/buffer.c | 2 +- fs/inode.c | 5 +++++ 3 files changed, 21 insertions(+), 8 deletions(-) Index: linux-2.6.21-rc7/fs/block_dev.c =================================================================== --- linux-2.6.21-rc7.orig/fs/block_dev.c 2007-04-23 23:13:16.000000000 -0700 +++ linux-2.6.21-rc7/fs/block_dev.c 2007-04-23 23:13:19.000000000 -0700 @@ -60,12 +60,12 @@ static void kill_bdev(struct block_devic { invalidate_bdev(bdev, 1); truncate_inode_pages(bdev->bd_inode->i_mapping, 0); -} +} int set_blocksize(struct block_device *bdev, int size) { - /* Size must be a power of two, and between 512 and PAGE_SIZE */ - if (size > PAGE_SIZE || size < 512 || (size & (size-1))) + /* Size must be a power of two, and greater than 512 */ + if (size < 512 || (size & (size-1))) return -EINVAL; /* Size cannot be smaller than the size supported by the device */ @@ -74,10 +74,16 @@ int set_blocksize(struct block_device *b /* Don't change the size if it is same as current */ if (bdev->bd_block_size != size) { + int bits = blksize_bits(size); + struct address_space *mapping = + bdev->bd_inode->i_mapping; + sync_blockdev(bdev); - bdev->bd_block_size = size; - bdev->bd_inode->i_blkbits = blksize_bits(size); kill_bdev(bdev); + bdev->bd_block_size = size; + bdev->bd_inode->i_blkbits = bits; + set_mapping_order(mapping, + bits < PAGE_SHIFT ? 0 : bits - PAGE_SHIFT); } return 0; } @@ -88,8 +94,10 @@ int sb_set_blocksize(struct super_block { if (set_blocksize(sb->s_bdev, size)) return 0; - /* If we get here, we know size is power of two - * and it's value is between 512 and PAGE_SIZE */ + /* + * If we get here, we know size is power of two + * and it's value is larger than 512 + */ sb->s_blocksize = size; sb->s_blocksize_bits = blksize_bits(size); return sb->s_blocksize; Index: linux-2.6.21-rc7/fs/buffer.c =================================================================== --- linux-2.6.21-rc7.orig/fs/buffer.c 2007-04-23 23:13:16.000000000 -0700 +++ linux-2.6.21-rc7/fs/buffer.c 2007-04-23 23:13:19.000000000 -0700 @@ -1084,7 +1084,7 @@ __getblk_slow(struct block_device *bdev, { /* Size must be multiple of hard sectorsize */ if (unlikely(size & (bdev_hardsect_size(bdev)-1) || - (size < 512 || size > PAGE_SIZE))) { + size < 512)) { printk(KERN_ERR "getblk(): invalid block size %d requested\n", size); printk(KERN_ERR "hardsect size: %d\n", Index: linux-2.6.21-rc7/fs/inode.c =================================================================== --- linux-2.6.21-rc7.orig/fs/inode.c 2007-04-23 23:14:36.000000000 -0700 +++ linux-2.6.21-rc7/fs/inode.c 2007-04-23 23:17:26.000000000 -0700 @@ -146,6 +146,11 @@ static struct inode *alloc_inode(struct mapping->host = inode; mapping->flags = 0; mapping_set_gfp_mask(mapping, GFP_HIGHUSER); + if (inode->i_blkbits > PAGE_SHIFT) + set_mapping_order(mapping, + inode->i_blkbits - PAGE_SHIFT); + else + set_mapping_order(mapping, 0); mapping->assoc_mapping = NULL; mapping->backing_dev_info = &default_backing_dev_info; -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/