From 6f0f73eb72f63c8988aa89e2bf05f24b6588e584 Mon Sep 17 00:00:00 2001 From: Artem Blagodarenko Date: Mon, 18 May 2015 10:20:14 -0400 Subject: [PATCH] LU-6464 ldiskfs: 64bit pointers in ext4_map_inode_page() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit To support >128TB OST ldiskfs should operates with large blocks numbers. There is function ext4_map_inode_page() with parameter “unsigned long *blocks”. An overflow is possible for large blocks numbers. The problem is actual for x86_32 systems only. This patch changes parameter type to sector_t that is 64 bit. Xyratex-bug-id: MRP-2020 Signed-off-by: Artem Blagodarenko Change-Id: If36544f39d3d31df9ff5ed644dad20f4910f3b39 Reviewed-on: http://review.whamcloud.com/14463 Tested-by: Jenkins Reviewed-by: James Simmons Tested-by: Maloo Reviewed-by: Yang Sheng Reviewed-by: Oleg Drokin --- .../rhel6.3/ext4-map_inode_page-2.6.18.patch | 4 +- .../sles11sp2/ext4-map_inode_page-3.0.patch | 4 +- lustre/osd-ldiskfs/osd_internal.h | 2 +- lustre/osd-ldiskfs/osd_io.c | 51 +++++++++++----------- lustre/osd-ldiskfs/osd_lproc.c | 4 +- 5 files changed, 33 insertions(+), 32 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/rhel6.3/ext4-map_inode_page-2.6.18.patch b/ldiskfs/kernel_patches/patches/rhel6.3/ext4-map_inode_page-2.6.18.patch index bbb4b78..22e67c0 100644 --- a/ldiskfs/kernel_patches/patches/rhel6.3/ext4-map_inode_page-2.6.18.patch +++ b/ldiskfs/kernel_patches/patches/rhel6.3/ext4-map_inode_page-2.6.18.patch @@ -6,7 +6,7 @@ diff -ur a/fs/ext4/ext4.h b/fs/ext4/ext4.h struct address_space *mapping, loff_t from); extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); +extern int ext4_map_inode_page(struct inode *inode, struct page *page, -+ unsigned long *blocks, int create); ++ sector_t *blocks, int create); extern qsize_t *ext4_get_reserved_space(struct inode *inode); extern int flush_aio_dio_completed_IO(struct inode *inode); extern void ext4_da_update_reserve_space(struct inode *inode, @@ -19,7 +19,7 @@ diff -ur a/fs/ext4/inode.c b/fs/ext4/inode.c } + +int ext4_map_inode_page(struct inode *inode, struct page *page, -+ unsigned long *blocks, int create) ++ sector_t *blocks, int create) +{ + unsigned int blocksize, blocks_per_page; + unsigned long iblock; diff --git a/ldiskfs/kernel_patches/patches/sles11sp2/ext4-map_inode_page-3.0.patch b/ldiskfs/kernel_patches/patches/sles11sp2/ext4-map_inode_page-3.0.patch index 94eaff7..a044252 100644 --- a/ldiskfs/kernel_patches/patches/sles11sp2/ext4-map_inode_page-3.0.patch +++ b/ldiskfs/kernel_patches/patches/sles11sp2/ext4-map_inode_page-3.0.patch @@ -10,7 +10,7 @@ extern void ext4_da_update_reserve_space(struct inode *inode, int used, int quota_claim); +extern int ext4_map_inode_page(struct inode *inode, struct page *page, -+ unsigned long *blocks, int created); ++ sector_t *blocks, int created); + /* ioctl.c */ extern long ext4_ioctl(struct file *, unsigned int, unsigned long); @@ -23,7 +23,7 @@ } + +int ext4_map_inode_page(struct inode *inode, struct page *page, -+ unsigned long *blocks, int create) ++ sector_t *blocks, int create) +{ + unsigned int blocksize, blocks_per_page; + unsigned long iblock; diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index 16ce2d1..296aa2f 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -481,7 +481,7 @@ struct osd_iobuf { struct lu_buf dr_pg_buf; struct page **dr_pages; struct lu_buf dr_bl_buf; - unsigned long *dr_blocks; + sector_t *dr_blocks; unsigned long dr_start_time; unsigned long dr_elapsed; /* how long io took */ struct osd_device *dr_dev; diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 8c32812..8507c38 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -259,22 +259,22 @@ static int osd_do_bio(struct osd_device *osd, struct inode *inode, struct osd_iobuf *iobuf) { int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits; - struct page **pages = iobuf->dr_pages; - int npages = iobuf->dr_npages; - unsigned long *blocks = iobuf->dr_blocks; - int total_blocks = npages * blocks_per_page; - int sector_bits = inode->i_sb->s_blocksize_bits - 9; - unsigned int blocksize = inode->i_sb->s_blocksize; - struct bio *bio = NULL; - struct page *page; - unsigned int page_offset; - sector_t sector; - int nblocks; - int block_idx; - int page_idx; - int i; - int rc = 0; - ENTRY; + struct page **pages = iobuf->dr_pages; + int npages = iobuf->dr_npages; + sector_t *blocks = iobuf->dr_blocks; + int total_blocks = npages * blocks_per_page; + int sector_bits = inode->i_sb->s_blocksize_bits - 9; + unsigned int blocksize = inode->i_sb->s_blocksize; + struct bio *bio = NULL; + struct page *page; + unsigned int page_offset; + sector_t sector; + int nblocks; + int block_idx; + int page_idx; + int i; + int rc = 0; + ENTRY; LASSERT(iobuf->dr_npages == npages); @@ -540,7 +540,7 @@ cleanup: #endif struct bpointers { - unsigned long *blocks; + sector_t *blocks; unsigned long start; int num; int init_num; @@ -764,7 +764,7 @@ map: } static int osd_ldiskfs_map_nblocks(struct inode *inode, unsigned long block, - unsigned long num, unsigned long *blocks, + unsigned long num, sector_t *blocks, int create) { struct bpointers bp; @@ -787,11 +787,11 @@ static int osd_ldiskfs_map_nblocks(struct inode *inode, unsigned long block, static int osd_ldiskfs_map_bm_inode_pages(struct inode *inode, struct page **page, int pages, - unsigned long *blocks, int create) + sector_t *blocks, int create) { int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits; pgoff_t bitmap_max_page_index; - unsigned long *b; + sector_t *b; int rc = 0, i; bitmap_max_page_index = LDISKFS_SB(inode->i_sb)->s_bitmap_maxbytes >> @@ -803,8 +803,9 @@ static int osd_ldiskfs_map_bm_inode_pages(struct inode *inode, } rc = ldiskfs_map_inode_page(inode, *page, b, create); if (rc) { - CERROR("ino %lu, blk %lu create %d: rc %d\n", - inode->i_ino, *b, create, rc); + CERROR("ino %lu, blk %llu create %d: rc %d\n", + inode->i_ino, + (unsigned long long)*b, create, rc); break; } b += blocks_per_page; @@ -814,7 +815,7 @@ static int osd_ldiskfs_map_bm_inode_pages(struct inode *inode, static int osd_ldiskfs_map_ext_inode_pages(struct inode *inode, struct page **page, - int pages, unsigned long *blocks, + int pages, sector_t *blocks, int create) { int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits; @@ -869,7 +870,7 @@ cleanup: } static int osd_ldiskfs_map_inode_pages(struct inode *inode, struct page **page, - int pages, unsigned long *blocks, + int pages, sector_t *blocks, int create) { int rc; @@ -885,7 +886,7 @@ static int osd_ldiskfs_map_inode_pages(struct inode *inode, struct page **page, } #else static int osd_ldiskfs_map_inode_pages(struct inode *inode, struct page **page, - int pages, unsigned long *blocks, + int pages, sector_t *blocks, int create) { int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits; diff --git a/lustre/osd-ldiskfs/osd_lproc.c b/lustre/osd-ldiskfs/osd_lproc.c index 91fd2ae..18a01a8 100644 --- a/lustre/osd-ldiskfs/osd_lproc.c +++ b/lustre/osd-ldiskfs/osd_lproc.c @@ -50,12 +50,12 @@ void osd_brw_stats_update(struct osd_device *osd, struct osd_iobuf *iobuf) { struct brw_stats *s = &osd->od_brw_stats; - unsigned long *last_block = NULL; + sector_t *last_block = NULL; struct page **pages = iobuf->dr_pages; struct page *last_page = NULL; unsigned long discont_pages = 0; unsigned long discont_blocks = 0; - unsigned long *blocks = iobuf->dr_blocks; + sector_t *blocks = iobuf->dr_blocks; int i, nr_pages = iobuf->dr_npages; int blocks_per_page; int rw = iobuf->dr_rw; -- 1.8.3.1