+}
+
+/*
-+ * returns first allocated block from next leaf or EXT_MAX_BLOCK
++ * returns first allocated block from next leaf or EXT_UNSET_BLOCK
+ */
+static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree,
+ struct ext3_ext_path *path)
+
+ /* zero-tree has no leaf blocks at all */
+ if (depth == 0)
-+ return EXT_MAX_BLOCK;
++ return EXT_UNSET_BLOCK;
+
+ /* go to index block */
+ depth--;
+ depth--;
+ }
+
-+ return EXT_MAX_BLOCK;
++ return EXT_UNSET_BLOCK;
+}
+
+/*
+ /* probably next leaf has space for us? */
+ fex = EXT_LAST_EXTENT(eh);
+ next = ext3_ext_next_leaf_block(tree, path);
-+ if (newext->ee_block > fex->ee_block && next != EXT_MAX_BLOCK) {
++ if (newext->ee_block > fex->ee_block && next != EXT_UNSET_BLOCK) {
+ ext_debug(tree, "next leaf block - %d\n", next);
+ EXT_ASSERT(!npath);
+ npath = ext3_ext_find_extent(tree, next, NULL);
+ path[depth].p_ext = ex;
+
+ a = ex->ee_block > start ? ex->ee_block : start;
-+ b = ex->ee_block + ex->ee_len - 1 < end ?
-+ ex->ee_block + ex->ee_len - 1 : end;
++ b = (unsigned long long)ex->ee_block + ex->ee_len - 1 <
++ end ? ex->ee_block + ex->ee_len - 1 : end;
+
+ ext_debug(tree, " border %u:%u\n", a, b);
+
===================================================================
--- /dev/null
+++ linux-2.6.16.54-0.2.5/include/linux/ext3_extents.h
-@@ -0,0 +1,262 @@
+@@ -0,0 +1,263 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.
+ * Written by Alex Tomas <alex@clusterfs.com>
+
+
+#define EXT_MAX_BLOCK 0xffffffff
++#define EXT_UNSET_BLOCK 1
+
+
+#define EXT_FIRST_EXTENT(__hdr__) \
+++ linux-2.6.18.8/fs/ext3/extents.c 2007-07-17 11:08:59.000000000 +0200
@@ -0,0 +1,2276 @@
+/*
-+ * Copyright 2008 Sun Microsystems, Inc.
++ * Copyright 2008, Sun Microsystems, Inc.
+ * Written by Alex Tomas <alex@clusterfs.com>
+ *
+ * Architecture independence:
+{
+ struct buffer_head *bh = NULL;
+ struct ext3_extent_header *eh;
-+ struct ext3_extent_idx *ix;
++ struct ext3_extent_idx *ix = NULL;
+ struct ext3_extent *ex;
+ unsigned long block;
+ int depth;
+}
+
+/*
-+ * returns first allocated block from next leaf or EXT_MAX_BLOCK
++ * returns first allocated block from next leaf or EXT_UNSET_BLOCK
+ */
+static unsigned ext3_ext_next_leaf_block(struct inode *inode,
+ struct ext3_ext_path *path)
+
+ /* zero-tree has no leaf blocks at all */
+ if (depth == 0)
-+ return EXT_MAX_BLOCK;
++ return EXT_UNSET_BLOCK;
+
+ /* go to index block */
+ depth--;
+ depth--;
+ }
+
-+ return EXT_MAX_BLOCK;
++ return EXT_UNSET_BLOCK;
+}
+
+/*
+ fex = EXT_LAST_EXTENT(eh);
+ next = ext3_ext_next_leaf_block(inode, path);
+ if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block)
-+ && next != EXT_MAX_BLOCK) {
++ && next != EXT_UNSET_BLOCK) {
+ ext_debug(inode, "next leaf block - %d\n", next);
+ BUG_ON(npath != NULL);
+ npath = ext3_ext_find_extent(inode, next, NULL);
+ path[depth].p_ext = ex;
+
+ a = ex_ee_block > start ? ex_ee_block : start;
-+ b = ex_ee_block + ex_ee_len - 1 < EXT_MAX_BLOCK ?
-+ ex_ee_block + ex_ee_len - 1 : EXT_MAX_BLOCK;
++ b = (unsigned long long)ex_ee_block + ex_ee_len - 1 <
++ EXT_MAX_BLOCK ? ex_ee_block + ex_ee_len - 1 : EXT_MAX_BLOCK;
+
+ ext_debug(inode, " border %u:%u\n", a, b);
+
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18.8/include/linux/ext3_extents.h 2007-07-17 09:18:14.000000000 +0200
-@@ -0,0 +1,231 @@
+@@ -0,0 +1,232 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.
+ * Written by Alex Tomas <alex@clusterfs.com>
+
+
+#define EXT_MAX_BLOCK 0xffffffff
++#define EXT_UNSET_BLOCK 1
+
+#define EXT_FLAGS_CLR_UNKNOWN 0x7 /* Flags cleared on modification */
+#define EXT_HDR_GEN_BITS 24
+{
+ struct buffer_head *bh = NULL;
+ struct ext3_extent_header *eh;
-+ struct ext3_extent_idx *ix;
++ struct ext3_extent_idx *ix = NULL;
+ struct ext3_extent *ex;
+ unsigned long block;
+ int depth;
===================================================================
--- linux-2.6.5-7.311.orig/fs/ext3/super.c
+++ linux-2.6.5-7.311/fs/ext3/super.c
-@@ -390,6 +390,7 @@ void ext3_put_super (struct super_block
+@@ -389,6 +389,7 @@ void ext3_put_super (struct super_block
struct ext3_super_block *es = sbi->s_es;
int i;
ext3_xattr_put_super(sb);
journal_destroy(sbi->s_journal);
if (!(sb->s_flags & MS_RDONLY)) {
-@@ -451,6 +452,8 @@ static struct inode *ext3_alloc_inode(st
+@@ -450,6 +451,8 @@ static struct inode *ext3_alloc_inode(st
#endif
ei->i_rsv_window.rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
ei->vfs_inode.i_version = 1;
return &ei->vfs_inode;
}
-@@ -615,6 +618,7 @@ enum {
+@@ -584,6 +587,7 @@ enum {
Opt_ignore, Opt_barrier,
Opt_err,
Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
};
static match_table_t tokens = {
-@@ -658,6 +662,9 @@ static match_table_t tokens = {
+@@ -627,6 +631,9 @@ static match_table_t tokens = {
{Opt_iopen, "iopen"},
{Opt_noiopen, "noiopen"},
{Opt_iopen_nopriv, "iopen_nopriv"},
{Opt_barrier, "barrier=%u"},
{Opt_err, NULL}
};
-@@ -874,6 +881,15 @@ static int parse_options (char * options
+@@ -843,6 +850,15 @@ static int parse_options (char * options
break;
case Opt_ignore:
break;
default:
printk (KERN_ERR
"EXT3-fs: Unrecognized mount option \"%s\" "
-@@ -1528,6 +1544,8 @@ static int ext3_fill_super (struct super
+@@ -1495,6 +1511,8 @@ static int ext3_fill_super (struct super
percpu_counter_mod(&sbi->s_dirs_counter,
ext3_count_dirs(sb));
-Index: linux-2.6.9-67.0.15/fs/ext3/extents.c
+Index: linux-2.6.9-67.0.20/fs/ext3/extents.c
===================================================================
--- /dev/null
-+++ linux-2.6.9-67.0.15/fs/ext3/extents.c
++++ linux-2.6.9-67.0.20/fs/ext3/extents.c
@@ -0,0 +1,2265 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.
+ ext3_init_tree_desc(&tree, inode);
+ return ext3_ext_calc_metadata_amount(&tree, blocks);
+}
-+
++
+EXPORT_SYMBOL(ext3_init_tree_desc);
+EXPORT_SYMBOL(ext3_mark_inode_dirty);
+EXPORT_SYMBOL(ext3_ext_invalidate_cache);
+EXPORT_SYMBOL(ext3_ext_walk_space);
+EXPORT_SYMBOL(ext3_ext_find_goal);
+EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert);
-Index: linux-2.6.9-67.0.15/fs/ext3/ialloc.c
+Index: linux-2.6.9-67.0.20/fs/ext3/ialloc.c
===================================================================
---- linux-2.6.9-67.0.15.orig/fs/ext3/ialloc.c
-+++ linux-2.6.9-67.0.15/fs/ext3/ialloc.c
+--- linux-2.6.9-67.0.20.orig/fs/ext3/ialloc.c
++++ linux-2.6.9-67.0.20/fs/ext3/ialloc.c
@@ -602,7 +602,7 @@ got:
ei->i_dir_start_lookup = 0;
ei->i_disksize = 0;
err = ext3_mark_inode_dirty(handle, inode);
if (err) {
ext3_std_error(sb, err);
-Index: linux-2.6.9-67.0.15/fs/ext3/inode.c
+Index: linux-2.6.9-67.0.20/fs/ext3/inode.c
===================================================================
---- linux-2.6.9-67.0.15.orig/fs/ext3/inode.c
-+++ linux-2.6.9-67.0.15/fs/ext3/inode.c
+--- linux-2.6.9-67.0.20.orig/fs/ext3/inode.c
++++ linux-2.6.9-67.0.20/fs/ext3/inode.c
@@ -797,6 +797,17 @@ changed:
goto reread;
}
if (ext3_should_journal_data(inode))
ret = 3 * (bpp + indirects) + 2;
else
-Index: linux-2.6.9-67.0.15/fs/ext3/Makefile
+Index: linux-2.6.9-67.0.20/fs/ext3/Makefile
===================================================================
---- linux-2.6.9-67.0.15.orig/fs/ext3/Makefile
-+++ linux-2.6.9-67.0.15/fs/ext3/Makefile
+--- linux-2.6.9-67.0.20.orig/fs/ext3/Makefile
++++ linux-2.6.9-67.0.20/fs/ext3/Makefile
@@ -5,7 +5,8 @@
obj-$(CONFIG_EXT3_FS) += ext3.o
ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
-Index: linux-2.6.9-67.0.15/fs/ext3/super.c
+Index: linux-2.6.9-67.0.20/fs/ext3/super.c
===================================================================
---- linux-2.6.9-67.0.15.orig/fs/ext3/super.c
-+++ linux-2.6.9-67.0.15/fs/ext3/super.c
+--- linux-2.6.9-67.0.20.orig/fs/ext3/super.c
++++ linux-2.6.9-67.0.20/fs/ext3/super.c
@@ -394,6 +394,7 @@ void ext3_put_super (struct super_block
struct ext3_super_block *es = sbi->s_es;
int i;
return &ei->vfs_inode;
}
-@@ -642,6 +645,7 @@ enum {
+@@ -635,6 +638,7 @@ enum {
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
Opt_ignore, Opt_barrier, Opt_err, Opt_resize,
Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
};
static match_table_t tokens = {
-@@ -691,6 +695,9 @@ static match_table_t tokens = {
+@@ -684,6 +688,9 @@ static match_table_t tokens = {
{Opt_iopen, "iopen"},
{Opt_noiopen, "noiopen"},
{Opt_iopen_nopriv, "iopen_nopriv"},
{Opt_barrier, "barrier=%u"},
{Opt_err, NULL},
{Opt_resize, "resize"},
-@@ -999,6 +1006,15 @@ clear_qf_name:
+@@ -988,6 +995,15 @@ clear_qf_name:
match_int(&args[0], &option);
*n_blocks_count = option;
break;
default:
printk (KERN_ERR
"EXT3-fs: Unrecognized mount option \"%s\" "
-@@ -1693,6 +1709,8 @@ static int ext3_fill_super (struct super
+@@ -1682,6 +1698,8 @@ static int ext3_fill_super (struct super
percpu_counter_mod(&sbi->s_dirs_counter,
ext3_count_dirs(sb));
return 0;
failed_mount3:
-Index: linux-2.6.9-67.0.15/include/linux/ext3_fs.h
+Index: linux-2.6.9-67.0.20/include/linux/ext3_fs.h
===================================================================
---- linux-2.6.9-67.0.15.orig/include/linux/ext3_fs.h
-+++ linux-2.6.9-67.0.15/include/linux/ext3_fs.h
+--- linux-2.6.9-67.0.20.orig/include/linux/ext3_fs.h
++++ linux-2.6.9-67.0.20/include/linux/ext3_fs.h
@@ -185,9 +185,10 @@ struct ext3_group_desc
#define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */
#define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
#endif /* __KERNEL__ */
-Index: linux-2.6.9-67.0.15/include/linux/ext3_extents.h
+Index: linux-2.6.9-67.0.20/include/linux/ext3_extents.h
===================================================================
--- /dev/null
-+++ linux-2.6.9-67.0.15/include/linux/ext3_extents.h
++++ linux-2.6.9-67.0.20/include/linux/ext3_extents.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.
+ tree->cex->ec_type = EXT3_EXT_CACHE_NO;
+}
+#endif /* _LINUX_EXT3_EXTENTS */
-Index: linux-2.6.9-67.0.15/include/linux/ext3_fs_i.h
+Index: linux-2.6.9-67.0.20/include/linux/ext3_fs_i.h
===================================================================
---- linux-2.6.9-67.0.15.orig/include/linux/ext3_fs_i.h
-+++ linux-2.6.9-67.0.15/include/linux/ext3_fs_i.h
+--- linux-2.6.9-67.0.20.orig/include/linux/ext3_fs_i.h
++++ linux-2.6.9-67.0.20/include/linux/ext3_fs_i.h
@@ -128,6 +128,8 @@ struct ext3_inode_info {
*/
struct semaphore truncate_sem;
+++ /dev/null
-A large part of this code is from the generic VFS code in fs/ioctl.c in the
-upstream kernel.
-
-Index: linux-2.6.9-67.0.22/fs/ext3/ioctl.c
-===================================================================
---- linux-2.6.9-67.0.22.orig/fs/ext3/ioctl.c
-+++ linux-2.6.9-67.0.22/fs/ext3/ioctl.c
-@@ -14,7 +14,159 @@
- #include <linux/time.h>
- #include <asm/uaccess.h>
- #include <linux/namei.h>
-+#include "fiemap.h"
-
-+/* So that the fiemap access checks can't overflow on 32 bit machines. */
-+#define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
-+
-+/**
-+ * fiemap_fill_next_extent - Fiemap helper function
-+ * @fieinfo: Fiemap context passed into ->fiemap
-+ * @logical: Extent logical start offset, in bytes
-+ * @phys: Extent physical start offset, in bytes
-+ * @len: Extent length, in bytes
-+ * @flags: FIEMAP_EXTENT flags that describe this extent
-+ * @lun: LUN on which this extent resides
-+ *
-+ * Called from file system ->fiemap callback. Will populate extent
-+ * info as passed in via arguments and copy to user memory. On
-+ * success, extent count on fieinfo is incremented.
-+ *
-+ * Returns 0 on success, -errno on error, 1 if this was the last
-+ * extent that will fit in user array.
-+ */
-+#define SET_UNKNOWN_FLAGS (FIEMAP_EXTENT_DELALLOC)
-+#define SET_NO_DIRECT_FLAGS (FIEMAP_EXTENT_DATA_COMPRESSED \
-+ |FIEMAP_EXTENT_DATA_ENCRYPTED \
-+ |FIEMAP_EXTENT_NET)
-+#define SET_NOT_ALIGNED_FLAGS (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
-+int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
-+ u64 phys, u64 len, u32 flags, dev_t dev)
-+{
-+ struct fiemap_extent extent = { 0 };
-+ struct fiemap_extent *dest = fieinfo->fi_extents_start;
-+
-+ /* only count the extents */
-+ if (fieinfo->fi_extents_max == 0) {
-+ fieinfo->fi_extents_mapped++;
-+ return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
-+ }
-+
-+ if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
-+ return 1;
-+
-+ if (flags & SET_UNKNOWN_FLAGS)
-+ flags |= FIEMAP_EXTENT_UNKNOWN;
-+ if (flags & SET_NO_DIRECT_FLAGS)
-+ flags |= FIEMAP_EXTENT_NO_DIRECT;
-+ if (flags & SET_NOT_ALIGNED_FLAGS)
-+ flags |= FIEMAP_EXTENT_NOT_ALIGNED;
-+
-+ extent.fe_logical = logical;
-+ extent.fe_physical = phys;
-+ extent.fe_length = len;
-+ extent.fe_flags = flags;
-+ extent.fe_device = new_encode_dev(dev);
-+
-+ dest += fieinfo->fi_extents_mapped;
-+ if (copy_to_user(dest, &extent, sizeof(extent)))
-+ return -EFAULT;
-+
-+ fieinfo->fi_extents_mapped++;
-+ if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
-+ return 1;
-+
-+ return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
-+}
-+
-+static int fiemap_check_ranges(struct super_block *sb,
-+ u64 start, u64 len, u64 *new_len)
-+{
-+ *new_len = len;
-+
-+ if (len == 0)
-+ return -EINVAL;
-+
-+ if (start > sb->s_maxbytes)
-+ return -EFBIG;
-+
-+ /*
-+ * Shrink request scope to what the fs can actually handle.
-+ */
-+ if ((len > sb->s_maxbytes) ||
-+ (sb->s_maxbytes - len) < start)
-+ *new_len = sb->s_maxbytes - start;
-+
-+ return 0;
-+}
-+
-+/*
-+ * fiemap_check_flags - check validity of requested flags for fiemap
-+ * @fieinfo: Fiemap context passed into ->fiemap
-+ * @fs_flags: Set of fiemap flags that the file system understands
-+ *
-+ * Called from file system ->fiemap callback. This will compute the
-+ * intersection of valid fiemap flags and those that the fs supports. That
-+ * value is then compared against the user supplied flags. In case of bad user
-+ * flags, the invalid values will be written into the fieinfo structure, and
-+ * -EBADR is returned, which tells ioctl_fiemap() to return those values to
-+ * userspace. For this reason, a return code of -EBADR should be preserved.
-+ *
-+ * Returns 0 on success, -EBADR on bad flags.
-+*/
-+int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags)
-+{
-+ u32 incompat_flags;
-+
-+ incompat_flags = fieinfo->fi_flags & ~(FIEMAP_FLAGS_COMPAT & fs_flags);
-+ if (incompat_flags) {
-+ fieinfo->fi_flags = incompat_flags;
-+ return -EBADR;
-+ }
-+
-+ return 0;
-+}
-+
-+int ioctl_fiemap(struct inode *inode, struct file *filp, unsigned long arg)
-+{
-+ struct fiemap fiemap;
-+ u64 len;
-+ struct fiemap_extent_info fieinfo = {0, };
-+ struct super_block *sb = inode->i_sb;
-+ int error = 0;
-+
-+ if (copy_from_user(&fiemap, (struct fiemap __user *) arg,
-+ sizeof(struct fiemap)))
-+ return -EFAULT;
-+
-+ if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
-+ return -EINVAL;
-+
-+ error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length,
-+ &len);
-+ if (error)
-+ return error;
-+
-+ fieinfo.fi_flags = fiemap.fm_flags;
-+ fieinfo.fi_extents_max = fiemap.fm_extent_count;
-+ fieinfo.fi_extents_start = (struct fiemap_extent *)(arg + sizeof(fiemap));
-+
-+ if (fiemap.fm_extent_count != 0 &&
-+ !access_ok(VERIFY_WRITE, (void *)arg,
-+ offsetof(typeof(fiemap), fm_extents[fiemap.fm_extent_count])))
-+ return -EFAULT;
-+
-+ if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
-+ ext3_sync_file(filp, filp->f_dentry, 1);
-+
-+ error = ext3_fiemap(inode, &fieinfo, fiemap.fm_start, len);
-+ fiemap.fm_flags = fieinfo.fi_flags;
-+ fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
-+ if (copy_to_user((char *)arg, &fiemap, sizeof(fiemap)))
-+ error = -EFAULT;
-+
-+ return error;
-+}
-
- int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
- unsigned long arg)
-@@ -244,7 +396,9 @@ flags_err:
-
- return err;
- }
--
-+ case EXT3_IOC_FIEMAP: {
-+ return ioctl_fiemap(inode, filp, arg);
-+ }
-
- default:
- return -ENOTTY;
-Index: linux-2.6.9-67.0.22/include/linux/ext3_fs.h
-===================================================================
---- linux-2.6.9-67.0.22.orig/include/linux/ext3_fs.h
-+++ linux-2.6.9-67.0.22/include/linux/ext3_fs.h
-@@ -259,15 +259,19 @@ struct ext3_new_group_data {
- #define EXT3_IOC_SETFLAGS _IOW('f', 2, long)
- #define EXT3_IOC_GETVERSION _IOR('f', 3, long)
- #define EXT3_IOC_SETVERSION _IOW('f', 4, long)
-+#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long)
-+#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
- #define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
- #define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input)
-+#define EXT3_IOC_FIEMAP _IOWR('f', 10, struct fiemap)
- #define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long)
- #define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long)
- #ifdef CONFIG_JBD_DEBUG
- #define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long)
- #endif
--#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long)
--#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
-+
-+/* FIEMAP flags supported by ext3 */
-+#define EXT3_FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC)
-
- /*
- * Structure of an inode on the disk
-@@ -969,6 +973,9 @@ extern void ext3_set_aops(struct inode *
- /* ioctl.c */
- extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
- unsigned long);
-+struct fiemap_extent_info;
-+extern int ext3_fiemap(struct inode *, struct fiemap_extent_info *, __u64,
-+ __u64);
-
- /* namei.c */
- extern int ext3_orphan_add(handle_t *, struct inode *);
-Index: linux-2.6.9-67.0.22/include/linux/ext3_extents.h
-===================================================================
---- linux-2.6.9-67.0.22.orig/include/linux/ext3_extents.h
-+++ linux-2.6.9-67.0.22/include/linux/ext3_extents.h
-@@ -170,7 +170,10 @@ struct ext3_extents_helpers {
- */
- typedef int (*ext_prepare_callback)(struct ext3_extents_tree *,
- struct ext3_ext_path *,
-- struct ext3_ext_cache *);
-+ struct ext3_ext_cache *,
-+ struct ext3_extent *);
-+
-+#define HAVE_EXT_PREPARE_CB_EXTENT
-
- #define EXT_CONTINUE 0
- #define EXT_BREAK 1
-@@ -179,6 +182,25 @@ typedef int (*ext_prepare_callback)(stru
-
- #define EXT_MAX_BLOCK 0xffffffff
-
-+/*
-+ * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
-+ * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
-+ * MSB of ee_len field in the extent datastructure to signify if this
-+ * particular extent is an initialized extent or an uninitialized (i.e.
-+ * preallocated).
-+ * EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
-+ * uninitialized extent.
-+ * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
-+ * uninitialized one. In other words, if MSB of ee_len is set, it is an
-+ * uninitialized extent with only one special scenario when ee_len = 0x8000.
-+ * In this case we can not have an uninitialized extent of zero length and
-+ * thus we make it as a special case of initialized extent with 0x8000 length.
-+ * This way we get better extent-to-group alignment for initialized extents.
-+ * Hence, the maximum number of blocks we can have in an *initialized*
-+ * extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
-+ */
-+#define EXT_INIT_MAX_LEN (1UL << 15)
-+#define EXT_UNINIT_MAX_LEN (EXT_INIT_MAX_LEN - 1)
-
- #define EXT_FIRST_EXTENT(__hdr__) \
- ((struct ext3_extent *) (((char *) (__hdr__)) + \
-@@ -244,6 +266,12 @@ struct ext3_extent_tree_stats {
- int leaf_num;
- };
-
-+static inline int ext3_ext_is_uninitialized(struct ext3_extent *ext)
-+{
-+ /* Extent with ee_len of 0x8000 is treated as an initialized extent */
-+ return (le16_to_cpu(ext->ee_len) > EXT_INIT_MAX_LEN);
-+}
-+
- extern int ext3_ext_search_left(struct ext3_extents_tree *, struct ext3_ext_path *, unsigned long *, unsigned long *);
- extern int ext3_ext_search_right(struct ext3_extents_tree *, struct ext3_ext_path *, unsigned long *, unsigned long *);
- extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *);
-Index: linux-2.6.9-67.0.22/fs/ext3/extents.c
-===================================================================
---- linux-2.6.9-67.0.22.orig/fs/ext3/extents.c
-+++ linux-2.6.9-67.0.22/fs/ext3/extents.c
-@@ -41,6 +41,7 @@
- #include <linux/string.h>
- #include <linux/slab.h>
- #include <linux/ext3_extents.h>
-+#include "fiemap.h"
- #include <asm/uaccess.h>
-
-
-@@ -1489,7 +1490,7 @@ int ext3_ext_walk_space(struct ext3_exte
-
- EXT_ASSERT(cbex.ec_len > 0);
- EXT_ASSERT(path[depth].p_hdr);
-- err = func(tree, path, &cbex);
-+ err = func(tree, path, &cbex, ex);
- ext3_ext_drop_refs(path);
-
- if (err < 0)
-@@ -2504,6 +2505,108 @@ int ext3_ext_calc_blockmap_metadata(stru
- return ext3_ext_calc_metadata_amount(&tree, blocks);
- }
-
-+/*
-+ * Callback function called for each extent to gather FIEMAP information.
-+ */
-+int ext3_ext_fiemap_cb(struct ext3_extents_tree *tree,
-+ struct ext3_ext_path *path, struct ext3_ext_cache *newex,
-+ struct ext3_extent *ex)
-+{
-+ struct fiemap_extent_info *fieinfo = (struct fiemap_extent_info *)tree->private;
-+ struct inode *inode = tree->inode;
-+ unsigned long blksize_bits = inode->i_sb->s_blocksize_bits;
-+ __u64 logical;
-+ __u64 physical;
-+ __u64 length;
-+ __u32 flags = 0;
-+ int error;
-+
-+ logical = (__u64)newex->ec_block << blksize_bits;
-+
-+ if (newex->ec_type == EXT3_EXT_CACHE_GAP) {
-+ pgoff_t offset;
-+ struct page *page;
-+ struct buffer_head *bh = NULL;
-+
-+ offset = logical >> PAGE_SHIFT;
-+ page = find_get_page(inode->i_mapping, offset);
-+ if (!page || !page_has_buffers(page))
-+ return EXT_CONTINUE;
-+
-+ bh = page_buffers(page);
-+
-+ if (!bh)
-+ return EXT_CONTINUE;
-+
-+ if (buffer_delay(bh)) {
-+ flags |= FIEMAP_EXTENT_DELALLOC;
-+ page_cache_release(page);
-+ } else {
-+ page_cache_release(page);
-+ return EXT_CONTINUE;
-+ }
-+ }
-+
-+ physical = (__u64)newex->ec_start << blksize_bits;
-+ length = (__u64)newex->ec_len << blksize_bits;
-+
-+ if (ex && ext3_ext_is_uninitialized(ex))
-+ flags |= FIEMAP_EXTENT_UNWRITTEN;
-+
-+ /*
-+ * If this extent reaches EXT_MAX_BLOCK, it must be last.
-+ *
-+ * Or if ext3_ext_next_allocated_block is EXT_MAX_BLOCK,
-+ * this indicates no more allocated blocks.
-+ *
-+ * XXX this might miss a single-block extent at EXT_MAX_BLOCK
-+ */
-+ if (logical + length - 1 == EXT_MAX_BLOCK ||
-+ ext3_ext_next_allocated_block(path) == EXT_MAX_BLOCK)
-+ flags |= FIEMAP_EXTENT_LAST;
-+
-+ error = fiemap_fill_next_extent(fieinfo, logical, physical,
-+ length, flags, inode->i_sb->s_dev);
-+ if (error < 0)
-+ return error;
-+ if (error == 1)
-+ return EXT_BREAK;
-+
-+ return EXT_CONTINUE;
-+}
-+
-+int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
-+ __u64 start, __u64 len)
-+{
-+ struct ext3_extents_tree tree;
-+ unsigned long start_blk;
-+ unsigned long len_blks;
-+ int error = 0;
-+
-+ if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL))
-+ return -EOPNOTSUPP;
-+
-+ if (fiemap_check_flags(fieinfo, EXT3_FIEMAP_FLAGS_COMPAT))
-+ return -EBADR;
-+
-+ start_blk = start >> inode->i_sb->s_blocksize_bits;
-+ len_blks = (len + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
-+
-+ ext3_init_tree_desc(&tree, inode);
-+ tree.private = fieinfo;
-+
-+ /*
-+ * Walk the extent tree gathering extent information.
-+ * ext3_ext_fiemap_cb will push extents back to user.
-+ */
-+ down(&EXT3_I(inode)->truncate_sem);
-+ error = ext3_ext_walk_space(&tree, start_blk, len_blks,
-+ ext3_ext_fiemap_cb);
-+ up(&EXT3_I(inode)->truncate_sem);
-+
-+ return error;
-+}
-+
- EXPORT_SYMBOL(ext3_init_tree_desc);
- EXPORT_SYMBOL(ext3_mark_inode_dirty);
- EXPORT_SYMBOL(ext3_ext_invalidate_cache);
-Index: linux-2.6.9-67.0.22/fs/ext3/fiemap.h
-===================================================================
---- /dev/null
-+++ linux-2.6.9-67.0.22/fs/ext3/fiemap.h
-@@ -0,0 +1,84 @@
-+/*
-+ * FIEMAP ioctl infrastructure.
-+ *
-+ * Copyright 2008 Sun Microsystems, Inc.
-+ *
-+ * Author: Kalpak Shah <kalpak.shah@sun.com>
-+ * Andreas Dilger <adilger@sun.com>
-+ */
-+
-+#ifndef _LINUX_EXT3_FIEMAP_H
-+#define _LINUX_EXT3_FIEMAP_H
-+
-+struct fiemap_extent {
-+ __u64 fe_logical; /* logical offset in bytes for the start of
-+ * the extent from the beginning of the file */
-+ __u64 fe_physical; /* physical offset in bytes for the start
-+ * of the extent from the beginning of the disk */
-+ __u64 fe_length; /* length in bytes for this extent */
-+ __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
-+ __u32 fe_device; /* device number for this extent */
-+};
-+
-+struct fiemap {
-+ __u64 fm_start; /* logical offset (inclusive) at
-+ * which to start mapping (in) */
-+ __u64 fm_length; /* logical length of mapping which
-+ * userspace wants (in) */
-+ __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
-+ __u32 fm_mapped_extents;/* number of extents that were mapped (out) */
-+ __u32 fm_extent_count; /* size of fm_extents array (in) */
-+ __u32 fm_reserved;
-+ struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
-+};
-+
-+/*
-+ * FIEMAP helper definition.
-+ */
-+struct fiemap_extent_info {
-+ unsigned int fi_flags; /* Flags as passed from user */
-+ unsigned int fi_extents_mapped; /* Number of mapped extents */
-+ unsigned int fi_extents_max; /* Size of fiemap_extent array*/
-+ struct fiemap_extent *fi_extents_start; /* Start of fiemap_extent array */
-+};
-+
-+int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
-+int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
-+ u64 phys, u64 len, u32 flags, u32 lun);
-+
-+#define FIEMAP_MAX_OFFSET (~0ULL)
-+
-+#define FIEMAP_FLAG_SYNC 0x00000001 /* sync file data before map */
-+#define FIEMAP_FLAG_XATTR 0x00000002 /* map extended attribute tree */
-+
-+/* ldiskfs only supports FLAG_SYNC flag currently */
-+#define FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR)
-+
-+
-+#define FIEMAP_EXTENT_LAST 0x00000001 /* Last extent in file. */
-+#define FIEMAP_EXTENT_UNKNOWN 0x00000002 /* Data location unknown. */
-+#define FIEMAP_EXTENT_DELALLOC 0x00000004 /* Location still pending.
-+ * Sets EXTENT_UNKNOWN. */
-+#define FIEMAP_EXTENT_NO_DIRECT 0x00000008 /* Data mapping undefined */
-+#define FIEMAP_EXTENT_SECONDARY 0x00000010 /* Data copied offline. May
-+ * set EXTENT_NO_DIRECT. */
-+#define FIEMAP_EXTENT_NET 0x00000020 /* Data stored remotely.
-+ * Sets EXTENT_NO_DIRECT. */
-+#define FIEMAP_EXTENT_DATA_COMPRESSED 0x00000040 /* Data is compressed by fs.
-+ * Sets EXTENT_NO_DIRECT. */
-+#define FIEMAP_EXTENT_DATA_ENCRYPTED 0x00000080 /* Data is encrypted by fs.
-+ * Sets EXTENT_NO_DIRECT. */
-+#define FIEMAP_EXTENT_NOT_ALIGNED 0x00000100 /* Extent offsets may not be
-+ * block aligned. */
-+#define FIEMAP_EXTENT_DATA_INLINE 0x00000200 /* Data mixed with metadata.
-+ * Sets EXTENT_NOT_ALIGNED.*/
-+#define FIEMAP_EXTENT_DATA_TAIL 0x00000400 /* Multiple files in block.
-+ * Sets EXTENT_NOT_ALIGNED.*/
-+#define FIEMAP_EXTENT_UNWRITTEN 0x00000800 /* Space allocated, but
-+ * no data (i.e. zero). */
-+#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
-+ * support extents. Result
-+ * merged for efficiency. */
-+
-+#endif /* _LINUX_EXT3_FIEMAP_H */
-+
+/*
+ * FIEMAP ioctl infrastructure.
+ *
-+ * Copyright 2008 Sun Microsystems, Inc.
++ * Copyright 2008 Sun Microsystems, Inc
+ *
+ * Author: Kalpak Shah <kalpak.shah@sun.com>
+ * Andreas Dilger <adilger@sun.com>
--- /dev/null
+Index: linux-2.6.18/fs/ext3/ioctl.c
+===================================================================
+--- linux-2.6.18.orig/fs/ext3/ioctl.c
++++ linux-2.6.18/fs/ext3/ioctl.c
+@@ -15,7 +15,7 @@
+ #include <linux/time.h>
+ #include <asm/uaccess.h>
+ #include <linux/namei.h>
+-
++#include "fiemap.h"
+
+ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
+ unsigned long arg)
+@@ -272,6 +272,9 @@ flags_err:
+
+ return err;
+ }
++ case EXT3_IOC_FIEMAP: {
++ return ext3_fiemap(inode, filp, cmd, arg);
++ }
+
+
+ default:
+Index: linux-2.6.18/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.6.18.orig/include/linux/ext3_fs.h
++++ linux-2.6.18/include/linux/ext3_fs.h
+@@ -249,7 +249,6 @@ struct ext3_new_group_data {
+ __u32 free_blocks_count;
+ };
+
+-
+ /*
+ * ioctl commands
+ */
+@@ -257,15 +256,16 @@ struct ext3_new_group_data {
+ #define EXT3_IOC_SETFLAGS _IOW('f', 2, long)
+ #define EXT3_IOC_GETVERSION _IOR('f', 3, long)
+ #define EXT3_IOC_SETVERSION _IOW('f', 4, long)
+-#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
++#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long)
++#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
++#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
+ #define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input)
++#define EXT3_IOC_FIEMAP _IOWR('f', 10, struct fiemap)
+ #define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long)
+ #define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long)
+ #ifdef CONFIG_JBD_DEBUG
+ #define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long)
+ #endif
+-#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long)
+-#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
+
+ /*
+ * Mount options
+@@ -1117,6 +1117,8 @@ ext3_get_blocks_wrap(handle_t *handle, s
+ bh->b_size = (ret << inode->i_blkbits);
+ return ret;
+ }
++extern int ext3_fiemap(struct inode *, struct file *, unsigned int,
++ unsigned long);
+
+
+ #endif /* __KERNEL__ */
+Index: linux-2.6.18/include/linux/ext3_extents.h
+===================================================================
+--- linux-2.6.18.orig/include/linux/ext3_extents.h
++++ linux-2.6.18/include/linux/ext3_extents.h
+@@ -142,8 +142,9 @@ struct ext3_ext_path {
+ * callback must return valid extent (passed or newly created)
+ */
+ typedef int (*ext_prepare_callback)(struct inode *, struct ext3_ext_path *,
+- struct ext3_ext_cache *,
+- void *);
++ struct ext3_ext_cache *,
++ struct ext3_extent *, void *);
++#define HAVE_EXT_PREPARE_CB_EXTENT
+
+ #define EXT_CONTINUE 0
+ #define EXT_BREAK 1
+@@ -152,6 +152,26 @@ typedef int (*ext_prepare_callback)(stru
+
+ #define EXT_MAX_BLOCK 0xffffffff
+
++/*
++ * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
++ * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
++ * MSB of ee_len field in the extent datastructure to signify if this
++ * particular extent is an initialized extent or an uninitialized (i.e.
++ * preallocated).
++ * EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
++ * uninitialized extent.
++ * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
++ * uninitialized one. In other words, if MSB of ee_len is set, it is an
++ * uninitialized extent with only one special scenario when ee_len = 0x8000.
++ * In this case we can not have an uninitialized extent of zero length and
++ * thus we make it as a special case of initialized extent with 0x8000 length.
++ * This way we get better extent-to-group alignment for initialized extents.
++ * Hence, the maximum number of blocks we can have in an *initialized*
++ * extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
++ */
++#define EXT_INIT_MAX_LEN (1UL << 15)
++#define EXT_UNINIT_MAX_LEN (EXT_INIT_MAX_LEN - 1)
++
+ #define EXT_FLAGS_CLR_UNKNOWN 0x7 /* Flags cleared on modification */
+ #define EXT_HDR_GEN_BITS 24
+ #define EXT_HDR_GEN_MASK ((1 << EXT_HDR_GEN_BITS) - 1)
+@@ -219,6 +239,13 @@ ext3_ext_invalidate_cache(struct inode *
+ EXT3_I(inode)->i_cached_extent.ec_type = EXT3_EXT_CACHE_NO;
+ }
+
++static inline int ext3_ext_is_uninitialized(struct ext3_extent *ext)
++{
++ /* Extent with ee_len of 0x8000 is treated as an initialized extent */
++ return (le16_to_cpu(ext->ee_len) > EXT_INIT_MAX_LEN);
++}
++
++
+ extern int ext3_ext_search_left(struct inode *, struct ext3_ext_path *, unsigned long *, unsigned long *);
+ extern int ext3_ext_search_right(struct inode *, struct ext3_ext_path *, unsigned long *, unsigned long *);
+ extern int ext3_extent_tree_init(handle_t *, struct inode *);
+Index: linux-2.6.18/fs/ext3/extents.c
+===================================================================
+--- linux-2.6.18.orig/fs/ext3/extents.c
++++ linux-2.6.18/fs/ext3/extents.c
+@@ -42,7 +42,7 @@
+ #include <linux/slab.h>
+ #include <linux/ext3_extents.h>
+ #include <asm/uaccess.h>
+-
++#include "fiemap.h"
+
+ static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed)
+ {
+@@ -1477,7 +1477,7 @@ int ext3_ext_walk_space(struct inode *in
+ }
+
+ BUG_ON(cbex.ec_len == 0);
+- err = func(inode, path, &cbex, cbdata);
++ err = func(inode, path, &cbex, ex, cbdata);
+ ext3_ext_drop_refs(path);
+
+ if (err < 0)
+@@ -2289,6 +2289,143 @@ int ext3_ext_writepage_trans_blocks(stru
+ return needed;
+ }
+
++struct fiemap_internal {
++ struct fiemap *fiemap_s;
++ struct fiemap_extent fm_extent;
++ size_t tot_mapping_len;
++ char *cur_ext_ptr;
++ int current_extent;
++ int err;
++};
++
++/*
++ * Callback function called for each extent to gather fiemap information.
++ */
++int ext3_ext_fiemap_cb(struct inode *inode, struct ext3_ext_path *path,
++ struct ext3_ext_cache *newex, struct ext3_extent *ex,
++ void *data)
++{
++ struct fiemap_internal *fiemap_i = data;
++ struct fiemap *fiemap_s = fiemap_i->fiemap_s;
++ struct fiemap_extent *fm_extent = &fiemap_i->fm_extent;
++ int current_extent = fiemap_i->current_extent;
++ unsigned long blksize_bits = inode->i_sb->s_blocksize_bits;
++
++ /*
++ * ext3_ext_walk_space returns a hole for extents that have not been
++ * allocated yet.
++ */
++ if (((u64)(newex->ec_block + newex->ec_len) << blksize_bits >=
++ inode->i_size) && !ext3_ext_is_uninitialized(ex) &&
++ newex->ec_type == EXT3_EXT_CACHE_GAP)
++ return EXT_BREAK;
++
++ /*
++ * We only need to return number of extents.
++ */
++ if (fiemap_s->fm_flags & FIEMAP_FLAG_NUM_EXTENTS)
++ goto count_extents;
++
++ if (current_extent >= fiemap_s->fm_extent_count)
++ return EXT_BREAK;
++
++ memset(fm_extent, 0, sizeof(*fm_extent));
++ fm_extent->fe_offset = (__u64)newex->ec_start << blksize_bits;
++ fm_extent->fe_length = (__u64)newex->ec_len << blksize_bits;
++ fiemap_i->tot_mapping_len += fm_extent->fe_length;
++
++ if (newex->ec_type == EXT3_EXT_CACHE_GAP)
++ fm_extent->fe_flags |= FIEMAP_EXTENT_HOLE;
++
++ if (ext3_ext_is_uninitialized(ex))
++ fm_extent->fe_flags |= (FIEMAP_EXTENT_DELALLOC |
++ FIEMAP_EXTENT_UNMAPPED);
++
++ /*
++ * Mark this fiemap_extent as FIEMAP_EXTENT_EOF if it's past the end
++ * of file.
++ */
++ if ((u64)(newex->ec_block + newex->ec_len) << blksize_bits >=
++ inode->i_size)
++ fm_extent->fe_flags |= FIEMAP_EXTENT_EOF;
++
++ if (!copy_to_user(fiemap_i->cur_ext_ptr, fm_extent,
++ sizeof(struct fiemap_extent))) {
++ fiemap_i->cur_ext_ptr += sizeof(struct fiemap_extent);
++ } else {
++ fiemap_i->err = -EFAULT;
++ return EXT_BREAK;
++ }
++
++count_extents:
++ fiemap_i->current_extent++;
++
++ /*
++ * Stop if we are beyond requested mapping size but return complete last
++ * extent.
++ */
++ if ((u64)(newex->ec_block + newex->ec_len) << blksize_bits >=
++ fiemap_s->fm_length)
++ return EXT_BREAK;
++
++ return EXT_CONTINUE;
++}
++
++int ext3_fiemap(struct inode *inode, struct file *filp, unsigned int cmd,
++ unsigned long arg)
++{
++ struct fiemap *fiemap_s;
++ struct fiemap_internal fiemap_i;
++ struct fiemap_extent *last_extent;
++ ext3_fsblk_t start_blk;
++ int err = 0;
++
++ if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL))
++ return -EOPNOTSUPP;
++
++ fiemap_s = kmalloc(sizeof(*fiemap_s), GFP_KERNEL);
++ if (fiemap_s == NULL)
++ return -ENOMEM;
++ if (copy_from_user(fiemap_s, (struct fiemap __user *)arg,
++ sizeof(*fiemap_s)))
++ return -EFAULT;
++
++ if (fiemap_s->fm_flags & FIEMAP_FLAG_INCOMPAT)
++ return -EOPNOTSUPP;
++
++ if (fiemap_s->fm_flags & FIEMAP_FLAG_SYNC)
++ ext3_sync_file(filp, filp->f_dentry, 1);
++
++ start_blk = (fiemap_s->fm_start + inode->i_sb->s_blocksize - 1) >>
++ inode->i_sb->s_blocksize_bits;
++ fiemap_i.fiemap_s = fiemap_s;
++ fiemap_i.tot_mapping_len = 0;
++ fiemap_i.cur_ext_ptr = (char *)(arg + sizeof(*fiemap_s));
++ fiemap_i.current_extent = 0;
++ fiemap_i.err = 0;
++
++ /*
++ * Walk the extent tree gathering extent information
++ */
++ mutex_lock(&EXT3_I(inode)->truncate_mutex);
++ err = ext3_ext_walk_space(inode, start_blk , EXT_MAX_BLOCK - start_blk,
++ ext3_ext_fiemap_cb, &fiemap_i);
++ mutex_unlock(&EXT3_I(inode)->truncate_mutex);
++ if (err)
++ return err;
++
++ fiemap_s->fm_extent_count = fiemap_i.current_extent;
++ fiemap_s->fm_length = fiemap_i.tot_mapping_len;
++ if (fiemap_i.current_extent != 0 &&
++ !(fiemap_s->fm_flags & FIEMAP_FLAG_NUM_EXTENTS)) {
++ last_extent = &fiemap_i.fm_extent;
++ last_extent->fe_flags |= FIEMAP_EXTENT_LAST;
++ }
++ err = copy_to_user((void *)arg, fiemap_s, sizeof(*fiemap_s));
++
++ return err;
++}
++
+ EXPORT_SYMBOL(ext3_mark_inode_dirty);
+ EXPORT_SYMBOL(ext3_ext_invalidate_cache);
+ EXPORT_SYMBOL(ext3_ext_insert_extent);
+Index: linux-2.6.18/fs/ext3/fiemap.h
+===================================================================
+--- /dev/null
++++ linux-2.6.18/fs/ext3/fiemap.h
+@@ -0,0 +1,49 @@
++/*
++ * linux/fs/ext3/fiemap.h
++ *
++ * Copyright 2008 Sun Microsystems, Inc.
++ *
++ * Author: Kalpak Shah <kalpak@clusterfs.com>
++ */
++
++#ifndef _LINUX_EXT3_FIEMAP_H
++#define _LINUX_EXT3_FIEMAP_H
++
++struct fiemap_extent {
++ __u64 fe_offset; /* offset in bytes for the start of the extent */
++ __u64 fe_length; /* length in bytes for the extent */
++ __u32 fe_flags; /* returned FIEMAP_EXTENT_* flags for the extent */
++ __u32 fe_lun; /* logical device number for extent (starting at 0)*/
++};
++
++/*
++ * fiemap is not ext3-specific and should be moved into fs.h eventually.
++ */
++
++struct fiemap {
++ __u64 fm_start; /* logical starting byte offset (in/out) */
++ __u64 fm_length; /* logical length of map (in/out) */
++ __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
++ __u32 fm_extent_count; /* number of extents in fm_extents (in/out) */
++ __u64 fm_unused;
++ struct fiemap_extent fm_extents[0];
++};
++
++#define FIEMAP_FLAG_SYNC 0x00000001 /* sync file data before map */
++#define FIEMAP_FLAG_HSM_READ 0x00000002 /* get data from HSM before map */
++#define FIEMAP_FLAG_NUM_EXTENTS 0x00000004 /* return only number of extents */
++#define FIEMAP_FLAG_INCOMPAT 0xff000000 /* error for unknown flags in here */
++
++#define FIEMAP_EXTENT_HOLE 0x00000001 /* has no data or space allocation */
++#define FIEMAP_EXTENT_UNWRITTEN 0x00000002 /* space allocated, but no data */
++#define FIEMAP_EXTENT_UNMAPPED 0x00000004 /* has data but no space allocation*/
++#define FIEMAP_EXTENT_ERROR 0x00000008 /* mapping error, errno in fe_start*/
++#define FIEMAP_EXTENT_NO_DIRECT 0x00000010 /* cannot access data directly */
++#define FIEMAP_EXTENT_LAST 0x00000020 /* last extent in the file */
++#define FIEMAP_EXTENT_DELALLOC 0x00000040 /* has data but not yet written,
++ * must have EXTENT_UNKNOWN set */
++#define FIEMAP_EXTENT_SECONDARY 0x00000080 /* data (also) in secondary storage,
++ * not in primary if EXTENT_UNKNOWN*/
++#define FIEMAP_EXTENT_EOF 0x00000100 /* if fm_start+fm_len is beyond EOF*/
++
++#endif /* _LINUX_EXT3_FIEMAP_H */
/*
* ioctl commands in 32 bit emulation
-@@ -281,6 +282,9 @@ struct ext3_new_group_data {
+@@ -280,6 +281,8 @@ struct ext3_new_group_data {
+ #define EXT3_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION
#define EXT3_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION
-
+/* FIEMAP flags supported by ext3 */
+#define EXT3_FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC)
-+
+
/*
* Mount options
- */
-@@ -1056,6 +1060,9 @@ extern int ext3_block_truncate_page(hand
+@@ -1056,6 +1059,9 @@ extern int ext3_block_truncate_page(hand
extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
unsigned long);
extern long ext3_compat_ioctl (struct file *, unsigned int, unsigned long);
+struct fiemap_extent_info;
+extern int ext3_fiemap(struct inode *, struct fiemap_extent_info *, __u64,
-+ __u64);
++ __u64);
/* namei.c */
extern int ext3_orphan_add(handle_t *, struct inode *);
-@@ -1133,7 +1140,6 @@ ext3_get_blocks_wrap(handle_t *handle, s
+@@ -1133,7 +1139,6 @@ ext3_get_blocks_wrap(handle_t *handle, s
return ret;
}
--- /dev/null
+Index: linux-2.6.9-67.0.22/fs/ext3/ioctl.c
+===================================================================
+--- linux-2.6.9-67.0.22.orig/fs/ext3/ioctl.c
++++ linux-2.6.9-67.0.22/fs/ext3/ioctl.c
+@@ -157,7 +157,7 @@ int ioctl_fiemap(struct inode *inode, st
+ return -EFAULT;
+
+ if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
+- filemap_write_and_wait(inode->i_mapping);
++ ext3_sync_file(filp, filp->f_dentry, 1);
+
+ error = ext3_fiemap(inode, &fieinfo, fiemap.fm_start, len);
+ fiemap.fm_flags = fieinfo.fi_flags;
-Index: linux-2.6.22.19/fs/ext3/ialloc.c
+Index: linux-2.6.18-92.1.17/fs/ext3/ialloc.c
===================================================================
---- linux-2.6.22.19.orig/fs/ext3/ialloc.c
-+++ linux-2.6.22.19/fs/ext3/ialloc.c
+--- linux-2.6.18-92.1.17.orig/fs/ext3/ialloc.c
++++ linux-2.6.18-92.1.17/fs/ext3/ialloc.c
@@ -521,12 +521,15 @@ struct inode *ext3_new_inode(handle_t *h
return ERR_PTR(-EPERM);
es = sbi->s_es;
if (goal) {
group = (goal - 1) / EXT3_INODES_PER_GROUP(sb);
-Index: linux-2.6.22.19/fs/ext3/super.c
+Index: linux-2.6.18-92.1.17/fs/ext3/super.c
===================================================================
---- linux-2.6.22.19.orig/fs/ext3/super.c
-+++ linux-2.6.22.19/fs/ext3/super.c
+--- linux-2.6.18-92.1.17.orig/fs/ext3/super.c
++++ linux-2.6.18-92.1.17/fs/ext3/super.c
@@ -45,6 +45,12 @@
#include "namei.h"
#include "group.h"
static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
unsigned long journal_devnum);
static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
-@@ -440,6 +446,7 @@ static void ext3_put_super (struct super
+@@ -439,6 +445,7 @@ static void ext3_put_super (struct super
}
if (sbi->s_mmp_tsk)
kthread_stop(sbi->s_mmp_tsk);
if (sbi->s_dev_proc) {
remove_proc_entry(sbi->s_dev_proc->name, proc_root_ext3);
sbi->s_dev_proc = NULL;
-@@ -1849,6 +1856,45 @@ failed:
+@@ -1854,6 +1861,45 @@ failed:
return 1;
}
static int ext3_fill_super (struct super_block *sb, void *data, int silent)
{
-@@ -1870,6 +1916,7 @@ static int ext3_fill_super (struct super
+@@ -1875,6 +1921,7 @@ static int ext3_fill_super (struct super
int i;
int needs_recovery;
__le32 features;
+ struct proc_dir_entry *proc;
- sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+ sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
-@@ -1897,6 +1944,23 @@ static int ext3_fill_super (struct super
+@@ -1903,6 +1950,23 @@ static int ext3_fill_super (struct super
unlock_kernel();
if (sbi->s_dev_proc) {
remove_proc_entry(sbi->s_dev_proc->name, proc_root_ext3);
sbi->s_dev_proc = NULL;
-Index: linux-2.6.22.19/include/linux/ext3_fs_sb.h
+Index: linux-2.6.18-92.1.17/include/linux/ext3_fs_sb.h
===================================================================
---- linux-2.6.22.19.orig/include/linux/ext3_fs_sb.h
-+++ linux-2.6.22.19/include/linux/ext3_fs_sb.h
+--- linux-2.6.18-92.1.17.orig/include/linux/ext3_fs_sb.h
++++ linux-2.6.18-92.1.17/include/linux/ext3_fs_sb.h
@@ -132,6 +132,8 @@ struct ext3_sb_info {
unsigned long s_mb_last_group;
unsigned long s_mb_last_start;
-Index: linux-2.6.15/include/linux/ext3_fs.h
+Index: linux-2.6.16.i686/include/linux/ext3_fs.h
===================================================================
---- linux-2.6.15.orig/include/linux/ext3_fs.h
-+++ linux-2.6.15/include/linux/ext3_fs.h
-@@ -57,6 +57,14 @@ struct statfs;
+--- linux-2.6.16.i686.orig/include/linux/ext3_fs.h 2006-05-30 22:55:32.000000000 +0800
++++ linux-2.6.16.i686/include/linux/ext3_fs.h 2006-05-30 23:02:59.000000000 +0800
+@@ -57,6 +57,14 @@
#define ext3_debug(f, a...) do {} while (0)
#endif
/*
* Special inodes numbers
*/
-@@ -383,6 +391,7 @@ struct ext3_inode {
+@@ -383,6 +391,7 @@
#define EXT3_MOUNT_IOPEN_NOPRIV 0x800000/* Make iopen world-readable */
#define EXT3_MOUNT_EXTENTS 0x1000000/* Extents support */
#define EXT3_MOUNT_EXTDEBUG 0x2000000/* Extents debug */
/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
#ifndef clear_opt
-@@ -405,6 +414,14 @@ struct ext3_inode {
+@@ -404,6 +413,14 @@
#define ext3_find_first_zero_bit ext2_find_first_zero_bit
#define ext3_find_next_zero_bit ext2_find_next_zero_bit
/*
* Maximal mount counts between two filesystem checks
*/
-@@ -744,7 +761,9 @@ extern int ext3_bg_has_super(struct supe
+@@ -744,7 +753,9 @@
extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group);
extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *);
extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long,
extern void ext3_free_blocks_sb (handle_t *, struct super_block *,
unsigned long, unsigned long, int *);
extern unsigned long ext3_count_free_blocks (struct super_block *);
-@@ -866,6 +885,17 @@ extern void ext3_extents_initialize_bloc
+@@ -865,6 +874,17 @@
extern int ext3_ext_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
#endif /* __KERNEL__ */
/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */
-Index: linux-2.6.15/include/linux/ext3_fs_sb.h
+Index: linux-2.6.16.i686/include/linux/ext3_fs_sb.h
===================================================================
---- linux-2.6.15.orig/include/linux/ext3_fs_sb.h
-+++ linux-2.6.15/include/linux/ext3_fs_sb.h
+--- linux-2.6.16.i686.orig/include/linux/ext3_fs_sb.h 2006-03-20 13:53:29.000000000 +0800
++++ linux-2.6.16.i686/include/linux/ext3_fs_sb.h 2006-05-30 23:02:59.000000000 +0800
@@ -21,8 +21,14 @@
#include <linux/wait.h>
#include <linux/blockgroup_lock.h>
/*
* third extended-fs super-block data in memory
-@@ -78,6 +84,43 @@ struct ext3_sb_info {
+@@ -78,6 +84,43 @@
char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */
int s_jquota_fmt; /* Format of quota to use */
#endif
+ unsigned long s_mb_buddies_generated;
+ unsigned long long s_mb_generation_time;
};
-
++
+#define EXT3_GROUP_INFO(sb, group) \
+ EXT3_SB(sb)->s_group_info[(group) >> EXT3_DESC_PER_BLOCK_BITS(sb)] \
+ [(group) & (EXT3_DESC_PER_BLOCK(sb) - 1)]
-+
+
#endif /* _LINUX_EXT3_FS_SB */
-Index: linux-2.6.15/fs/ext3/super.c
+Index: linux-2.6.16.i686/fs/ext3/super.c
===================================================================
---- linux-2.6.15.orig/fs/ext3/super.c
-+++ linux-2.6.15/fs/ext3/super.c
-@@ -391,6 +391,7 @@ static void ext3_put_super (struct super
+--- linux-2.6.16.i686.orig/fs/ext3/super.c 2006-05-30 22:55:32.000000000 +0800
++++ linux-2.6.16.i686/fs/ext3/super.c 2006-05-30 23:02:59.000000000 +0800
+@@ -392,6 +392,7 @@
struct ext3_super_block *es = sbi->s_es;
int i;
ext3_ext_release(sb);
ext3_xattr_put_super(sb);
journal_destroy(sbi->s_journal);
-@@ -640,6 +641,7 @@ enum {
+@@ -640,6 +641,7 @@
Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
Opt_extents, Opt_noextents, Opt_extdebug,
Opt_grpquota
};
-@@ -693,6 +695,9 @@ static match_table_t tokens = {
+@@ -694,6 +695,9 @@
{Opt_extents, "extents"},
{Opt_noextents, "noextents"},
{Opt_extdebug, "extdebug"},
{Opt_barrier, "barrier=%u"},
{Opt_err, NULL},
{Opt_resize, "resize"},
-@@ -1032,6 +1037,19 @@ clear_qf_name:
+@@ -1041,6 +1043,19 @@
case Opt_extdebug:
set_opt (sbi->s_mount_opt, EXTDEBUG);
break;
default:
printk (KERN_ERR
"EXT3-fs: Unrecognized mount option \"%s\" "
-@@ -1755,6 +1773,7 @@ static int ext3_fill_super (struct super
+@@ -1766,6 +1771,7 @@
ext3_count_dirs(sb));
ext3_ext_init(sb);
lock_kernel();
return 0;
-@@ -2669,7 +2688,13 @@ static struct file_system_type ext3_fs_t
+@@ -2699,7 +2705,13 @@
static int __init init_ext3_fs(void)
{
if (err)
return err;
err = init_inodecache();
-@@ -2691,6 +2716,7 @@ static void __exit exit_ext3_fs(void)
+@@ -2721,6 +2733,7 @@
unregister_filesystem(&ext3_fs_type);
destroy_inodecache();
exit_ext3_xattr();
+ exit_ext3_proc();
}
- int ext3_map_inode_page(struct inode *inode, struct page *page,
-Index: linux-2.6.15/fs/ext3/extents.c
+ int ext3_prep_san_write(struct inode *inode, long *blocks,
+Index: linux-2.6.16.i686/fs/ext3/extents.c
===================================================================
---- linux-2.6.15.orig/fs/ext3/extents.c
-+++ linux-2.6.15/fs/ext3/extents.c
-@@ -779,7 +779,7 @@ cleanup:
+--- linux-2.6.16.i686.orig/fs/ext3/extents.c 2006-05-30 22:55:32.000000000 +0800
++++ linux-2.6.16.i686/fs/ext3/extents.c 2006-05-30 23:02:59.000000000 +0800
+@@ -771,7 +771,7 @@
for (i = 0; i < depth; i++) {
if (!ablocks[i])
continue;
}
}
kfree(ablocks);
-@@ -1438,7 +1438,7 @@ int ext3_ext_rm_idx(handle_t *handle, st
+@@ -1428,7 +1428,7 @@
path->p_idx->ei_leaf);
bh = sb_find_get_block(tree->inode->i_sb, path->p_idx->ei_leaf);
ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf);
return err;
}
-@@ -1923,10 +1923,12 @@ ext3_remove_blocks(struct ext3_extents_t
+@@ -1913,10 +1913,12 @@
int needed = ext3_remove_blocks_credits(tree, ex, from, to);
handle_t *handle = ext3_journal_start(tree->inode, needed);
struct buffer_head *bh;
if (from >= ex->ee_block && to == ex->ee_block + ex->ee_len - 1) {
/* tail removal */
unsigned long num, start;
-@@ -1938,7 +1940,7 @@ ext3_remove_blocks(struct ext3_extents_t
+@@ -1928,7 +1930,7 @@
bh = sb_find_get_block(tree->inode->i_sb, start + i);
ext3_forget(handle, 0, tree->inode, bh, start + i);
}
} else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) {
printk("strange request: removal %lu-%lu from %u:%u\n",
from, to, ex->ee_block, ex->ee_len);
-Index: linux-2.6.15/fs/ext3/inode.c
+Index: linux-2.6.16.i686/fs/ext3/inode.c
===================================================================
---- linux-2.6.15.orig/fs/ext3/inode.c
-+++ linux-2.6.15/fs/ext3/inode.c
-@@ -568,7 +568,7 @@ static int ext3_alloc_branch(handle_t *h
+--- linux-2.6.16.i686.orig/fs/ext3/inode.c 2006-05-30 22:55:32.000000000 +0800
++++ linux-2.6.16.i686/fs/ext3/inode.c 2006-05-30 23:02:59.000000000 +0800
+@@ -568,7 +568,7 @@
ext3_journal_forget(handle, branch[i].bh);
}
for (i = 0; i < keys; i++)
return err;
}
-@@ -1861,7 +1861,7 @@ ext3_clear_blocks(handle_t *handle, stru
+@@ -1862,7 +1862,7 @@
}
}
}
/**
-@@ -2034,7 +2034,7 @@ static void ext3_free_branches(handle_t
+@@ -2035,7 +2035,7 @@
ext3_journal_test_restart(handle, inode);
}
if (parent_bh) {
/*
-Index: linux-2.6.15/fs/ext3/balloc.c
+Index: linux-2.6.16.i686/fs/ext3/balloc.c
===================================================================
---- linux-2.6.15.orig/fs/ext3/balloc.c
-+++ linux-2.6.15/fs/ext3/balloc.c
-@@ -81,7 +81,7 @@ struct ext3_group_desc * ext3_get_group_
+--- linux-2.6.16.i686.orig/fs/ext3/balloc.c 2006-03-20 13:53:29.000000000 +0800
++++ linux-2.6.16.i686/fs/ext3/balloc.c 2006-05-30 23:02:59.000000000 +0800
+@@ -80,7 +80,7 @@
*
* Return buffer_head on success or NULL in case of failure.
*/
read_block_bitmap(struct super_block *sb, unsigned int block_group)
{
struct ext3_group_desc * desc;
-@@ -492,24 +492,6 @@ error_return:
+@@ -491,24 +491,6 @@
return;
}
/*
* For ext3 allocations, we must not reuse any blocks which are
* allocated in the bitmap buffer's "last committed data" copy. This
-@@ -1155,7 +1137,7 @@ int ext3_should_retry_alloc(struct super
+@@ -1154,7 +1136,7 @@
* bitmap, and then for any free bit if that fails.
* This function also updates quota and i_blocks field.
*/
unsigned long goal, int *errp)
{
struct buffer_head *bitmap_bh = NULL;
-Index: linux-2.6.15/fs/ext3/xattr.c
+Index: linux-2.6.16.i686/fs/ext3/xattr.c
===================================================================
---- linux-2.6.15.orig/fs/ext3/xattr.c
-+++ linux-2.6.15/fs/ext3/xattr.c
-@@ -484,7 +484,7 @@ ext3_xattr_release_block(handle_t *handl
+--- linux-2.6.16.i686.orig/fs/ext3/xattr.c 2006-03-20 13:53:29.000000000 +0800
++++ linux-2.6.16.i686/fs/ext3/xattr.c 2006-05-30 23:02:59.000000000 +0800
+@@ -484,7 +484,7 @@
ea_bdebug(bh, "refcount now=0; freeing");
if (ce)
mb_cache_entry_free(ce);
get_bh(bh);
ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
} else {
-@@ -804,7 +804,7 @@ inserted:
+@@ -804,7 +804,7 @@
new_bh = sb_getblk(sb, block);
if (!new_bh) {
getblk_failed:
error = -EIO;
goto cleanup;
}
-Index: linux-2.6.15/fs/ext3/mballoc.c
+Index: linux-2.6.16.i686/fs/ext3/mballoc.c
===================================================================
---- /dev/null
-+++ linux-2.6.15/fs/ext3/mballoc.c
-@@ -0,0 +1,2728 @@
+--- linux-2.6.16.i686.orig/fs/ext3/mballoc.c 2006-05-31 04:14:15.752410384 +0800
++++ linux-2.6.16.i686/fs/ext3/mballoc.c 2006-05-30 23:03:38.000000000 +0800
+@@ -0,0 +1,2726 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.
+ * Written by Alex Tomas <alex@clusterfs.com>
+ remove_proc_entry(EXT3_MB_ORDER2_REQ, proc_root_ext3);
+ remove_proc_entry(EXT3_ROOT, proc_root_fs);
+}
-+
-+EXPORT_SYMBOL(ext3_free_blocks);
-Index: linux-2.6.15/fs/ext3/Makefile
+Index: linux-2.6.16.i686/fs/ext3/Makefile
===================================================================
---- linux-2.6.15.orig/fs/ext3/Makefile
-+++ linux-2.6.15/fs/ext3/Makefile
-@@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o
+--- linux-2.6.16.i686.orig/fs/ext3/Makefile 2006-05-30 22:55:32.000000000 +0800
++++ linux-2.6.16.i686/fs/ext3/Makefile 2006-05-30 23:02:59.000000000 +0800
+@@ -6,7 +6,7 @@
ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
ioctl.o namei.o super.o symlink.o hash.o resize.o \
-Index: linux-2.6.10/include/linux/ext3_fs.h
+Index: linux-2.6.9-full/include/linux/ext3_fs.h
===================================================================
---- linux-2.6.10.orig/include/linux/ext3_fs.h
-+++ linux-2.6.10/include/linux/ext3_fs.h
+--- linux-2.6.9-full.orig/include/linux/ext3_fs.h 2006-06-01 14:58:46.000000000 +0400
++++ linux-2.6.9-full/include/linux/ext3_fs.h 2006-10-24 12:54:31.000000000 +0400
@@ -57,6 +57,14 @@ struct statfs;
#define ext3_debug(f, a...) do {} while (0)
#endif
/*
* Special inodes numbers
*/
-@@ -362,6 +370,7 @@ struct ext3_inode {
+@@ -365,6 +373,7 @@ struct ext3_inode {
#define EXT3_MOUNT_IOPEN_NOPRIV 0x100000/* Make iopen world-readable */
#define EXT3_MOUNT_EXTENTS 0x200000/* Extents support */
#define EXT3_MOUNT_EXTDEBUG 0x400000/* Extents debug */
/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
#ifndef clear_opt
-@@ -384,6 +393,14 @@ struct ext3_inode {
+@@ -387,6 +396,14 @@ struct ext3_inode {
#define ext3_find_first_zero_bit ext2_find_first_zero_bit
#define ext3_find_next_zero_bit ext2_find_next_zero_bit
/*
* Maximal mount counts between two filesystem checks
*/
-@@ -723,7 +740,8 @@ extern int ext3_bg_has_super(struct supe
+@@ -726,7 +743,8 @@ extern int ext3_bg_has_super(struct supe
extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group);
extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *);
extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long,
extern void ext3_free_blocks_sb (handle_t *, struct super_block *,
unsigned long, unsigned long, int *);
extern unsigned long ext3_count_free_blocks (struct super_block *);
-@@ -854,6 +872,17 @@ extern void ext3_ext_init(struct super_b
- extern void ext3_ext_release(struct super_block *);
- extern void ext3_extents_initialize_blockmap(handle_t *, struct inode *);
+@@ -857,6 +874,17 @@ extern void ext3_extents_initialize_bloc
+ extern int ext3_ext_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+/* mballoc.c */
+extern long ext3_mb_stats;
#endif /* __KERNEL__ */
/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */
-Index: linux-2.6.10/include/linux/ext3_fs_sb.h
+Index: linux-2.6.9-full/include/linux/ext3_fs_sb.h
===================================================================
---- linux-2.6.10.orig/include/linux/ext3_fs_sb.h
-+++ linux-2.6.10/include/linux/ext3_fs_sb.h
+--- linux-2.6.9-full.orig/include/linux/ext3_fs_sb.h 2006-05-18 23:57:04.000000000 +0400
++++ linux-2.6.9-full/include/linux/ext3_fs_sb.h 2006-10-24 12:54:31.000000000 +0400
@@ -23,9 +23,15 @@
#define EXT_INCLUDE
#include <linux/blockgroup_lock.h>
+ [(group) & (EXT3_DESC_PER_BLOCK(sb) - 1)]
+
#endif /* _LINUX_EXT3_FS_SB */
-Index: linux-2.6.10/fs/ext3/super.c
+Index: linux-2.6.9-full/fs/ext3/super.c
===================================================================
---- linux-2.6.10.orig/fs/ext3/super.c
-+++ linux-2.6.10/fs/ext3/super.c
+--- linux-2.6.9-full.orig/fs/ext3/super.c 2006-06-01 14:58:46.000000000 +0400
++++ linux-2.6.9-full/fs/ext3/super.c 2006-10-24 12:54:31.000000000 +0400
@@ -394,6 +394,7 @@ void ext3_put_super (struct super_block
struct ext3_super_block *es = sbi->s_es;
int i;
default:
printk (KERN_ERR
"EXT3-fs: Unrecognized mount option \"%s\" "
-@@ -1647,6 +1665,7 @@ static int ext3_fill_super (struct super
+@@ -1651,6 +1669,7 @@ static int ext3_fill_super (struct super
ext3_count_dirs(sb));
ext3_ext_init(sb);
+ exit_ext3_proc();
}
- int ext3_map_inode_page(struct inode *inode, struct page *page,
-Index: linux-2.6.10/fs/ext3/extents.c
+ int ext3_prep_san_write(struct inode *inode, long *blocks,
+Index: linux-2.6.9-full/fs/ext3/extents.c
===================================================================
---- linux-2.6.10.orig/fs/ext3/extents.c
-+++ linux-2.6.10/fs/ext3/extents.c
-@@ -780,7 +780,7 @@ cleanup:
+--- linux-2.6.9-full.orig/fs/ext3/extents.c 2006-06-01 14:58:46.000000000 +0400
++++ linux-2.6.9-full/fs/ext3/extents.c 2006-10-24 12:54:31.000000000 +0400
+@@ -777,7 +777,7 @@ cleanup:
for (i = 0; i < depth; i++) {
if (!ablocks[i])
continue;
}
}
kfree(ablocks);
-@@ -1439,7 +1439,7 @@ int ext3_ext_rm_idx(handle_t *handle, st
+@@ -1434,7 +1434,7 @@ int ext3_ext_rm_idx(handle_t *handle, st
path->p_idx->ei_leaf);
bh = sb_find_get_block(tree->inode->i_sb, path->p_idx->ei_leaf);
ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf);
return err;
}
-@@ -1924,10 +1924,12 @@ ext3_remove_blocks(struct ext3_extents_t
+@@ -1919,10 +1919,12 @@ ext3_remove_blocks(struct ext3_extents_t
int needed = ext3_remove_blocks_credits(tree, ex, from, to);
handle_t *handle = ext3_journal_start(tree->inode, needed);
struct buffer_head *bh;
if (from >= ex->ee_block && to == ex->ee_block + ex->ee_len - 1) {
/* tail removal */
unsigned long num, start;
-@@ -1939,7 +1941,7 @@ ext3_remove_blocks(struct ext3_extents_t
+@@ -1934,7 +1936,7 @@ ext3_remove_blocks(struct ext3_extents_t
bh = sb_find_get_block(tree->inode->i_sb, start + i);
ext3_forget(handle, 0, tree->inode, bh, start + i);
}
} else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) {
printk("strange request: removal %lu-%lu from %u:%u\n",
from, to, ex->ee_block, ex->ee_len);
-Index: linux-2.6.10/fs/ext3/inode.c
+Index: linux-2.6.9-full/fs/ext3/inode.c
===================================================================
---- linux-2.6.10.orig/fs/ext3/inode.c
-+++ linux-2.6.10/fs/ext3/inode.c
+--- linux-2.6.9-full.orig/fs/ext3/inode.c 2006-06-01 14:58:46.000000000 +0400
++++ linux-2.6.9-full/fs/ext3/inode.c 2006-10-24 12:54:31.000000000 +0400
@@ -572,7 +572,7 @@ static int ext3_alloc_branch(handle_t *h
ext3_journal_forget(handle, branch[i].bh);
}
return err;
}
-@@ -1833,7 +1833,7 @@ ext3_clear_blocks(handle_t *handle, stru
+@@ -1831,7 +1831,7 @@ ext3_clear_blocks(handle_t *handle, stru
}
}
}
/**
-@@ -2006,7 +2006,7 @@ static void ext3_free_branches(handle_t
+@@ -2004,7 +2004,7 @@ static void ext3_free_branches(handle_t
ext3_journal_test_restart(handle, inode);
}
if (parent_bh) {
/*
-Index: linux-2.6.10/fs/ext3/balloc.c
+Index: linux-2.6.9-full/fs/ext3/balloc.c
===================================================================
---- linux-2.6.10.orig/fs/ext3/balloc.c
-+++ linux-2.6.10/fs/ext3/balloc.c
+--- linux-2.6.9-full.orig/fs/ext3/balloc.c 2006-03-10 18:20:03.000000000 +0300
++++ linux-2.6.9-full/fs/ext3/balloc.c 2006-10-24 12:54:31.000000000 +0400
@@ -79,7 +79,7 @@ struct ext3_group_desc * ext3_get_group_
*
* Return buffer_head on success or NULL in case of failure.
read_block_bitmap(struct super_block *sb, unsigned int block_group)
{
struct ext3_group_desc * desc;
-@@ -449,24 +449,6 @@ error_return:
+@@ -451,24 +451,6 @@ error_return:
return;
}
/*
* For ext3 allocations, we must not reuse any blocks which are
* allocated in the bitmap buffer's "last committed data" copy. This
-@@ -1129,7 +1111,7 @@ int ext3_should_retry_alloc(struct super
+@@ -1131,7 +1113,7 @@ int ext3_should_retry_alloc(struct super
* bitmap, and then for any free bit if that fails.
* This function also updates quota and i_blocks field.
*/
unsigned long goal, int *errp)
{
struct buffer_head *bitmap_bh = NULL;
-Index: linux-2.6.10/fs/ext3/xattr.c
+Index: linux-2.6.9-full/fs/ext3/xattr.c
===================================================================
---- linux-2.6.10.orig/fs/ext3/xattr.c
-+++ linux-2.6.10/fs/ext3/xattr.c
-@@ -1287,7 +1287,7 @@ ext3_xattr_set_handle2(handle_t *handle,
+--- linux-2.6.9-full.orig/fs/ext3/xattr.c 2006-05-18 23:57:04.000000000 +0400
++++ linux-2.6.9-full/fs/ext3/xattr.c 2006-10-24 12:54:31.000000000 +0400
+@@ -1281,7 +1281,7 @@ ext3_xattr_set_handle2(handle_t *handle,
new_bh = sb_getblk(sb, block);
if (!new_bh) {
getblk_failed:
error = -EIO;
goto cleanup;
}
-@@ -1334,7 +1334,7 @@ getblk_failed:
+@@ -1328,7 +1328,7 @@ getblk_failed:
if (ce)
mb_cache_entry_free(ce);
ea_bdebug(old_bh, "freeing");
/* ext3_forget() calls bforget() for us, but we
let our caller release old_bh, so we need to
-@@ -1433,7 +1433,7 @@ ext3_xattr_delete_inode(handle_t *handle
+@@ -1427,7 +1427,7 @@ ext3_xattr_delete_inode(handle_t *handle
if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
if (ce)
mb_cache_entry_free(ce);
get_bh(bh);
ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl);
} else {
-Index: linux-2.6.10/fs/ext3/mballoc.c
+Index: linux-2.6.9-full/fs/ext3/mballoc.c
===================================================================
---- /dev/null
-+++ linux-2.6.10/fs/ext3/mballoc.c
-@@ -0,0 +1,2728 @@
+--- linux-2.6.9-full.orig/fs/ext3/mballoc.c 2006-10-23 18:07:54.821533176 +0400
++++ linux-2.6.9-full/fs/ext3/mballoc.c 2006-10-24 13:00:56.000000000 +0400
+@@ -0,0 +1,2726 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.
+ * Written by Alex Tomas <alex@clusterfs.com>
+ remove_proc_entry(EXT3_MB_ORDER2_REQ, proc_root_ext3);
+ remove_proc_entry(EXT3_ROOT, proc_root_fs);
+}
-+
-+EXPORT_SYMBOL(ext3_free_blocks);
-Index: linux-2.6.10/fs/ext3/Makefile
+Index: linux-2.6.9-full/fs/ext3/Makefile
===================================================================
---- linux-2.6.10.orig/fs/ext3/Makefile
-+++ linux-2.6.10/fs/ext3/Makefile
+--- linux-2.6.9-full.orig/fs/ext3/Makefile 2006-06-01 14:58:46.000000000 +0400
++++ linux-2.6.9-full/fs/ext3/Makefile 2006-10-24 12:54:31.000000000 +0400
@@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o
ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
A checksum of each group descriptor is used to ensure that corruption in
the group descriptor's bit flags does not cause incorrect operation.
-Index: linux-2.6.16.54-0.2.5/include/linux/ext3_fs.h
+Index: linux-2.6.16.60-0.27/include/linux/ext3_fs.h
===================================================================
---- linux-2.6.16.54-0.2.5.orig/include/linux/ext3_fs.h
-+++ linux-2.6.16.54-0.2.5/include/linux/ext3_fs.h
+--- linux-2.6.16.60-0.27.orig/include/linux/ext3_fs.h
++++ linux-2.6.16.60-0.27/include/linux/ext3_fs.h
@@ -153,16 +153,22 @@ struct ext3_allocation_request {
*/
struct ext3_group_desc
/*
* Macro-instructions used to manage group descriptors
*/
-@@ -607,6 +613,7 @@ static inline int ext3_valid_inum(struct
+@@ -604,6 +610,7 @@ static inline int ext3_valid_inum(struct
#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001
-@@ -623,6 +630,7 @@ static inline int ext3_valid_inum(struct
+@@ -620,6 +627,7 @@ static inline int ext3_valid_inum(struct
EXT3_FEATURE_INCOMPAT_EXTENTS)
#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
-Index: linux-2.6.16.54-0.2.5/fs/ext3/resize.c
+Index: linux-2.6.16.60-0.27/fs/ext3/resize.c
===================================================================
---- linux-2.6.16.54-0.2.5.orig/fs/ext3/resize.c
-+++ linux-2.6.16.54-0.2.5/fs/ext3/resize.c
+--- linux-2.6.16.60-0.27.orig/fs/ext3/resize.c
++++ linux-2.6.16.60-0.27/fs/ext3/resize.c
@@ -19,6 +19,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
#define outside(b, first, last) ((b) < (first) || (b) >= (last))
#define inside(b, first, last) ((b) >= (first) && (b) < (last))
-@@ -133,25 +134,6 @@ static struct buffer_head *bclean(handle
- return bh;
+@@ -134,25 +135,6 @@ static struct buffer_head *bclean(handle
}
--/*
+ /*
- * To avoid calling the atomic setbit hundreds or thousands of times, we only
- * need to use it within a single byte (to ensure we get endianness right).
- * We can use memset for the rest of the bitmap as there are no other users.
- memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
-}
-
- /*
+-/*
* If we have fewer than thresh credits, extend by EXT3_MAX_TRANS_DATA.
* If that fails, restart the transaction & regain write access for the
-@@ -818,6 +800,7 @@ int ext3_group_add(struct super_block *s
+ * buffer head which is used for block_bitmap modifications.
+@@ -865,6 +847,7 @@ int ext3_group_add(struct super_block *s
gdp->bg_inode_table = cpu_to_le32(input->inode_table);
gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
gdp->bg_free_inodes_count = cpu_to_le16(EXT3_INODES_PER_GROUP(sb));
/*
* Make the new blocks and inodes valid next. We do this before
-Index: linux-2.6.16.54-0.2.5/fs/ext3/super.c
+Index: linux-2.6.16.60-0.27/fs/ext3/super.c
===================================================================
---- linux-2.6.16.54-0.2.5.orig/fs/ext3/super.c
-+++ linux-2.6.16.54-0.2.5/fs/ext3/super.c
+--- linux-2.6.16.60-0.27.orig/fs/ext3/super.c
++++ linux-2.6.16.60-0.27/fs/ext3/super.c
@@ -42,6 +42,7 @@
#include "xattr.h"
#include "acl.h"
block += EXT3_BLOCKS_PER_GROUP(sb);
gdp++;
}
-Index: linux-2.6.16.54-0.2.5/fs/ext3/group.h
+Index: linux-2.6.16.60-0.27/fs/ext3/group.h
===================================================================
--- /dev/null
-+++ linux-2.6.16.54-0.2.5/fs/ext3/group.h
++++ linux-2.6.16.60-0.27/fs/ext3/group.h
@@ -0,0 +1,30 @@
+/*
+ * linux/fs/ext3/group.h
+ *
-+ * Copyright 2008 Sun Microsystems, Inc.
++ * Copyright 2008 Sun Microsystems, Inc
+ *
+ * Author: Andreas Dilger <adilger@clusterfs.com>
+ */
+ struct ext3_group_desc *desc);
+extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
+#endif /* _LINUX_EXT3_GROUP_H */
-Index: linux-2.6.16.54-0.2.5/fs/ext3/ialloc.c
+Index: linux-2.6.16.60-0.27/fs/ext3/ialloc.c
===================================================================
---- linux-2.6.16.54-0.2.5.orig/fs/ext3/ialloc.c
-+++ linux-2.6.16.54-0.2.5/fs/ext3/ialloc.c
+--- linux-2.6.16.60-0.27.orig/fs/ext3/ialloc.c
++++ linux-2.6.16.60-0.27/fs/ext3/ialloc.c
@@ -28,6 +28,7 @@
#include "xattr.h"
/* This is the optimal IO size (for stat), not the fs block size */
inode->i_blksize = PAGE_SIZE;
inode->i_blocks = 0;
-Index: linux-2.6.16.54-0.2.5/fs/ext3/mballoc.c
+Index: linux-2.6.16.60-0.27/fs/ext3/mballoc.c
===================================================================
---- linux-2.6.16.54-0.2.5.orig/fs/ext3/mballoc.c
-+++ linux-2.6.16.54-0.2.5/fs/ext3/mballoc.c
+--- linux-2.6.16.60-0.27.orig/fs/ext3/mballoc.c
++++ linux-2.6.16.60-0.27/fs/ext3/mballoc.c
@@ -36,6 +36,8 @@
#include <linux/seq_file.h>
#include <linux/version.h>
spin_unlock(sb_bgl_lock(sbi, block_group));
percpu_counter_mod(&sbi->s_freeblocks_counter, count);
-Index: linux-2.6.16.54-0.2.5/fs/ext3/balloc.c
+Index: linux-2.6.16.60-0.27/fs/ext3/balloc.c
===================================================================
---- linux-2.6.16.54-0.2.5.orig/fs/ext3/balloc.c
-+++ linux-2.6.16.54-0.2.5/fs/ext3/balloc.c
+--- linux-2.6.16.60-0.27.orig/fs/ext3/balloc.c
++++ linux-2.6.16.60-0.27/fs/ext3/balloc.c
@@ -21,6 +21,7 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
+/*
+ * linux/fs/ext3/group.h
+ *
-+ * Copyright 2008 Sun Microsystems, Inc.
++ * Copyright 2007 Sun Microsystems, Inc.
+ *
+ * Author: Andreas Dilger <adilger@clusterfs.com>
+ */
ext3-nanosecond-2.6-rhel4.patch
ext3-unlink-race.patch
ext3-mmp-2.6-rhel4.patch
+ext3-fiemap-2.6-sles10.patch
ext3-external-journal-2.6.9.patch
ext3-max-dir-size.patch
ext3-print-inum-in-htree-warning.patch
ext3-xattr-no-update-ctime-rhel4.patch
ext3-check-bad-inode.patch
-ext3-fiemap-2.6-rhel4.patch
+ext3-fiemap-fix-rhel4.patch
ext3-get-raid-stripe-from-sb.patch
ext3-big-endian-check-2.6-rhel4.patch
ext3-ea-expand-lose-block.patch
ext3-mmp-2.6.18-vanilla.patch
ext3-handle-directory-corruption-better.patch
+ext3-fiemap-2.6.18-vanilla.patch
ext3-lookup-dotdot-2.6.9.patch
ext3-max-dir-size.patch
ext3-print-inum-in-htree-warning.patch