Whamcloud - gitweb
LU-3373 osd-ldiskfs: Use ext4_map_blocks for IO map 16/8116/14
authorYang Sheng <yang.sheng@intel.com>
Wed, 30 Jul 2014 19:39:35 +0000 (15:39 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 11 Aug 2014 05:37:49 +0000 (05:37 +0000)
Use ext4_map_blocks instead patch ext4 code too much.

Signed-off-by: yang sheng <yang.sheng@intel.com>
Change-Id: Ifc0cf2e45fbcbff688c57d4da52e17471bd55386
Reviewed-on: http://review.whamcloud.com/8116
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
config/lustre-build-ldiskfs.m4
lustre/osd-ldiskfs/osd_io.c

index 39cb853..4cf15a1 100644 (file)
@@ -85,6 +85,25 @@ ext4_journal_start, [
 ]) # LB_EXT4_JOURNAL_START_3ARGS
 
 #
 ]) # LB_EXT4_JOURNAL_START_3ARGS
 
 #
+# LB_LDISKFS_MAP_BLOCKS
+#
+# Since 2.6.35 brought ext4_map_blocks() for IO.
+# We just check this function whether existed.
+# it must be exported by ldiskfs patches.
+#
+AC_DEFUN([LB_LDISKFS_MAP_BLOCKS], [
+LB_CHECK_COMPILE([if kernel has ext4_map_blocks],
+ext4_map_blocks, [
+       #include <linux/fs.h>
+       #include "$EXT4_SRC_DIR/ext4.h"
+],[
+       ext4_map_blocks(NULL, NULL, NULL, 0);
+],[
+       AC_DEFINE(HAVE_LDISKFS_MAP_BLOCKS, 1, [kernel has ext4_map_blocks])
+])
+])
+
+#
 # LDISKFS_AC_PATCH_PROGRAM
 #
 # Determine which program should be used to apply the patches to
 # LDISKFS_AC_PATCH_PROGRAM
 #
 # Determine which program should be used to apply the patches to
@@ -162,6 +181,7 @@ AS_IF([test x$enable_ldiskfs != xno],[
        LB_EXT_FREE_BLOCKS_WITH_BUFFER_HEAD
        LB_EXT_PBLOCK
        LB_EXT4_JOURNAL_START_3ARGS
        LB_EXT_FREE_BLOCKS_WITH_BUFFER_HEAD
        LB_EXT_PBLOCK
        LB_EXT4_JOURNAL_START_3ARGS
+       LB_LDISKFS_MAP_BLOCKS
        AC_DEFINE(CONFIG_LDISKFS_FS_POSIX_ACL, 1, [posix acls for ldiskfs])
        AC_DEFINE(CONFIG_LDISKFS_FS_SECURITY, 1, [fs security for ldiskfs])
        AC_DEFINE(CONFIG_LDISKFS_FS_XATTR, 1, [extened attributes for ldiskfs])
        AC_DEFINE(CONFIG_LDISKFS_FS_POSIX_ACL, 1, [posix acls for ldiskfs])
        AC_DEFINE(CONFIG_LDISKFS_FS_SECURITY, 1, [fs security for ldiskfs])
        AC_DEFINE(CONFIG_LDISKFS_FS_XATTR, 1, [extened attributes for ldiskfs])
index 83e1bd2..9b2038a 100644 (file)
@@ -499,6 +499,8 @@ static int osd_bufs_put(const struct lu_env *env, struct dt_object *dt,
        RETURN(0);
 }
 
        RETURN(0);
 }
 
+#ifndef HAVE_LDISKFS_MAP_BLOCKS
+
 #ifdef HAVE_EXT_PBLOCK /* Name changed to ext4_ext_pblock for kernel 2.6.35 */
 #define ldiskfs_ext_pblock(ex) ext_pblock((ex))
 #endif
 #ifdef HAVE_EXT_PBLOCK /* Name changed to ext4_ext_pblock for kernel 2.6.35 */
 #define ldiskfs_ext_pblock(ex) ext_pblock((ex))
 #endif
@@ -618,7 +620,8 @@ static int ldiskfs_ext_new_extent_cb(struct inode *inode,
        tgen = LDISKFS_I(inode)->i_ext_generation;
        count = ldiskfs_ext_calc_credits_for_insert(inode, path);
 
        tgen = LDISKFS_I(inode)->i_ext_generation;
        count = ldiskfs_ext_calc_credits_for_insert(inode, path);
 
-       handle = ldiskfs_journal_start(inode, count + LDISKFS_ALLOC_NEEDED + 1);
+       handle = osd_journal_start(inode, LDISKFS_HT_MISC,
+                                  count + LDISKFS_ALLOC_NEEDED + 1);
        if (IS_ERR(handle)) {
                return PTR_ERR(handle);
        }
        if (IS_ERR(handle)) {
                return PTR_ERR(handle);
        }
@@ -748,6 +751,26 @@ int osd_ldiskfs_map_nblocks(struct inode *inode, unsigned long block,
        return err;
 }
 
        return err;
 }
 
+int osd_ldiskfs_map_bm_inode_pages(struct inode *inode, struct page **page,
+                                  int pages, unsigned long *blocks,
+                                  int create)
+{
+       int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits;
+       unsigned long *b;
+       int rc = 0, i;
+
+       for (i = 0, b = blocks; i < pages; i++, page++) {
+               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);
+                       break;
+               }
+               b += blocks_per_page;
+       }
+       return rc;
+}
+
 int osd_ldiskfs_map_ext_inode_pages(struct inode *inode, struct page **page,
                                    int pages, unsigned long *blocks,
                                    int create)
 int osd_ldiskfs_map_ext_inode_pages(struct inode *inode, struct page **page,
                                    int pages, unsigned long *blocks,
                                    int create)
@@ -797,27 +820,6 @@ cleanup:
        return rc;
 }
 
        return rc;
 }
 
-int osd_ldiskfs_map_bm_inode_pages(struct inode *inode, struct page **page,
-                                  int pages, unsigned long *blocks,
-                                  int create)
-{
-       int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits;
-       unsigned long *b;
-       int rc = 0, i;
-
-       for (i = 0, b = blocks; i < pages; i++, page++) {
-               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);
-                       break;
-               }
-
-               b += blocks_per_page;
-       }
-       return rc;
-}
-
 static int osd_ldiskfs_map_inode_pages(struct inode *inode, struct page **page,
                                       int pages, unsigned long *blocks,
                                       int create)
 static int osd_ldiskfs_map_inode_pages(struct inode *inode, struct page **page,
                                       int pages, unsigned long *blocks,
                                       int create)
@@ -833,6 +835,85 @@ static int osd_ldiskfs_map_inode_pages(struct inode *inode, struct page **page,
 
        return rc;
 }
 
        return rc;
 }
+#else
+static int osd_ldiskfs_map_inode_pages(struct inode *inode, struct page **page,
+                                      int pages, unsigned long *blocks,
+                                      int create)
+{
+       int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits;
+       int rc = 0, i = 0;
+       struct page *fp = NULL;
+       int clen = 0;
+
+       CDEBUG(D_OTHER, "inode %lu: map %d pages from %lu\n",
+               inode->i_ino, pages, (*page)->index);
+
+       /* pages are sorted already. so, we just have to find
+        * contig. space and process them properly */
+       while (i < pages) {
+               long blen, total = 0;
+               handle_t *handle = NULL;
+               struct ldiskfs_map_blocks map = { 0 };
+
+               if (fp == NULL) { /* start new extent */
+                       fp = *page++;
+                       clen = 1;
+                       if (++i != pages)
+                               continue;
+               } else if (fp->index + clen == (*page)->index) {
+                       /* continue the extent */
+                       page++;
+                       clen++;
+                       if (++i != pages)
+                               continue;
+               }
+               /* process found extent */
+               map.m_lblk = fp->index * blocks_per_page;
+               map.m_len = blen = clen * blocks_per_page;
+               if (create) {
+                       create = LDISKFS_GET_BLOCKS_CREATE;
+                       handle = ldiskfs_journal_current_handle();
+                       LASSERT(handle != NULL);
+               }
+cont_map:
+               rc = ldiskfs_map_blocks(handle, inode, &map, create);
+               if (rc >= 0) {
+                       int c = 0;
+                       for (; total < blen && c < map.m_len; c++, total++) {
+                               if (rc == 0) {
+                                       *(blocks + total) = 0;
+                                       total++;
+                                       break;
+                               } else {
+                                       *(blocks + total) = map.m_pblk + c;
+                                       /* unmap any possible underlying
+                                        * metadata from the block device
+                                        * mapping.  bug 6998. */
+                                       if ((map.m_flags & LDISKFS_MAP_NEW) &&
+                                           create)
+                                               unmap_underlying_metadata(
+                                                       inode->i_sb->s_bdev,
+                                                       map.m_pblk + c);
+                               }
+                       }
+                       rc = 0;
+               }
+               if (rc == 0 && total < blen) {
+                       map.m_lblk = fp->index * blocks_per_page + total;
+                       map.m_len = blen - total;
+                       goto cont_map;
+               }
+               if (rc != 0)
+                       GOTO(cleanup, rc);
+
+               /* look for next extent */
+               fp = NULL;
+               blocks += blocks_per_page * clen;
+       }
+cleanup:
+       return rc;
+}
+#endif /* HAVE_LDISKFS_MAP_BLOCKS */
 
 static int osd_write_prep(const struct lu_env *env, struct dt_object *dt,
                           struct niobuf_local *lnb, int npages)
 
 static int osd_write_prep(const struct lu_env *env, struct dt_object *dt,
                           struct niobuf_local *lnb, int npages)