Whamcloud - gitweb
LU-6464 ldiskfs: 64bit pointers in ext4_map_inode_page() 63/14463/6
authorArtem Blagodarenko <artem_blagodarenko@xyratex.com>
Mon, 18 May 2015 14:20:14 +0000 (10:20 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 5 Jun 2015 01:54:02 +0000 (01:54 +0000)
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 <artem_blagodarenko@xyratex.com>
Change-Id: If36544f39d3d31df9ff5ed644dad20f4910f3b39
Reviewed-on: http://review.whamcloud.com/14463
Tested-by: Jenkins
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Yang Sheng <yang.sheng@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
ldiskfs/kernel_patches/patches/rhel6.3/ext4-map_inode_page-2.6.18.patch
ldiskfs/kernel_patches/patches/sles11sp2/ext4-map_inode_page-3.0.patch
lustre/osd-ldiskfs/osd_internal.h
lustre/osd-ldiskfs/osd_io.c
lustre/osd-ldiskfs/osd_lproc.c

index bbb4b78..22e67c0 100644 (file)
@@ -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;
index 94eaff7..a044252 100644 (file)
@@ -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;
index 16ce2d1..296aa2f 100644 (file)
@@ -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;
index 8c32812..8507c38 100644 (file)
@@ -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;
index 91fd2ae..18a01a8 100644 (file)
 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;