]) # 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
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])
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
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);
}
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)
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)
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)