--- linux-stage.orig/fs/ext4/ext4.h
+++ linux-stage/fs/ext4/ext4.h
@@ -1024,6 +1024,8 @@ extern unsigned long ext4_count_free_ino
- extern unsigned long ext4_count_dirs (struct super_block *);
- extern void ext4_check_inodes_bitmap (struct super_block *);
- extern unsigned long ext4_count_free (struct buffer_head *, unsigned);
+ extern unsigned long ext4_count_free_inodes(struct super_block *);
+ extern unsigned long ext4_count_dirs(struct super_block *);
+ extern void ext4_check_inodes_bitmap(struct super_block *);
+extern struct buffer_head *ext4_read_inode_bitmap(struct super_block *sb,
+ ext4_group_t block_group);
EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
@@ -816,6 +821,9 @@ extern int ext3_get_inode_loc(struct ino
- extern void ext3_truncate (struct inode *);
- extern void ext3_set_inode_flags(struct inode *);
extern void ext3_set_aops(struct inode *inode);
+ extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ u64 start, u64 len);
+extern int ext3_writepage_trans_blocks(struct inode *);
+extern int ext3_block_truncate_page(handle_t *handle, struct page *page,
+ struct address_space *mapping, loff_t from);
struct buffer_head *bh;
struct dx_frame *frame = frame_in;
u32 hash;
-@@ -372,45 +374,45 @@ dx_probe(struct dentry *dentry, struct i
+@@ -372,46 +374,45 @@ dx_probe(struct dentry *dentry, struct i
dir = dentry->d_parent->d_inode;
if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
goto fail;
- entries = (struct dx_entry *) (((char *)&root->info) +
- root->info.info_length);
-- assert(dx_get_limit(entries) == dx_root_limit(dir,
-- root->info.info_length));
+ entries = (struct dx_entry *) (((char *)info) + info->info_length);
-+ assert(dx_get_limit(entries) == dx_root_limit(dir, info->info_length));
-+
- dxtrace (printk("Look up %x", hash));
- while (1)
- {
+
+- if (dx_get_limit(entries) != dx_root_limit(dir,
+- root->info.info_length)) {
++ if (dx_get_limit(entries) != dx_root_limit(dir, info->info_length)) {
+ ext3_warning(dir->i_sb, __FUNCTION__,
+ "dx entry: limit != root limit");
+ brelse(bh);
@@ -467,10 +469,12 @@ fail:
static void dx_release (struct dx_frame *frames)
extern struct proc_dir_entry *proc_root_ext3;
extern int __init init_ext3_proc(void);
extern void exit_ext3_proc(void);
-@@ -1107,6 +1111,19 @@ extern struct inode_operations ext3_file
+@@ -1107,6 +1111,20 @@ extern struct inode_operations ext3_file
extern const struct file_operations ext3_file_operations;
/* namei.c */
+extern struct buffer_head * ext3_find_entry(struct dentry *dentry,
+ struct ext3_dir_entry_2
+ ** res_dir);
++#define ll_ext3_find_entry(inode, dentry, res_dir) ext3_find_entry(dentry, res_dir)
+extern int ext3_add_dot_dotdot(handle_t *handle, struct inode *dir,
+ struct inode *inode);
extern struct inode_operations ext3_dir_inode_operations;
return 0;
out:
destroy_inodecache();
+--- /dev/null 2009-09-21 17:11:24.467285554 +0800
++++ linux-2.6.27.21-0.1/fs/ext3/fiemap.h
+@@ -0,0 +1,2 @@
++
++#include_next <fiemap.h>
names++;
}
de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-@@ -411,7 +422,10 @@ dx_probe(struct dentry *dentry, struct i
- }
+@@ -411,7 +422,9 @@ dx_probe(struct dentry *dentry, struct i
entries = (struct dx_entry *) (((char *)info) + info->info_length);
-- assert(dx_get_limit(entries) == dx_root_limit(dir, info->info_length));
-+ assert(dx_get_limit(entries) == dx_root_limit(dir->i_sb->s_blocksize,
-+ (struct ext3_dir_entry_2*)bh->b_data,
-+ info->info_length));
-+
- dxtrace (printk("Look up %x", hash));
- while (1)
+- if (dx_get_limit(entries) != dx_root_limit(dir, info->info_length)) {
++ if (dx_get_limit(entries) != dx_root_limit(dir->i_sb->s_blocksize,
++ (struct ext3_dir_entry_2*)bh->b_data,
++ info->info_length)) {
+ ext3_warning(dir->i_sb, __FUNCTION__,
+ "dx entry: limit != root limit");
+ brelse(bh);
@@ -583,7 +597,7 @@ static int htree_dirblock_to_tree(struct
de = (struct ext3_dir_entry_2 *) bh->b_data;
top = (struct ext3_dir_entry_2 *) ((char *) de +
-Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
+Index: linux-2.6.27.21-0.1/fs/ext4/ialloc.c
===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/ialloc.c
-+++ linux-2.6.18-128.1.6/fs/ext4/ialloc.c
-@@ -946,6 +946,36 @@ fail_drop:
+--- linux-2.6.27.21-0.1.orig/fs/ext4/ialloc.c 2009-07-07 14:47:04.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/ialloc.c 2009-07-07 15:04:02.000000000 +0530
+@@ -953,6 +953,36 @@
return ERR_PTR(err);
}
+ for (group = EXT4_SB(sb)->s_groups_count - 1; group >= 0;
+ --group) {
+ desc = ext4_get_group_desc(sb, group, NULL);
-+ if (desc->bg_free_inodes_count == 0)
++ if (ext4_free_inodes_count(sb, desc) == 0)
+ continue;
+
+ bitmap_bh = ext4_read_inode_bitmap(sb, group);
/* Verify that we are loading a valid orphan from disk */
struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
{
-Index: linux-2.6.18-128.1.6/fs/ext4/namei.c
+Index: linux-2.6.27.21-0.1/fs/ext4/namei.c
===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/namei.c
-+++ linux-2.6.18-128.1.6/fs/ext4/namei.c
-@@ -151,14 +151,24 @@ struct dx_map_entry
- u16 size;
- };
-
-+/*
-+ * dentry_param used by ext4_new_inode_wantedi()
-+ */
- #define LVFS_DENTRY_PARAM_MAGIC 20070216UL
- struct lvfs_dentry_params
- {
-- unsigned long p_inum;
-- void *p_ptr;
-- u32 magic;
-+ unsigned long ldp_inum;
-+ long ldp_flags;
-+ u32 ldp_magic;
+--- linux-2.6.27.21-0.1.orig/fs/ext4/namei.c 2009-07-07 14:47:05.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/namei.c 2009-07-07 15:04:21.000000000 +0530
+@@ -161,6 +161,12 @@
+ u32 ldp_magic;
};
+/* Only use the least 3 bits of ldp_flags for goal policy */
+ DP_LASTGROUP_REVERSE = 1,
+} dp_policy_t;
+
-+
static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
- static inline unsigned dx_get_hash (struct dx_entry *entry);
-@@ -1762,8 +1772,13 @@ static struct inode * ext4_new_inode_wan
+ static inline unsigned dx_get_hash(struct dx_entry *entry);
+@@ -1771,8 +1777,14 @@
if (dentry->d_fsdata != NULL) {
struct lvfs_dentry_params *param = dentry->d_fsdata;
-- if (param->magic == LVFS_DENTRY_PARAM_MAGIC)
-- inum = param->p_inum;
+- if (param->ldp_magic == LVFS_DENTRY_PARAM_MAGIC)
+- inum = param->ldp_inum;
+ if (param->ldp_magic == LVFS_DENTRY_PARAM_MAGIC) {
+ if ((dp_policy_t)(param->ldp_flags & 0x7) ==
+ DP_LASTGROUP_REVERSE)
-+ inum = ext4_find_reverse(dir->i_sb);
-+ else /* DP_GOAL_POLICY */
++ inum = ext4_find_reverse(sb);
++ else /* DP_GOAL_POLICY */
+ inum = param->ldp_inum;
-+ }
++ }
++
}
- return ext4_new_inode(handle, dir, mode, inum);
+ return inum;
}
-Index: linux-2.6.18-128.1.6/fs/ext4/ext4.h
+Index: linux-2.6.27.21-0.1/fs/ext4/ext4.h
===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
-+++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
-@@ -1071,6 +1071,7 @@ extern int ext4fs_dirhash(const char *na
- /* ialloc.c */
- extern struct inode * ext4_new_inode (handle_t *, struct inode *, int,
- unsigned long);
+--- linux-2.6.27.21-0.1.orig/fs/ext4/ext4.h 2009-07-07 14:47:22.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/ext4.h 2009-07-07 15:04:02.000000000 +0530
+@@ -1101,6 +1101,7 @@
+ EXT4_SB(dir->i_sb)->s_inode_goal);
+ }
+ extern void ext4_free_inode(handle_t *, struct inode *);
+extern unsigned long ext4_find_reverse(struct super_block *);
- extern void ext4_free_inode (handle_t *, struct inode *);
- extern struct inode * ext4_orphan_get (struct super_block *, unsigned long);
- extern unsigned long ext4_count_free_inodes (struct super_block *);
+ extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
+ extern unsigned long ext4_count_free_inodes(struct super_block *);
+ extern unsigned long ext4_count_dirs(struct super_block *);
@@ -1222,7 +1224,7 @@ enum {
Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
- Opt_mballoc, Opt_nomballoc, Opt_stripe,
+ Opt_inode_readahead_blks, Opt_journal_ioprio,
- Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
+ Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, Opt_bigendian_extents,
};
static match_table_t tokens = {
@@ -1284,6 +1286,7 @@ static match_table_t tokens = {
- {Opt_nomballoc, "nomballoc"},
- {Opt_stripe, "stripe=%u"},
- {Opt_resize, "resize"},
+ {Opt_auto_da_alloc, "auto_da_alloc=%u"},
+ {Opt_auto_da_alloc, "auto_da_alloc"},
+ {Opt_noauto_da_alloc, "noauto_da_alloc"},
+ {Opt_bigendian_extents, "bigendian_extents"},
{Opt_err, NULL},
};
===================================================================
--- linux-2.6.18-128.1.6.orig/fs/ext4/balloc.c
+++ linux-2.6.18-128.1.6/fs/ext4/balloc.c
-@@ -321,15 +321,15 @@ ext4_read_block_bitmap(struct super_bloc
- if (bh_uptodate_or_lock(bh))
- return bh;
-
+@@ -321,16 +321,16 @@ ext4_read_block_bitmap(struct super_bloc
+ unlock_buffer(bh);
+ return bh;
+ }
- spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_lock_group(sb, block_group);
if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
ext4_init_block_bitmap(sb, bh, block_group, desc);
+ set_bitmap_uptodate(bh);
set_buffer_uptodate(bh);
- unlock_buffer(bh);
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_unlock_group(sb, block_group);
+ unlock_buffer(bh);
return bh;
}
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_unlock_group(sb, block_group);
- if (bh_submit_read(bh) < 0) {
- put_bh(bh);
- ext4_error(sb, __func__,
-@@ -778,8 +778,9 @@ do_more:
- BUFFER_TRACE(bitmap_bh, "set in b_committed_data");
- J_ASSERT_BH(bitmap_bh,
- bh2jh(bitmap_bh)->b_committed_data != NULL);
-- ext4_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i,
-- bh2jh(bitmap_bh)->b_committed_data);
-+ ext4_set_bit_atomic(ext4_group_lock_ptr(sb, block_group),
-+ bit + i,
-+ bh2jh(bitmap_bh)->b_committed_data);
-
- /*
- * We clear the bit in the bitmap after setting the committed
+ if (buffer_uptodate(bh)) {
+ /*
+ * if not uninit if bh is uptodate,
@@ -787,7 +788,7 @@ do_more:
* the allocator uses.
*/
bit + i, bitmap_bh->b_data)) {
jbd_unlock_bh_state(bitmap_bh);
ext4_error(sb, __func__,
-@@ -801,17 +802,17 @@ do_more:
- }
- jbd_unlock_bh_state(bitmap_bh);
-
+@@ -801,18 +802,18 @@ do_more:
+ blocks_freed++;
+ }
+ }
- spin_lock(sb_bgl_lock(sbi, block_group));
+ ext4_lock_group(sb, block_group);
- le16_add_cpu(&desc->bg_free_blocks_count, group_freed);
+ blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc);
+ ext4_free_blks_set(sb, desc, blk_free_count);
desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
- spin_unlock(sb_bgl_lock(sbi, block_group));
+ ext4_unlock_group(sb, block_group);
- percpu_counter_add(&sbi->s_freeblocks_counter, count);
+ percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed);
if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
- spin_lock(sb_bgl_lock(sbi, flex_group));
+ ext4_lock_group(sb, block_group);
- sbi->s_flex_groups[flex_group].free_blocks += count;
+ sbi->s_flex_groups[flex_group].free_blocks += blocks_freed;
- spin_unlock(sb_bgl_lock(sbi, flex_group));
+ ext4_unlock_group(sb, block_group);
}
/* We dirtied the bitmap block */
-@@ -1104,7 +1105,7 @@ repeat:
- }
- start = grp_goal;
-
-- if (!claim_block(sb_bgl_lock(EXT4_SB(sb), group),
-+ if (!claim_block(ext4_group_lock_ptr(sb, group),
- grp_goal, bitmap_bh)) {
- /*
- * The block was allocated by another thread, or it was
-@@ -1120,7 +1121,7 @@ repeat:
- grp_goal++;
- while (num < *count && grp_goal < end
- && ext4_test_allocatable(grp_goal, bitmap_bh)
-- && claim_block(sb_bgl_lock(EXT4_SB(sb), group),
-+ && claim_block(ext4_group_lock_ptr(sb, group),
- grp_goal, bitmap_bh)) {
- num++;
- grp_goal++;
-@@ -1872,7 +1873,7 @@ allocated:
- }
- }
- jbd_lock_bh_state(bitmap_bh);
-- spin_lock(sb_bgl_lock(sbi, group_no));
-+ ext4_lock_group(sb, group_no);
- if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) {
- int i;
-
-@@ -1885,7 +1886,7 @@ allocated:
- }
- }
- ext4_debug("found bit %d\n", grp_alloc_blk);
-- spin_unlock(sb_bgl_lock(sbi, group_no));
-+ ext4_unlock_group(sb, group_no);
- jbd_unlock_bh_state(bitmap_bh);
- #endif
-
-@@ -1902,19 +1903,19 @@ allocated:
- * list of some description. We don't know in advance whether
- * the caller wants to use it as metadata or data.
- */
-- spin_lock(sb_bgl_lock(sbi, group_no));
-+ ext4_lock_group(sb, group_no);
- if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
- gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
- le16_add_cpu(&gdp->bg_free_blocks_count, -num);
- gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
-- spin_unlock(sb_bgl_lock(sbi, group_no));
-+ ext4_unlock_group(sb, group_no);
- percpu_counter_sub(&sbi->s_freeblocks_counter, num);
-
- if (sbi->s_log_groups_per_flex) {
- ext4_group_t flex_group = ext4_flex_group(sbi, group_no);
-- spin_lock(sb_bgl_lock(sbi, flex_group));
-+ ext4_lock_group(sb, flex_group);
- sbi->s_flex_groups[flex_group].free_blocks -= num;
-- spin_unlock(sb_bgl_lock(sbi, flex_group));
-+ ext4_unlock_group(sb, flex_group);
- }
-
- BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor");
Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
===================================================================
--- linux-2.6.18-128.1.6.orig/fs/ext4/ialloc.c
+++ linux-2.6.18-128.1.6/fs/ext4/ialloc.c
-@@ -118,15 +118,15 @@ ext4_read_inode_bitmap(struct super_bloc
- if (bh_uptodate_or_lock(bh))
- return bh;
-
+@@ -118,16 +118,16 @@ ext4_read_inode_bitmap(struct super_bloc
+ unlock_buffer(bh);
+ return bh;
+ }
- spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_lock_group(sb, block_group);
if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
ext4_init_inode_bitmap(sb, bh, block_group, desc);
+ set_bitmap_uptodate(bh);
set_buffer_uptodate(bh);
- unlock_buffer(bh);
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_unlock_group(sb, block_group);
+ unlock_buffer(bh);
return bh;
}
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
+ ext4_unlock_group(sb, block_group);
- if (bh_submit_read(bh) < 0) {
- put_bh(bh);
- ext4_error(sb, __func__,
-@@ -221,8 +221,8 @@ void ext4_free_inode (handle_t *handle,
+ if (buffer_uptodate(bh)) {
+ /*
+ * if not uninit if bh is uptodate,
+@@ -221,9 +221,9 @@ void ext4_free_inode (handle_t *handle,
goto error_return;
/* Ok, now we can actually update the inode bitmaps.. */
-- if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
-- bit, bitmap_bh->b_data))
-+ if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
-+ bit, bitmap_bh->b_data))
- ext4_error (sb, "ext4_free_inode",
- "bit already cleared for inode %lu", ino);
- else {
-@@ -233,22 +233,22 @@ void ext4_free_inode (handle_t *handle,
+- spin_lock(sb_bgl_lock(sbi, block_group));
++ ext4_lock_group(sb, block_group);
+ cleared = ext4_clear_bit(bit, bitmap_bh->b_data);
+- spin_unlock(sb_bgl_lock(sbi, block_group));
++ ext4_unlock_group(sb, block_group);
+ if (!cleared)
+ ext4_error(sb, "ext4_free_inode",
+ "bit already cleared for inode %lu", ino);
+@@ -233,7 +233,7 @@ void ext4_free_inode (handle_t *handle,
if (fatal) goto error_return;
if (gdp) {
- spin_lock(sb_bgl_lock(sbi, block_group));
+ ext4_lock_group(sb, block_group);
- le16_add_cpu(&gdp->bg_free_inodes_count, 1);
- if (is_directory)
- le16_add_cpu(&gdp->bg_used_dirs_count, -1);
+ count = ext4_free_inodes_count(sb, gdp) + 1;
+ ext4_free_inodes_set(sb, gdp, count);
+ if (is_directory) {
+@@ -233,16 +233,16 @@ void ext4_free_inode (handle_t *handle,
+ }
gdp->bg_checksum = ext4_group_desc_csum(sbi,
block_group, gdp);
- spin_unlock(sb_bgl_lock(sbi, block_group));
}
}
BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
-@@ -630,7 +630,7 @@ struct inode *ext4_new_inode(handle_t *h
- if (err)
- goto fail;
-
-- if (ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
-+ if (ext4_set_bit_atomic(ext4_group_lock_ptr(sb, group),
- ino, bitmap_bh->b_data)) {
- printk(KERN_ERR "goal inode %lu unavailable\n", goal);
- /* Oh well, we tried. */
-@@ -691,7 +691,7 @@ repeat_in_this_group:
- if (err)
- goto fail;
+@@ -630,7 +630,7 @@
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
+
+- spin_lock(sb_bgl_lock(sbi, group));
++ ext4_lock_group(sb, group);
+ if (ext4_set_bit(ino, inode_bitmap_bh->b_data)) {
+ /* not a free inode */
+ retval = 1;
+@@ -691,7 +691,7 @@
+ ino++;
+ if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
+ ino > EXT4_INODES_PER_GROUP(sb)) {
+- spin_unlock(sb_bgl_lock(sbi, group));
++ ext4_unlock_group(sb, group);
+ ext4_error(sb, __func__,
+ "reserved inode or inode > inodes count - "
+ "block_group = %u, inode=%lu", group,
+@@ -692,7 +692,7 @@
+ }
+ gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
+ err_ret:
+- spin_unlock(sb_bgl_lock(sbi, group));
++ ext4_unlock_group(sb, group);
+ return retval;
+ }
-- if (!ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
-+ if (!ext4_set_bit_atomic(ext4_group_lock_ptr(sb, group),
- ino, bitmap_bh->b_data)) {
- /* we won it */
- BUFFER_TRACE(bitmap_bh,
-@@ -751,14 +751,14 @@ got:
+@@ -751,16 +751,16 @@ got:
}
free = 0;
+ ext4_lock_group(sb, group);
/* recheck and clear flag under lock if we still need to */
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
- gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
free = ext4_free_blocks_after_init(sb, group, gdp);
- gdp->bg_free_blocks_count = cpu_to_le16(free);
+ gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+ ext4_free_blks_set(sb, gdp, free);
+ gdp->bg_checksum = ext4_group_desc_csum(sbi, group,
+ gdp);
}
- spin_unlock(sb_bgl_lock(sbi, group));
+ ext4_unlock_group(sb, group);
/* Don't need to dirty bitmap block if we didn't change it */
if (free) {
-@@ -771,7 +771,7 @@ got:
- goto fail;
- }
-
-- spin_lock(sb_bgl_lock(sbi, group));
-+ ext4_lock_group(sb, group);
- /* If we didn't allocate from within the initialized part of the inode
- * table then we need to initialize up to this inode. */
- if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
-@@ -807,7 +807,7 @@ got:
- le16_add_cpu(&gdp->bg_used_dirs_count, 1);
- }
- gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
-- spin_unlock(sb_bgl_lock(sbi, group));
-+ ext4_unlock_group(sb, group);
- BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
- err = ext4_journal_dirty_metadata(handle, bh2);
- if (err) goto fail;
@@ -819,9 +819,9 @@ got:
if (sbi->s_log_groups_per_flex) {
static inline int mb_find_next_zero_bit(void *addr, int max, int start)
{
int fix = 0, ret, tmpmax;
-@@ -789,16 +777,16 @@ static int ext4_mb_init_cache(struct pag
- if (bh_uptodate_or_lock(bh[i]))
- continue;
-
+@@ -789,17 +777,17 @@ static int ext4_mb_init_cache(struct pag
+ unlock_buffer(bh[i]);
+ continue;
+ }
- spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+ ext4_lock_group(sb, first_group + i);
if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
ext4_init_block_bitmap(sb, bh[i],
first_group + i, desc);
+ set_bitmap_uptodate(bh[i]);
set_buffer_uptodate(bh[i]);
- unlock_buffer(bh[i]);
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+ ext4_unlock_group(sb, first_group + i);
+ unlock_buffer(bh[i]);
continue;
}
- spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
+ ext4_unlock_group(sb, first_group + i);
- get_bh(bh[i]);
- bh[i]->b_end_io = end_buffer_read_sync;
- submit_bh(READ, bh[i]);
+ if (buffer_uptodate(bh[i])) {
+ /*
+ * if not uninit if bh is uptodate,
@@ -1021,7 +1009,7 @@ static int mb_find_order_for_block(struc
return 0;
}
{
__u32 *addr;
-@@ -1034,12 +1022,12 @@ static void mb_clear_bits(spinlock_t *lo
+@@ -1034,15 +1022,12 @@ static void mb_clear_bits(spinlock_t *lo
cur += 32;
continue;
}
-- mb_clear_bit_atomic(lock, cur, bm);
+- if (lock)
+- mb_clear_bit_atomic(lock, cur, bm);
+- else
+- mb_clear_bit(cur, bm);
+ mb_clear_bit(cur, bm);
cur++;
}
{
__u32 *addr;
-@@ -1052,7 +1040,7 @@ static void mb_set_bits(spinlock_t *lock
+@@ -1052,10 +1040,7 @@ static void mb_set_bits(spinlock_t *lock
cur += 32;
continue;
}
-- mb_set_bit_atomic(lock, cur, bm);
+- if (lock)
+- mb_set_bit_atomic(lock, cur, bm);
+- else
+- mb_set_bit(cur, bm);
+ mb_set_bit(cur, bm);
cur++;
}
+ mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,
+ ac->ac_b_ex.fe_len);
+ ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
- err = ext4_journal_dirty_metadata(handle, bitmap_bh);
+ err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
if (!err)
err = -EAGAIN;
goto out_err;
#ifdef AGGRESSIVE_CHECK
{
int i;
-@@ -3147,10 +3137,8 @@ ext4_mb_mark_diskspace_used(struct ext4_
+@@ -3147,9 +3137,7 @@ ext4_mb_mark_diskspace_used(struct ext4_
}
}
#endif
-- mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), bitmap_bh->b_data,
+- spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
+- mb_set_bits(NULL, bitmap_bh->b_data,
- ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
+ mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,ac->ac_b_ex.fe_len);
-
-- spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
gdp->bg_free_blocks_count =
-@@ -3160,15 +3148,16 @@ ext4_mb_mark_diskspace_used(struct ext4_
- }
- le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len);
- gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
+@@ -3160,7 +3148,8 @@ ext4_mb_mark_diskspace_used(struct ext4_
+ len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len;
+ ext4_free_blks_set(sb, gdp, len);
+ gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
- spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
+
+ ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len);
-
+ /*
+ * Now reduce the dirty block count also. Should not go negative
+@@ -3161,9 +3148,9 @@ ext4_mb_mark_diskspace_used(struct ext4_
if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi,
ac->ac_b_ex.fe_group);
}
err = ext4_journal_dirty_metadata(handle, bitmap_bh);
+@@ -3500,9 +3589,7 @@ int ext4_mb_check_ondisk_bitmap(struct s
+
+ while (n) {
+ entry = rb_entry(n, struct ext4_free_data, node);
+- mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group),
+- bitmap, entry->start_blk,
+- entry->count);
++ mb_set_bits(bitmap, entry->start_blk, entry->count);
+ n = rb_next(n);
+ }
+ return;
@@ -3600,7 +3589,7 @@ int ext4_mb_check_ondisk_bitmap(struct s
/*
* the function goes through all preallocation in this group and marks them
static noinline_for_stack int
ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
ext4_group_t group, ext4_grpblk_t block, int count)
-@@ -4755,7 +4744,6 @@ ext4_mb_free_metadata(handle_t *handle,
- BUG_ON(e4b->bd_bitmap_page == NULL);
- BUG_ON(e4b->bd_buddy_page == NULL);
-
-- ext4_lock_group(sb, group);
- for (i = 0; i < count; i++) {
- md = db->bb_md_cur;
- if (md && db->bb_tid != handle->h_transaction->t_tid) {
-@@ -4766,8 +4754,10 @@ ext4_mb_free_metadata(handle_t *handle,
- if (md == NULL) {
- ext4_unlock_group(sb, group);
- md = kmalloc(sizeof(*md), GFP_NOFS);
-- if (md == NULL)
-+ if (md == NULL) {
-+ ext4_lock_group(sb, group);
- return -ENOMEM;
-+ }
- md->num = 0;
- md->group = group;
-
-@@ -4800,7 +4790,6 @@ ext4_mb_free_metadata(handle_t *handle,
- db->bb_md_cur = NULL;
- }
- }
-- ext4_unlock_group(sb, group);
- return 0;
- }
-
-@@ -4901,6 +4890,13 @@ do_more:
- if (err)
- goto error_return;
-
-+ if (ac) {
-+ ac->ac_b_ex.fe_group = block_group;
-+ ac->ac_b_ex.fe_start = bit;
-+ ac->ac_b_ex.fe_len = count;
-+ ext4_mb_store_history(ac);
-+ }
-+
- err = ext4_mb_load_buddy(sb, block_group, &e4b);
- if (err)
- goto error_return;
-@@ -4912,42 +4908,31 @@ do_more:
- BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data));
- }
- #endif
-- mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
-- bit, count);
--
-+ ext4_lock_group(sb, block_group);
-+ mb_clear_bits(bitmap_bh->b_data, bit, count);
- /* We dirtied the bitmap block */
- BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
- err = ext4_journal_dirty_metadata(handle, bitmap_bh);
-
-- if (ac) {
-- ac->ac_b_ex.fe_group = block_group;
-- ac->ac_b_ex.fe_start = bit;
-- ac->ac_b_ex.fe_len = count;
-- ext4_mb_store_history(ac);
-- }
--
- if (metadata) {
- /* blocks being freed are metadata. these blocks shouldn't
- * be used until this transaction is committed */
- ext4_mb_free_metadata(handle, &e4b, block_group, bit, count);
- } else {
-- ext4_lock_group(sb, block_group);
- mb_free_blocks(inode, &e4b, bit, count);
- ext4_mb_return_to_preallocation(inode, &e4b, block, count);
+@@ -4912,35 +4908,30 @@ do_more:
+ new_entry->count = count;
+ new_entry->t_tid = handle->h_transaction->t_tid;
+ ext4_lock_group(sb, block_group);
+- mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
+- bit, count);
++ mb_clear_bits(bitmap_bh->b_data, bit, count);
+ ext4_mb_free_metadata(handle, &e4b, new_entry);
+- ext4_unlock_group(sb, block_group);
+ } else {
+ ext4_lock_group(sb, block_group);
+ /* need to update group_info->bb_free and bitmap
+ * with group lock held. generate_buddy look at
+ * them with group lock_held
+ */
+- mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
+- bit, count);
++ mb_clear_bits(bitmap_bh->b_data, bit, count);
+ mb_free_blocks(inode, &e4b, bit, count);
+ ext4_mb_return_to_preallocation(inode, &e4b, block, count);
- ext4_unlock_group(sb, block_group);
}
- spin_lock(sb_bgl_lock(sbi, block_group));
- le16_add_cpu(&gdp->bg_free_blocks_count, count);
- gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
+ ret = ext4_free_blks_count(sb, gdp) + count;
+ ext4_free_blks_set(sb, gdp, ret);
+ gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
- spin_unlock(sb_bgl_lock(sbi, block_group));
+ ext4_unlock_group(sb, block_group);
percpu_counter_add(&sbi->s_freeblocks_counter, count);
===================================================================
--- linux-2.6.18-128.1.6.orig/fs/ext4/super.c
+++ linux-2.6.18-128.1.6/fs/ext4/super.c
-@@ -1934,16 +1934,18 @@ static int ext4_check_descriptors(struct
- "(block %llu)!", i, inode_table);
- return 0;
- }
+@@ -1934,18 +1934,18 @@ static int ext4_check_descriptors(struct
+ "(block %llu)!\n", i, inode_table);
+ return 0;
+ }
- spin_lock(sb_bgl_lock(sbi, i));
+ ext4_lock_group(sb, i);
- if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
- printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
- "Checksum for group %lu failed (%u!=%u)\n",
- i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
- gdp)), le16_to_cpu(gdp->bg_checksum));
-- if (!(sb->s_flags & MS_RDONLY))
-+ if (!(sb->s_flags & MS_RDONLY)) {
+ if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
+ printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
+ "Checksum for group %u failed (%u!=%u)\n",
+ i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
+ gdp)), le16_to_cpu(gdp->bg_checksum));
+ if (!(sb->s_flags & MS_RDONLY)) {
+- spin_unlock(sb_bgl_lock(sbi, i));
+ ext4_unlock_group(sb, i);
return 0;
-+ }
+ }
}
- spin_unlock(sb_bgl_lock(sbi, i));
+ ext4_unlock_group(sb, i);
===================================================================
--- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
+++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
-@@ -1303,6 +1303,33 @@ extern int ext4_get_blocks_wrap(handle_t
- sector_t block, unsigned long max_blocks,
- struct buffer_head *bh, int create,
- int extend_disksize);
-+
-+static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb,
-+ ext4_group_t group)
-+{
-+ struct blockgroup_lock *bgl = &EXT4_SB(sb)->s_blockgroup_lock;
-+ return &bgl->locks[group & (NR_BG_LOCKS-1)].lock;
-+}
-+
-+static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
-+{
-+ spin_lock(ext4_group_lock_ptr(sb, group));
-+}
-+
-+static inline void ext4_unlock_group(struct super_block *sb,
-+ ext4_group_t group)
-+{
-+ spin_unlock(ext4_group_lock_ptr(sb, group));
-+}
-+
-+static inline int ext4_is_group_locked(struct super_block *sb,
-+ ext4_group_t group)
-+{
-+ return spin_is_locked(ext4_group_lock_ptr(sb, group));
-+}
-+
-+
-+
- #endif /* __KERNEL__ */
-
- #endif /* _EXT4_H */
-Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.h
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/mballoc.h
-+++ linux-2.6.18-128.1.6/fs/ext4/mballoc.h
-@@ -127,7 +127,6 @@ struct ext4_group_info {
+@@ -127,35 +127,9 @@ struct ext4_group_info {
};
#define EXT4_GROUP_INFO_NEED_INIT_BIT 0
#define EXT4_MB_GRP_NEED_INIT(grp) \
(test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state)))
-@@ -272,31 +271,6 @@ static void ext4_mb_put_pa(struct ext4_a
- static int ext4_mb_init_per_dev_proc(struct super_block *sb);
- static int ext4_mb_destroy_per_dev_proc(struct super_block *sb);
-
-
-static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
-{
- &(grinfo->bb_state));
-}
-
- static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb,
- struct ext4_free_extent *fex)
- {
+ /*
+ * Inodes and files operations
+ */
+@@ -1303,6 +1303,32 @@ extern int ext4_get_blocks_wrap(handle_t
+ set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
+ }
+
++static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb,
++ ext4_group_t group)
++{
++ struct blockgroup_lock *bgl = &EXT4_SB(sb)->s_blockgroup_lock;
++ return &bgl->locks[group & (NR_BG_LOCKS-1)].lock;
++}
++
++static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
++{
++ spin_lock(ext4_group_lock_ptr(sb, group));
++}
++
++static inline void ext4_unlock_group(struct super_block *sb,
++ ext4_group_t group)
++{
++ spin_unlock(ext4_group_lock_ptr(sb, group));
++}
++
++static inline int ext4_is_group_locked(struct super_block *sb,
++ ext4_group_t group)
++{
++ return spin_is_locked(ext4_group_lock_ptr(sb, group));
++}
++
++
++
+ #endif /* __KERNEL__ */
+
+ #endif /* _EXT4_H */
--- /dev/null
+diff -up linux-2.6.18-164/fs/ext4/ext4.h linux-2.6.18-164/fs/ext4/ext4.h
+--- linux-2.6.18-164/fs/ext4/ext4.h 2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/ext4.h 2009-10-16 23:31:41.000000000 +0800
+@@ -539,6 +539,7 @@ do { \
+ #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
+ #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
+ #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
++#define EXT4_MOUNT_EXTENTS 0x400000 /* Extents support */
+ #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
+ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
+ #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */
+diff -up linux-2.6.18-164/fs/ext4/ext4_jbd2.h linux-2.6.18-164/fs/ext4/ext4_jbd2.h
+--- linux-2.6.18-164/fs/ext4/ext4_jbd2.h 2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/ext4_jbd2.h 2009-10-16 23:32:02.000000000 +0800
+@@ -33,7 +33,7 @@
+
+ #define EXT4_SINGLEDATA_TRANS_BLOCKS(sb) \
+ (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS) \
+- ? 27U : 8U)
++ || test_opt(sb, EXTENTS) ? 27U : 8U)
+
+ /* Indicate that EXT4_SINGLEDATA_TRANS_BLOCKS takes the sb as argument */
+ #define EXT4_SINGLEDATA_TRANS_BLOCKS_HAS_SB
+diff -up linux-2.6.18-164/fs/ext4/extents.c linux-2.6.18-164/fs/ext4/extents.c
+--- linux-2.6.18-164/fs/ext4/extents.c 2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/extents.c 2009-10-16 23:33:36.000000000 +0800
+@@ -2313,7 +2313,7 @@ void ext4_ext_init(struct super_block *s
+ * possible initialization would be here
+ */
+
+- if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
++ if (test_opt(sb, EXTENTS)) {
+ printk(KERN_INFO "EXT4-fs: file extents enabled");
+ #ifdef AGGRESSIVE_TEST
+ printk(", aggressive tests");
+@@ -2338,7 +2338,7 @@ void ext4_ext_init(struct super_block *s
+ */
+ void ext4_ext_release(struct super_block *sb)
+ {
+- if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
++ if (!test_opt(sb, EXTENTS))
+ return;
+
+ #ifdef EXTENTS_STATS
+diff -up linux-2.6.18-164/fs/ext4/ialloc.c linux-2.6.18-164/fs/ext4/ialloc.c
+--- linux-2.6.18-164/fs/ext4/ialloc.c 2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/ialloc.c 2009-10-16 23:34:38.000000000 +0800
+@@ -938,7 +938,7 @@ got:
+ if (err)
+ goto fail_free_drop;
+
+- if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
++ if (test_opt(sb, EXTENTS)) {
+ /* set extent flag only for directory, file and normal symlink*/
+ if (S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) {
+ EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
+diff -up linux-2.6.18-164/fs/ext4/migrate.c linux-2.6.18-164/fs/ext4/migrate.c
+--- linux-2.6.18-164/fs/ext4/migrate.c 2009-09-28 16:11:26.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/migrate.c 2009-10-16 23:36:49.000000000 +0800
+@@ -459,13 +459,13 @@ int ext4_ext_migrate(struct inode *inode
+ struct list_blocks_struct lb;
+ unsigned long max_entries;
+
+- /*
+- * If the filesystem does not support extents, or the inode
+- * already is extent-based, error out.
+- */
+- if (!EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
+- EXT4_FEATURE_INCOMPAT_EXTENTS) ||
+- (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
++ if (!test_opt(inode->i_sb, EXTENTS))
++ /*
++ * if mounted with noextents we don't allow the migrate
++ */
++ return -EINVAL;
++
++ if ((EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
+ return -EINVAL;
+
+ if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0)
+diff -up linux-2.6.18-164/fs/ext4/super.c linux-2.6.18-164/fs/ext4/super.c
+--- linux-2.6.18-164/fs/ext4/super.c 2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/super.c 2009-10-16 23:48:19.000000000 +0800
+@@ -849,6 +849,8 @@ static int ext4_show_options(struct seq_
+ seq_puts(seq, ",journal_async_commit");
+ if (test_opt(sb, NOBH))
+ seq_puts(seq, ",nobh");
++ if (!test_opt(sb, EXTENTS))
++ seq_puts(seq, ",noextents");
+ if (test_opt(sb, I_VERSION))
+ seq_puts(seq, ",i_version");
+ if (!test_opt(sb, DELALLOC))
+@@ -1334,6 +1336,7 @@ enum {
+ Opt_inode_readahead_blks, Opt_journal_ioprio,
+ Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, Opt_bigendian_extents,
+ Opt_force_over_8tb,
++ Opt_extents, Opt_noextents,
+ };
+
+ static match_table_t tokens = {
+@@ -1401,6 +1404,8 @@ static match_table_t tokens = {
+ {Opt_noauto_da_alloc, "noauto_da_alloc"},
+ {Opt_bigendian_extents, "bigendian_extents"},
+ {Opt_force_over_8tb, "force_over_8tb"},
++ {Opt_extents, "extents"},
++ {Opt_noextents, "noextents"},
+ {Opt_err, NULL},
+ };
+
+@@ -1441,6 +1446,7 @@ static int parse_options(char *options,
+ int qtype, qfmt;
+ char *qname;
+ #endif
++ ext4_fsblk_t last_block;
+
+ if (!options)
+ return 1;
+@@ -1829,6 +1835,33 @@ set_qf_format:
+ case Opt_force_over_8tb:
+ force_over_8tb = 1;
+ break;
++ case Opt_extents:
++ if (!EXT4_HAS_INCOMPAT_FEATURE(sb,
++ EXT4_FEATURE_INCOMPAT_EXTENTS)) {
++ ext4_warning(sb, __func__,
++ "extents feature not enabled "
++ "on this filesystem, use tune2fs");
++ return 0;
++ }
++ set_opt(sbi->s_mount_opt, EXTENTS);
++ break;
++ case Opt_noextents:
++ /*
++ * When e2fsprogs support resizing an already existing
++ * ext3 file system to greater than 2**32 we need to
++ * add support to block allocator to handle growing
++ * already existing block mapped inode so that blocks
++ * allocated for them fall within 2**32
++ */
++ last_block = ext4_blocks_count(sbi->s_es) - 1;
++ if (last_block > 0xffffffffULL) {
++ printk(KERN_ERR "EXT4-fs: Filesystem too "
++ "large to mount with "
++ "-o noextents options\n");
++ return 0;
++ }
++ clear_opt(sbi->s_mount_opt, EXTENTS);
++ break;
+ default:
+ printk(KERN_ERR
+ "EXT4-fs: Unrecognized mount option \"%s\" "
+@@ -2501,6 +2534,18 @@ static int ext4_fill_super(struct super_
+ set_opt(sbi->s_mount_opt, BARRIER);
+
+ /*
++ * turn on extents feature by default in ext4 filesystem
++ * only if feature flag already set by mkfs or tune2fs.
++ * Use -o noextents to turn it off
++ */
++ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
++ set_opt(sbi->s_mount_opt, EXTENTS);
++ else
++ ext4_warning(sb, __func__,
++ "extents feature not enabled on this filesystem, "
++ "use tune2fs.");
++
++ /*
+ * enable delayed allocation by default
+ * Use -o nodelalloc to turn it off
+ */
--- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
+++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
@@ -300,6 +300,7 @@ struct ext4_new_group_data {
- #define EXT4_IOC_GETRSVSZ _IOR('f', 5, long)
- #define EXT4_IOC_SETRSVSZ _IOW('f', 6, long)
- #define EXT4_IOC_MIGRATE _IO('f', 7)
+ #define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
+ #define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input)
+ #define EXT4_IOC_MIGRATE _IO('f', 9)
+#define EXT4_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
+ /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */
/*
- * ioctl commands in 32 bit emulation
@@ -317,6 +318,8 @@ struct ext4_new_group_data {
#define EXT4_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION
#define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION
@@ -1117,6 +1120,9 @@ extern int ext4_page_mkwrite(struct vm_a
/* ioctl.c */
extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
- extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long);
+ extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
+struct fiemap_extent_info;
+extern int ext4_fiemap(struct inode *, struct fiemap_extent_info *, __u64,
+ __u64);
/* migrate.c */
extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
-Index: linux-2.6.18-128.1.6/fs/ext4/ext4_extents.h
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/ext4_extents.h
-+++ linux-2.6.18-128.1.6/fs/ext4/ext4_extents.h
-@@ -128,6 +128,22 @@ struct ext4_ext_path {
- #define EXT_MAX_BLOCK 0xffffffff
-
- /*
-+ * to be called by ext4_ext_walk_space()
-+ * negative retcode - error
-+ * positive retcode - signal for ext4_ext_walk_space(), see below
-+ * callback must return valid extent (passed or newly created)
-+ */
-+typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *,
-+ struct ext4_ext_cache *,
-+ struct ext4_extent *, void *);
-+
-+#define HAVE_EXT_PREPARE_CB_EXTENT
-+
-+#define EXT_CONTINUE 0
-+#define EXT_BREAK 1
-+#define EXT_REPEAT 2
-+
-+/*
- * 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
-@@ -223,6 +239,8 @@ extern int ext4_ext_try_to_merge(struct
- struct ext4_extent *);
- extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *);
- extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *);
-+extern int ext4_ext_walk_space(struct inode *, ext4_lblk_t, ext4_lblk_t,
-+ ext_prepare_callback, void *);
- extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t,
- struct ext4_ext_path *);
- extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *,
-Index: linux-2.6.18-128.1.6/fs/ext4/extents.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/extents.c
-+++ linux-2.6.18-128.1.6/fs/ext4/extents.c
-@@ -44,7 +44,7 @@
- #include <asm/uaccess.h>
- #include "ext4_jbd2.h"
- #include "ext4_extents.h"
--
-+#include "fiemap.h"
-
- /*
- * ext_pblock:
-@@ -1597,6 +1597,113 @@ cleanup:
- return err;
- }
-
-+int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
-+ ext4_lblk_t num, ext_prepare_callback func,
-+ void *cbdata)
-+{
-+ struct ext4_ext_path *path = NULL;
-+ struct ext4_ext_cache cbex;
-+ struct ext4_extent *ex;
-+ ext4_lblk_t next, start = 0, end = 0;
-+ ext4_lblk_t last = block + num;
-+ int depth, exists, err = 0;
-+
-+ BUG_ON(func == NULL);
-+ BUG_ON(inode == NULL);
-+
-+ while (block < last && block != EXT_MAX_BLOCK) {
-+ num = last - block;
-+ /* find extent for this block */
-+ path = ext4_ext_find_extent(inode, block, path);
-+ if (IS_ERR(path)) {
-+ err = PTR_ERR(path);
-+ path = NULL;
-+ break;
-+ }
-+
-+ depth = ext_depth(inode);
-+ BUG_ON(path[depth].p_hdr == NULL);
-+ ex = path[depth].p_ext;
-+ next = ext4_ext_next_allocated_block(path);
-+
-+ exists = 0;
-+ if (!ex) {
-+ /* there is no extent yet, so try to allocate
-+ * all requested space */
-+ start = block;
-+ end = block + num;
-+ } else if (le32_to_cpu(ex->ee_block) > block) {
-+ /* need to allocate space before found extent */
-+ start = block;
-+ end = le32_to_cpu(ex->ee_block);
-+ if (block + num < end)
-+ end = block + num;
-+ } else if (block >= le32_to_cpu(ex->ee_block)
-+ + ext4_ext_get_actual_len(ex)) {
-+ /* need to allocate space after found extent */
-+ start = block;
-+ end = block + num;
-+ if (end >= next)
-+ end = next;
-+ } else if (block >= le32_to_cpu(ex->ee_block)) {
-+ /*
-+ * some part of requested space is covered
-+ * by found extent
-+ */
-+ start = block;
-+ end = le32_to_cpu(ex->ee_block)
-+ + ext4_ext_get_actual_len(ex);
-+ if (block + num < end)
-+ end = block + num;
-+ exists = 1;
-+ } else {
-+ BUG();
-+ }
-+ BUG_ON(end <= start);
-+
-+ if (!exists) {
-+ cbex.ec_block = start;
-+ cbex.ec_len = end - start;
-+ cbex.ec_start = 0;
-+ cbex.ec_type = EXT4_EXT_CACHE_GAP;
-+ } else {
-+ cbex.ec_block = le32_to_cpu(ex->ee_block);
-+ cbex.ec_len = ext4_ext_get_actual_len(ex);
-+ cbex.ec_start = ext_pblock(ex);
-+ cbex.ec_type = EXT4_EXT_CACHE_EXTENT;
-+ }
-+
-+ BUG_ON(cbex.ec_len == 0);
-+ err = func(inode, path, &cbex, ex, cbdata);
-+ ext4_ext_drop_refs(path);
-+
-+ if (err < 0)
-+ break;
-+
-+ if (err == EXT_REPEAT)
-+ continue;
-+ else if (err == EXT_BREAK) {
-+ err = 0;
-+ break;
-+ }
-+
-+ if (ext_depth(inode) != depth) {
-+ /* depth was changed. we have to realloc path */
-+ kfree(path);
-+ path = NULL;
-+ }
-+
-+ block = cbex.ec_block + cbex.ec_len;
-+ }
-+
-+ if (path) {
-+ ext4_ext_drop_refs(path);
-+ kfree(path);
-+ }
-+
-+ return err;
-+}
-+
- static void
- ext4_ext_put_in_cache(struct inode *inode, ext4_lblk_t block,
- __u32 len, ext4_fsblk_t start, int type)
-@@ -2953,3 +3060,100 @@ retry:
- return ret > 0 ? ret2 : ret;
- }
- #endif
-+
-+/*
-+ * Callback function called for each extent to gather FIEMAP information.
-+ */
-+int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
-+ struct ext4_ext_cache *newex, struct ext4_extent *ex,
-+ void *data)
-+{
-+ struct fiemap_extent_info *fieinfo = data;
-+ unsigned char 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 == EXT4_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 && ext4_ext_is_uninitialized(ex))
-+ flags |= FIEMAP_EXTENT_UNWRITTEN;
-+
-+ /*
-+ * If this extent reaches EXT_MAX_BLOCK, it must be last.
-+ *
-+ * Or if ext4_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 (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK ||
-+ newex->ec_block + newex->ec_len - 1 == 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 ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
-+ __u64 start, __u64 len)
-+{
-+ ext4_fsblk_t start_blk;
-+ ext4_fsblk_t len_blks;
-+ int error = 0;
-+
-+ if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
-+ return -EOPNOTSUPP;
-+
-+ if (fiemap_check_flags(fieinfo, EXT4_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;
-+
-+ /*
-+ * Walk the extent tree gathering extent information.
-+ * ext4_ext_fiemap_cb will push extents back to user.
-+ */
-+ down_write(&EXT4_I(inode)->i_data_sem);
-+ error = ext4_ext_walk_space(inode, start_blk, len_blks,
-+ ext4_ext_fiemap_cb, fieinfo);
-+ up_write(&EXT4_I(inode)->i_data_sem);
-+
-+ return error;
-+}
Index: linux-2.6.18-128.1.6/fs/ext4/fiemap.h
===================================================================
--- /dev/null
--- linux-2.6.18.i386.orig/fs/ext4/ext4_i.h
+++ linux-2.6.18.i386/fs/ext4/ext4_i.h
@@ -162,6 +162,8 @@ struct ext4_inode_info {
- /* mballoc */
- struct list_head i_prealloc_list;
- spinlock_t i_prealloc_lock;
+ __u16 i_extra_isize;
+
+ spinlock_t i_block_reservation_lock;
+
+ void *i_filterdata;
};
--- linux-2.6.18.i386.orig/fs/ext4/super.c
+++ linux-2.6.18.i386/fs/ext4/super.c
@@ -574,6 +574,7 @@ static struct inode *ext4_alloc_inode(st
- memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
- INIT_LIST_HEAD(&ei->i_prealloc_list);
- spin_lock_init(&ei->i_prealloc_lock);
+ ei->i_allocated_meta_blocks = 0;
+ ei->i_delalloc_reserved_flag = 0;
+ spin_lock_init(&(ei->i_block_reservation_lock));
+ ei->i_filterdata = NULL;
return &ei->vfs_inode;
}
+
+out_journal:
+ if (journal) {
-+ BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata");
-+ err = ext4_journal_dirty_metadata(handle, dir_block);
++ BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
++ err = ext4_handle_dirty_metadata(handle, dir, dir_block);
+ ext4_mark_inode_dirty(handle, dir);
+ }
+ brelse (dir_block);
};
#endif /* _EXT4_I */
-Index: linux-2.6.18-128.1.6/fs/ext4/xattr.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/xattr.c
-+++ linux-2.6.18-128.1.6/fs/ext4/xattr.c
-@@ -959,13 +959,18 @@ ext4_xattr_set_handle(handle_t *handle,
- struct ext4_xattr_block_find bs = {
- .s = { .not_found = -ENODATA, },
- };
-+ unsigned long no_expand;
- int error;
-
- if (!name)
- return -EINVAL;
- if (strlen(name) > 255)
- return -ERANGE;
-+
- down_write(&EXT4_I(inode)->xattr_sem);
-+ no_expand = EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND;
-+ EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
-+
- error = ext4_get_inode_loc(inode, &is.iloc);
- if (error)
- goto cleanup;
-@@ -1042,6 +1047,8 @@ ext4_xattr_set_handle(handle_t *handle,
- cleanup:
- brelse(is.iloc.bh);
- brelse(bs.bh);
-+ if (no_expand == 0)
-+ EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND;
- up_write(&EXT4_I(inode)->xattr_sem);
- return error;
- }
Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
===================================================================
--- linux-2.6.18-128.1.6.orig/fs/ext4/ialloc.c
struct buffer_head *bh;
struct dx_frame *frame = frame_in;
u32 hash;
-@@ -388,46 +389,46 @@ dx_probe(struct dentry *dentry, struct i
+@@ -388,18 +389,19 @@ dx_probe(struct dentry *dentry, struct i
dir = dentry->d_parent->d_inode;
if (!(bh = ext4_bread (NULL,dir, 0, 0, err)))
goto fail;
}
- hinfo->hash_version = root->info.hash_version;
+ hinfo->hash_version = info->hash_version;
+ if (hinfo->hash_version <= DX_HASH_TEA)
+ hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
- if (dentry)
+@@ -398,29 +399,28 @@ dx_probe(struct dentry *dentry, struct i
ext4fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
hash = hinfo->hash;
bh2 = ext4_append (handle, dir, &block, &retval);
if (!(bh2)) {
-@@ -1460,11 +1461,13 @@ static int make_indexed_dir(handle_t *ha
- EXT4_I(dir)->i_flags |= EXT4_INDEX_FL;
- data1 = bh2->b_data;
+@@ -1460,18 +1461,20 @@ static int make_indexed_dir(handle_t *ha
+ }
+ root = (struct dx_root *) bh->b_data;
+ dot_de = (struct ext4_dir_entry_2 *) bh->b_data;
+ dotdot_de = ext4_next_entry(dot_de);
- fde = &root->dotdot;
- de = (struct ext4_dir_entry_2 *)((char *)fde +
- ext4_rec_len_from_disk(fde->rec_len));
-- len = ((char *) root) + blocksize - (char *) de;
+ de = (struct ext4_dir_entry_2 *)((char *)dotdot_de +
+ ext4_rec_len_from_disk(dotdot_de->rec_len));
+- if ((char *) de >= (((char *) root) + blocksize)) {
++ if ((char *) de >= (((char *) dot_de) + blocksize)) {
+ ext4_error(dir->i_sb, __func__,
+ "invalid rec_len for '..' in inode %lu",
+ dir->i_ino);
+ brelse(bh);
+ return -EIO;
+ }
+- len = ((char *) root) + blocksize - (char *) de;
+ len = ((char *) dot_de) + blocksize - (char *) de;
- memcpy (data1, de, len);
- de = (struct ext4_dir_entry_2 *) data1;
- top = data1 + len;
-@@ -1472,18 +1475,24 @@ static int make_indexed_dir(handle_t *ha
+
+ /* Allocate new block for the 0th block's dirents */
+ bh2 = ext4_append(handle, dir, &block, &retval);
+@@ -1472,18 +1475,23 @@ static int make_indexed_dir(handle_t *ha
de = de2;
de->rec_len = ext4_rec_len_to_disk(data1 + blocksize - (char *) de);
/* Initialize the root; the dot dirents already exist */
- root->info.info_length = sizeof(root->info);
- root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
- entries = root->entries;
-- dx_set_block (entries, 1);
-- dx_set_count (entries, 1);
-- dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
+- dx_set_block(entries, 1);
+- dx_set_count(entries, 1);
+- dx_set_limit(entries, dx_root_limit(dir, sizeof(root->info)));
+ dotdot_de->rec_len = ext4_rec_len_to_disk(blocksize -
+ le16_to_cpu(dot_de->rec_len));
+
/* Initialize as for dx_probe */
- hinfo.hash_version = root->info.hash_version;
+ hinfo.hash_version = dx_info->hash_version;
-+
+ if (hinfo.hash_version <= DX_HASH_TEA)
+ hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
- ext4fs_dirhash(name, namelen, &hinfo);
- frame = frames;
@@ -1724,6 +1733,7 @@ static int ext4_dx_add_entry(handle_t *h
goto journal_error;
brelse (bh2);
} else {
+ struct dx_root_info * info;
- dxtrace(printk("Creating second level index...\n"));
+ dxtrace(printk(KERN_DEBUG
+ "Creating second level index...\n"));
memcpy((char *) entries2, (char *) entries,
- icount * sizeof(struct dx_entry));
@@ -1732,7 +1742,9 @@ static int ext4_dx_add_entry(handle_t *h
/* Set up root */
dx_set_count(entries, 1);
--- linux-2.6.18.i386.orig/fs/ext4/ialloc.c
+++ linux-2.6.18.i386/fs/ext4/ialloc.c
@@ -622,12 +622,15 @@ struct inode *ext4_new_inode(handle_t *h
- return ERR_PTR(-EPERM);
-
sb = dir->i_sb;
+ trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id,
+ dir->i_ino, mode);
+ sbi = EXT4_SB(sb);
+ if (sbi->s_max_dir_size > 0 && i_size_read(dir) >= sbi->s_max_dir_size)
+ return ERR_PTR(-EFBIG);
#include "ext4.h"
#include "ext4_jbd2.h"
-@@ -67,6 +68,8 @@ static void ext4_write_super_lockfs(stru
-
- struct page *ext4_zero_page;
-
-+struct proc_dir_entry *proc_root_ext4;
-+
- ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
- struct ext4_group_desc *bg)
- {
-@@ -551,6 +554,9 @@ static void ext4_put_super(struct super_
- }
- if (sbi->s_mmp_tsk)
- kthread_stop(sbi->s_mmp_tsk);
-+
-+ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
-+
- sb->s_fs_info = NULL;
- kfree(sbi);
- return;
-@@ -2185,6 +2191,46 @@ static unsigned long ext4_get_stripe_siz
+@@ -551,6 +554,7 @@ static void ext4_put_super(struct super_
+ ext4_commit_super(sb, es, 1);
+ }
+ if (sbi->s_proc) {
++ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_proc);
+ remove_proc_entry("inode_readahead_blks", sbi->s_proc);
+ remove_proc_entry(sb->s_id, ext4_proc_root);
+ }
+@@ -2185,6 +2191,48 @@ static unsigned long ext4_get_stripe_siz
return 0;
}
++#ifdef CONFIG_PROC_FS
+static int ext4_max_dir_size_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ sbi->s_max_dir_size = value;
+ return count;
+}
++#endif
+
static int ext4_fill_super(struct super_block *sb, void *data, int silent)
__releases(kernel_lock)
__acquires(kernel_lock)
-@@ -2208,6 +2254,7 @@ static int ext4_fill_super(struct super_
- int needs_recovery;
- __le32 features;
- __u64 blocks_count;
-+ struct proc_dir_entry *proc;
-
- sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
- if (!sbi)
-@@ -2743,6 +2790,22 @@ static int ext4_fill_super(struct super_
- ext4_ext_init(sb);
- ext4_mb_init(sb, needs_recovery);
-
-+ sbi->s_max_dir_size = EXT4_DEFAULT_MAX_DIR_SIZE;
-+ proc = create_proc_entry(EXT4_MAX_DIR_SIZE_NAME,
-+ S_IFREG | S_IRUGO | S_IWUSR, sbi->s_mb_proc);
-+ if (proc == NULL) {
-+ printk(KERN_ERR "EXT4-fs: unable to create %s\n",
-+ EXT4_MAX_DIR_SIZE_NAME);
-+ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
-+ remove_proc_entry(sbi->s_mb_proc->name, proc_root_ext4);
-+ sbi->s_mb_proc = NULL;
-+ ret = -ENOMEM;
-+ goto failed_mount4;
-+ }
-+ proc->data = sbi;
-+ proc->read_proc = ext4_max_dir_size_read;
-+ proc->write_proc = ext4_max_dir_size_write;
+@@ -2743,6 +2790,20 @@ static int ext4_fill_super(struct super_
+ p->proc_fops = &ext4_ui_proc_fops,
+ p->data = &sbi->s_inode_goal;
+ }
++ sbi->s_max_dir_size = EXT4_DEFAULT_MAX_DIR_SIZE;
++ p = create_proc_entry(EXT4_MAX_DIR_SIZE_NAME,
++ S_IFREG | S_IRUGO | S_IWUSR, sbi->s_proc);
++ if (p == NULL) {
++ printk(KERN_ERR "EXT4-fs: unable to create %s\n",
++ EXT4_MAX_DIR_SIZE_NAME);
++ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_proc);
++ ret = -ENOMEM;
++ goto failed_mount;
++ }
++ p->data = sbi;
++ p->read_proc = ext4_max_dir_size_read;
++ p->write_proc = ext4_max_dir_size_write;
+
- lock_kernel();
- return 0;
-
-@@ -3082,7 +3145,6 @@ static void ext4_commit_super(struct sup
- sync_dirty_buffer(sbh);
- }
+ }
+ #endif
--
- /*
- * Have we just finished recovery? If so, and if we are mounting (or
- * remounting) the filesystem readonly, then we will end up with a
Index: linux-2.6.18.i386/fs/ext4/ext4_sb.h
===================================================================
--- linux-2.6.18.i386.orig/fs/ext4/ext4_sb.h
===================================================================
--- linux-2.6.18.i386.orig/fs/ext4/ext4.h
+++ linux-2.6.18.i386/fs/ext4/ext4.h
-@@ -992,6 +992,14 @@ struct mmp_struct {
+@@ -992,6 +992,12 @@ struct mmp_struct {
*/
#define EXT4_MMP_MIN_CHECK_INTERVAL 5
-+extern struct proc_dir_entry *proc_root_ext4;
-+
+/*
+ * max directory size tunable
+ */
/*
* Function prototypes
*/
-Index: linux-2.6.18.i386/fs/ext4/mballoc.h
-===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/mballoc.h
-+++ linux-2.6.18.i386/fs/ext4/mballoc.h
-@@ -257,7 +257,6 @@ static void ext4_mb_store_history(struct
-
- #define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
-
--static struct proc_dir_entry *proc_root_ext4;
- struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t);
-
- static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
-Index: linux-2.6.18.i386/fs/ext4/mballoc.c
-===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/mballoc.c
-+++ linux-2.6.18.i386/fs/ext4/mballoc.c
-@@ -2821,6 +2821,7 @@ err_out:
- remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
- remove_proc_entry(devname, proc_root_ext4);
- sbi->s_mb_proc = NULL;
-
-@@ -2842,7 +2843,9 @@ static int ext4_mb_destroy_per_dev_proc(
- remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
- remove_proc_entry(devname, proc_root_ext4);
-+ sbi->s_mb_proc = NULL;
-
- return 0;
- }
diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/ext4/mballoc.c
---- linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c 2009-09-28 16:38:04.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/mballoc.c 2009-09-28 16:40:35.000000000 +0530
+--- linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c
++++ linux-2.6.18-128.1.6_2//fs/ext4/mballoc.c
+@@ -360,8 +360,8 @@ static void ext4_mb_mark_free_simple(str
+ static struct kmem_cache *ext4_pspace_cachep;
+ static struct kmem_cache *ext4_ac_cachep;
+ static struct kmem_cache *ext4_free_ext_cachep;
+-static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
+- ext4_group_t group);
++static int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
++ ext4_group_t group);
+ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
+ ext4_group_t group);
+
@@ -660,7 +660,7 @@ static void ext4_mb_mark_free_simple(str
}
}
grp->bb_fragments = fragments;
if (free != grp->bb_free) {
-- ext4_error(sb, __func__,
-- "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n",
+- ext4_grp_locked_error(sb, group, __func__,
+- "EXT4-fs: group %u: %u blocks in bitmap, %u in gd",
- group, free, grp->bb_free);
- /*
- * If we intent to continue, we consider group descritor
+ ext4_error(sb, __FUNCTION__,
+ "group %lu: %u blocks in bitmap, %u in bb, "
+ "%u in gd, %lu pa's\n", group, free, grp->bb_free,
-+ le16_to_cpu(gdp->bg_free_blocks_count),
++ ext4_free_blks_count(sb, gdp),
+ grp->bb_prealloc_nr);
+ return -EIO;
}
/* The buddy information is attached the buddy cache inode
@@ -814,7 +816,7 @@ static int ext4_mb_init_cache(struct pag
-
- err = 0;
first_block = page->index * blocks_per_page;
+ /* init the page */
+ memset(page_address(page), 0xff, PAGE_CACHE_SIZE);
- for (i = 0; i < blocks_per_page; i++) {
+ for (i = 0; i < blocks_per_page && err == 0; i++) {
int group;
struct ext4_group_info *grinfo;
@@ -848,7 +850,7 @@ static int ext4_mb_init_cache(struct pag
- /*
* incore got set to the group block bitmap below
*/
+ ext4_lock_group(sb, group);
- ext4_mb_generate_buddy(sb, data, incore, group);
+ err = ext4_mb_generate_buddy(sb, data, incore, group);
+ ext4_unlock_group(sb, group);
incore = NULL;
} else {
- /* this is block of bitmap */
@@ -861,7 +863,7 @@ static int ext4_mb_init_cache(struct pag
memcpy(data, bitmap, blocksize);
/* mark all preallocated blks used in in-core bitmap */
- ext4_mb_generate_from_pa(sb, data, group);
+ err = ext4_mb_generate_from_pa(sb, data, group);
+ ext4_mb_generate_from_freelist(sb, data, group);
ext4_unlock_group(sb, group);
- /* set incore so that the buddy information can be
@@ -870,6 +872,7 @@ static int ext4_mb_init_cache(struct pag
incore = data;
}
{
struct super_block *sb = seq->private;
+ struct ext4_group_desc *gdp;
- long group = (long) v;
+ ext4_group_t group = (ext4_group_t) ((unsigned long) v);
int i;
int err;
+ int free = 0;
+
+ gdp = ext4_get_group_desc(sb, group, NULL);
+ if (gdp != NULL)
-+ free = le16_to_cpu(gdp->bg_free_blocks_count);
++ free = ext4_free_blks_count(sb, gdp);
+
ext4_lock_group(sb, group);
memcpy(&sg, ext4_get_group_info(sb, group), i);
ext4_unlock_group(sb, group);
ext4_mb_release_desc(&e4b);
-- seq_printf(seq, "#%-5lu: %-5u %-5u %-5u [", group, sg.info.bb_free,
+- seq_printf(seq, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free,
- sg.info.bb_fragments, sg.info.bb_first_free);
+ seq_printf(seq, "#%-5lu: %-5u %-5u %-5u %-5u %-5lu [", group,
+ sg.info.bb_free, free,
+ i = mb_find_next_zero_bit(bitmap, max, i);
+ }
+
-+ if (free != le16_to_cpu(gdp->bg_free_blocks_count)) {
++ if (free != ext4_free_blks_count(sb, gdp)) {
+ ext4_error(sb, __FUNCTION__, "on-disk bitmap for group %d"
+ "corrupted: %u blocks free in bitmap, %u - in gd\n",
-+ group, free, le16_to_cpu(gdp->bg_free_blocks_count));
++ group, free, ext4_free_blks_count(sb, gdp));
+ return -EIO;
+ }
+ return 0;
+ count, grp->bb_prealloc_nr, skip);
+ return -EIO;
+ }
- mb_debug("prellocated %u for group %lu\n", preallocated, group);
+ mb_debug("prellocated %u for group %u\n", preallocated, group);
+ return 0;
}
@@ -4107,7 +4183,7 @@ repeat:
if (err) {
ext4_error(sb, __func__, "Error in loading buddy "
- "information for %lu\n", group);
+ "information for %u", group);
- continue;
+ return;
}
ext4_mb_release_group_pa(&e4b, pa, ac);
ext4_unlock_group(sb, group);
-diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.h linux-2.6.18-128.1.6_2//fs/ext4/mballoc.h
---- linux-2.6.18-128.1.6_1//fs/ext4/mballoc.h 2009-09-28 16:38:04.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/mballoc.h 2009-09-28 16:38:43.000000000 +0530
+diff -rupN linux-2.6.18-128.1.6/fs/ext4/ext4.h
+--- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
++++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
@@ -119,6 +119,7 @@ struct ext4_group_info {
- unsigned short bb_free;
- unsigned short bb_fragments;
- struct list_head bb_prealloc_list;
+ unsigned short bb_free;
+ unsigned short bb_fragments;
+ struct list_head bb_prealloc_list;
+ unsigned long bb_prealloc_nr;
#ifdef DOUBLE_CHECK
void *bb_bitmap;
#endif
+Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.h
+===================================================================
+--- linux-2.6.18-128.1.6.orig/fs/ext4/mballoc.h
++++ linux-2.6.18-128.1.6/fs/ext4/mballoc.h
@@ -228,7 +229,7 @@ struct ext4_mb_history {
__u16 tail; /* what tail broke some buddy */
__u16 buddy; /* buddy the tail ^^^ broke */
__u8 op:4;
__u8 merged:1;
};
-@@ -259,7 +260,7 @@ static void ext4_mb_store_history(struct
-
- struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t);
-
--static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
-+static int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
- ext4_group_t group);
- static void ext4_mb_poll_new_transaction(struct super_block *, handle_t *);
- static void ext4_mb_free_committed_blocks(struct super_block *);
===================================================================
--- linux-2.6.18.i386.orig/fs/ext4/ext4_jbd2.h
+++ linux-2.6.18.i386/fs/ext4/ext4_jbd2.h
-@@ -35,6 +35,9 @@
+@@ -35,6 +35,11 @@
(EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS) \
|| test_opt(sb, EXTENTS) ? 27U : 8U)
+/* Indicate that EXT4_SINGLEDATA_TRANS_BLOCKS takes the sb as argument */
+#define EXT4_SINGLEDATA_TRANS_BLOCKS_HAS_SB
+
++#define ext4_journal_dirty_metadata(handle, bh) \
++ ext4_handle_dirty_metadata(handle, NULL, bh)
/* Extended attribute operations touch at most two data buffers,
* two bitmap buffers, and two group summaries, in addition to the inode
* and the superblock, which are already accounted for. */
* ext4_ext_calc_credits_for_single_extent:
* This routine returns max. credits that needed to insert an extent
* to the extent tree.
-@@ -3157,3 +3207,14 @@ int ext4_fiemap(struct inode *inode, str
+@@ -3157,4 +3207,14 @@ int ext4_fiemap(struct inode *inode, str
return error;
}
+EXPORT_SYMBOL(ext4_ext_walk_space);
+EXPORT_SYMBOL(ext4_ext_calc_credits_for_insert);
+EXPORT_SYMBOL(ext4_mark_inode_dirty);
-+
+
Index: linux-2.6.18.i386/fs/ext4/ext4_extents.h
===================================================================
--- linux-2.6.18.i386.orig/fs/ext4/ext4_extents.h
+++ linux-2.6.18.i386/fs/ext4/ext4_extents.h
-@@ -59,6 +59,11 @@
+@@ -59,6 +59,12 @@
*/
#define EXT_STATS_
+ * are now accounted in ext4_ext_calc_credits_for_insert()
+ */
+#define EXT4_ALLOC_NEEDED 0
++#define HAVE_EXT_PREPARE_CB_EXTENT
/*
* ext4_inode has i_block array (60 bytes total).
#define EXT_MAX_BLOCK 0xffffffff
-@@ -228,9 +234,13 @@ static inline int ext4_ext_get_actual_le
- (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
+@@ -228,9 +234,12 @@ static inline int ext4_ext_get_actual_le
}
+ extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks);
+extern ext4_fsblk_t ext_pblock(struct ext4_extent *ex);
-+extern void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb);
extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *);
extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t);
extern int ext4_extent_tree_init(handle_t *, struct inode *);
===================================================================
--- linux-2.6.18.i386.orig/fs/ext4/mballoc.c
+++ linux-2.6.18.i386/fs/ext4/mballoc.c
-@@ -4965,3 +4965,7 @@ error_return:
+@@ -4355,6 +4355,13 @@
+ kmem_cache_free(ext4_ac_cachep, ac);
+ }
+
++/* For backward compatibility, since Lustre uses this symbol */
++void ext4_mb_discard_inode_preallocations(struct inode *inode)
++{
++ ext4_discard_preallocations(inode);
++}
++EXPORT_SYMBOL(ext4_mb_discard_inode_preallocations);
++
+ /*
+ * finds all preallocated spaces and return blocks being freed to them
+ * if preallocated space becomes full (no block is used from the space)
+@@ -4965,3 +4965,6 @@ error_return:
kmem_cache_free(ext4_ac_cachep, ac);
return;
}
+
+EXPORT_SYMBOL(ext4_free_blocks);
-+EXPORT_SYMBOL(ext4_mb_discard_inode_preallocations);
+
Index: linux-2.6.18.i386/fs/ext4/super.c
===================================================================
ext4_fsblk_t ext4_inode_table(struct super_block *sb,
struct ext4_group_desc *bg)
-@@ -513,7 +514,8 @@ static void ext4_put_super(struct super_
- struct ext4_super_block *es = sbi->s_es;
- int i;
-
-- ext4_mb_release(sb);
-+ if (test_opt(sb, MBALLOC))
-+ ext4_mb_release(sb);
- ext4_ext_release(sb);
- ext4_xattr_put_super(sb);
- jbd2_journal_destroy(sbi->s_journal);
-@@ -2373,16 +2375,6 @@ static int ext4_fill_super(struct super_
- "running e2fsck is recommended\n");
-
- /*
-- * Since ext4 is still considered development code, we require
-- * that the TEST_FILESYS flag in s->flags be set.
-- */
-- if (!(le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS)) {
-- printk(KERN_WARNING "EXT4-fs: %s: not marked "
-- "OK to use with test code.\n", sb->s_id);
-- goto failed_mount;
-- }
--
-- /*
- * Check feature flags regardless of the revision level, since we
- * previously didn't change the revision level when setting the flags,
- * so there is a chance incompat flags are set on a rev 0 filesystem.
-@@ -3835,9 +3827,9 @@ static int ext4_get_sb(struct file_syste
- return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt);
+@@ -113,6 +118,7 @@
+ (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+ (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
}
-
--static struct file_system_type ext4dev_fs_type = {
-+static struct file_system_type ext4_fs_type = {
- .owner = THIS_MODULE,
-- .name = "ext4dev",
-+ .name = "ext4",
- .get_sb = ext4_get_sb,
- .kill_sb = kill_block_super,
- #ifdef HAVE_FALLOCATE
-@@ -3867,7 +3859,7 @@ static int __init init_ext4_fs(void)
- err = init_inodecache();
- if (err)
- goto out1;
-- err = register_filesystem(&ext4dev_fs_type);
-+ err = register_filesystem(&ext4_fs_type);
- if (err)
- goto out;
- return 0;
-@@ -3884,7 +3876,7 @@ out3:
-
- static void __exit exit_ext4_fs(void)
- {
-- unregister_filesystem(&ext4dev_fs_type);
-+ unregister_filesystem(&ext4_fs_type);
- destroy_inodecache();
- exit_ext4_xattr();
- exit_ext4_mballoc();
++EXPORT_SYMBOL(ext4_itable_unused_count);
+
+ void ext4_block_bitmap_set(struct super_block *sb,
+ struct ext4_group_desc *bg, ext4_fsblk_t blk)
Index: linux-2.6.18.i386/fs/ext4/ext4_jbd2.c
===================================================================
--- linux-2.6.18.i386.orig/fs/ext4/ext4_jbd2.c
ext4_journal_abort_handle(where, __func__, bh, handle, err);
return err;
}
-+EXPORT_SYMBOL(__ext4_journal_dirty_metadata);
++EXPORT_SYMBOL(__ext4_handle_dirty_metadata);
+Index: linux-2.6.27.21-0.1/fs/ext4/ext4.h
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/ext4.h 2009-07-07 14:47:19.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/ext4.h 2009-07-07 14:47:22.000000000 +0530
+@@ -1123,6 +1128,8 @@
+ extern int ext4_mb_get_buddy_cache_lock(struct super_block *, ext4_group_t);
+ extern void ext4_mb_put_buddy_cache_lock(struct super_block *,
+ ext4_group_t, int);
++extern void ext4_mb_discard_inode_preallocations(struct inode *);
++
+ /* inode.c */
+ int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
+ struct buffer_head *bh, ext4_fsblk_t blocknr);
+Index: linux-2.6.27.21-0.1/fs/ext4/inode.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/inode.c 2009-07-07 14:47:19.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/inode.c 2009-07-07 14:47:22.000000000 +0530
+@@ -4240,6 +4240,7 @@
+ iget_failed(inode);
+ return ERR_PTR(ret);
+ }
++EXPORT_SYMBOL(ext4_iget);
+
+ static int ext4_inode_blocks_set(handle_t *handle,
+ struct ext4_inode *raw_inode,
+Index: linux-2.6.27.21-0.1/fs/ext4/super.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/super.c 2009-07-07 14:47:19.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/super.c 2009-07-07 14:48:53.000000000 +0530
+@@ -1286,6 +1287,7 @@
+ Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
+ Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
+ Opt_usrquota, Opt_grpquota, Opt_i_version,
++ Opt_mballoc,
+ Opt_stripe, Opt_delalloc, Opt_nodelalloc,
+ Opt_inode_readahead_blks, Opt_journal_ioprio,
+ Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, Opt_bigendian_extents,
+@@ -1346,6 +1348,7 @@
+ {Opt_barrier, "barrier"},
+ {Opt_nobarrier, "nobarrier"},
+ {Opt_i_version, "i_version"},
++ {Opt_mballoc, "mballoc"},
+ {Opt_stripe, "stripe=%u"},
+ {Opt_resize, "resize"},
+ {Opt_delalloc, "delalloc"},
+@@ -1768,6 +1771,8 @@
+ case Opt_bigendian_extents:
+ bigendian_extents = 1;
+ break;
++ case Opt_mballoc:
++ break;
+ default:
+ printk(KERN_ERR
+ "EXT4-fs: Unrecognized mount option \"%s\" "
+Index: linux-2.6.27.21-0.1/fs/ext4/fsync.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/fsync.c 2009-07-07 14:47:19.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/fsync.c 2009-07-07 14:48:53.000000000 +0530
+@@ -1768,7 +1771,7 @@
+
+ trace_mark(ext4_sync_file, "dev %s datasync %d ino %ld parent %ld",
+ inode->i_sb->s_id, datasync, inode->i_ino,
+- dentry->d_parent->d_inode->i_ino);
++ 0L);
+
+ /*
+ * data=writeback:
* The first inode we look at is the journal inode. Don't try
* root first: it may be modified in the journal!
@@ -2445,6 +2775,8 @@ failed_mount3:
- percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
+ percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
+ if (sbi->s_mmp_tsk)
+ kthread_stop(sbi->s_mmp_tsk);
failed_mount2:
for (i = 0; i < db_count; i++)
brelse(sbi->s_group_desc[i]);
@@ -2918,7 +3250,7 @@ static int ext4_remount(struct super_blo
- unsigned long old_sb_flags;
struct ext4_mount_options old_opts;
ext4_group_t g;
+ unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
- int err;
+ int err = 0;
#ifdef CONFIG_QUOTA
-diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/ext4.h linux-2.6.18-128.1.6_2//fs/ext4/ext4.h
---- linux-2.6.18-128.1.6_1//fs/ext4/ext4.h 2009-08-24 15:54:11.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/ext4.h 2009-08-24 15:54:52.000000000 +0530
-@@ -1144,6 +1144,18 @@ extern int ext4_fiemap(struct inode *, s
- extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
- unsigned long);
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/ext4.h linux-2.6.27.21-0.1_2//fs/ext4/ext4.h
+--- linux-2.6.27.21-0.1_1//fs/ext4/ext4.h 2009-08-24 15:32:00.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/ext4.h 2009-08-24 15:32:55.000000000 +0530
+@@ -1171,6 +1171,19 @@ extern int ext4_fiemap(struct inode *, s
+ /* migrate.c */
+ extern int ext4_ext_migrate(struct inode *);
/* namei.c */
+extern struct inode *ext4_create_inode(handle_t *handle,
-+ struct inode * dir, int mode);
++ struct inode * dir, int mode);
+extern int ext4_add_entry(handle_t *handle, struct dentry *dentry,
-+ struct inode *inode);
++ struct inode *inode);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
-+ struct ext4_dir_entry_2 * de_del,
-+ struct buffer_head * bh);
-+extern struct buffer_head * ext4_find_entry(struct dentry *dentry,
-+ struct ext4_dir_entry_2
-+ ** res_dir);
++ struct ext4_dir_entry_2 * de_del,
++ struct buffer_head * bh);
++extern struct buffer_head * ext4_find_entry(struct inode *dir,
++ const struct qstr *d_name,
++ struct ext4_dir_entry_2 ** res_dir);
++#define ll_ext4_find_entry(inode, dentry, res_dir) ext4_find_entry(dir, &(dentry)->d_name, res_dir)
+extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
-+ struct inode *inode);
++ struct inode *inode);
extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/inode.c linux-2.6.18-128.1.6_2//fs/ext4/inode.c
---- linux-2.6.18-128.1.6_1//fs/ext4/inode.c 2009-08-24 15:54:11.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/inode.c 2009-08-24 15:54:52.000000000 +0530
-@@ -2891,6 +2891,7 @@ bad_inode:
- iput(inode);
- return ERR_PTR(ret);
- }
-+EXPORT_SYMBOL(ext4_iget);
-
- static int ext4_inode_blocks_set(handle_t *handle,
- struct ext4_inode *raw_inode,
-diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ext4/namei.c
---- linux-2.6.18-128.1.6_1//fs/ext4/namei.c 2009-08-24 15:54:11.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/namei.c 2009-08-24 15:55:18.000000000 +0530
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/namei.c linux-2.6.27.21-0.1_2//fs/ext4/namei.c
+--- linux-2.6.27.21-0.1_1//fs/ext4/namei.c 2009-08-24 15:32:00.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/namei.c 2009-08-24 15:43:56.000000000 +0530
@@ -24,6 +24,7 @@
* Theodore Ts'o, 2002
*/
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/jbd2.h>
-@@ -878,8 +879,8 @@ static inline int search_dirblock(struct
+@@ -882,9 +883,9 @@ static inline int search_dirblock(struct
* The returned buffer_head has ->b_count elevated. The caller is expected
* to brelse() it when appropriate.
*/
--static struct buffer_head * ext4_find_entry (struct dentry *dentry,
+-static struct buffer_head * ext4_find_entry (struct inode *dir,
+- const struct qstr *d_name,
- struct ext4_dir_entry_2 ** res_dir)
-+struct buffer_head * ext4_find_entry (struct dentry *dentry,
++struct buffer_head * ext4_find_entry(struct inode *dir,
++ const struct qstr *d_name,
+ struct ext4_dir_entry_2 ** res_dir)
{
- struct super_block * sb;
- struct buffer_head * bh_use[NAMEI_RA_SIZE];
-@@ -986,6 +987,7 @@ cleanup_and_exit:
- brelse (bh_use[ra_ptr]);
+ struct super_block *sb;
+ struct buffer_head *bh_use[NAMEI_RA_SIZE];
+@@ -991,6 +992,7 @@ cleanup_and_exit:
+ brelse(bh_use[ra_ptr]);
return ret;
}
+EXPORT_SYMBOL(ext4_find_entry);
- static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
+ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct qstr *d_name,
struct ext4_dir_entry_2 **res_dir, int *err)
-@@ -1506,8 +1508,8 @@ static int make_indexed_dir(handle_t *ha
+@@ -1511,8 +1513,8 @@ static int make_indexed_dir(handle_t *ha
* may not sleep between calling this and putting something into
* the entry, as someone else might have used it while you slept.
*/
--static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
-- struct inode *inode)
-+int ext4_add_entry (handle_t *handle, struct dentry *dentry,
-+ struct inode *inode)
+-static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
+- struct inode *inode)
++int ext4_add_entry(handle_t *handle, struct dentry *dentry,
++ struct inode *inode)
{
struct inode *dir = dentry->d_parent->d_inode;
- unsigned long offset;
-@@ -1553,6 +1555,7 @@ static int ext4_add_entry (handle_t *han
+ struct buffer_head *bh;
+@@ -1557,6 +1559,7 @@ static int ext4_add_entry(handle_t *hand
de->rec_len = ext4_rec_len_to_disk(blocksize);
return add_dirent_to_buf(handle, dentry, inode, de, bh);
}
/*
* Returns 0 for success, or a negative error value
-@@ -1693,10 +1696,10 @@ cleanup:
+@@ -1699,10 +1702,10 @@ cleanup:
* ext4_delete_entry deletes a directory entry by merging it with the
* previous entry
*/
--static int ext4_delete_entry (handle_t *handle,
-- struct inode * dir,
-- struct ext4_dir_entry_2 * de_del,
-- struct buffer_head * bh)
-+int ext4_delete_entry (handle_t *handle,
-+ struct inode * dir,
-+ struct ext4_dir_entry_2 * de_del,
-+ struct buffer_head * bh)
+-static int ext4_delete_entry(handle_t *handle,
+- struct inode *dir,
+- struct ext4_dir_entry_2 *de_del,
+- struct buffer_head *bh)
++int ext4_delete_entry(handle_t *handle,
++ struct inode *dir,
++ struct ext4_dir_entry_2 *de_del,
++ struct buffer_head *bh)
{
- struct ext4_dir_entry_2 * de, * pde;
+ struct ext4_dir_entry_2 *de, *pde;
int i;
-@@ -1727,7 +1730,7 @@ static int ext4_delete_entry (handle_t *
+@@ -1733,7 +1736,7 @@ static int ext4_delete_entry(handle_t *h
}
return -ENOENT;
}
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
-@@ -1790,6 +1793,26 @@ static struct inode * ext4_new_inode_wan
- return ext4_new_inode(handle, dir, mode, inum);
+@@ -1796,6 +1799,26 @@ static unsigned ext4_dentry_goal(struct
+ return inum;
}
+struct inode * ext4_create_inode(handle_t *handle, struct inode * dir, int mode)
+{
+ struct inode *inode;
+
-+ inode = ext4_new_inode(handle, dir, mode, 0);
++ inode = ext4_new_inode(handle, dir, mode);
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
-@@ -1864,38 +1887,25 @@ retry:
+@@ -1872,39 +1895,31 @@ retry:
return err;
}
--static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
--{
-- handle_t *handle;
-- struct inode * inode;
+-static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+/* Initialize @inode as a subdirectory of @dir, and add the
+ * "." and ".." entries into the first directory block. */
+int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
-+ struct inode *inode)
-+ {
- struct buffer_head * dir_block;
- struct ext4_dir_entry_2 * de;
++ struct inode *inode)
+ {
+- handle_t *handle;
+- struct inode *inode;
+- struct buffer_head *dir_block;
+- struct ext4_dir_entry_2 *de;
- int err, retries = 0;
-
- if (EXT4_DIR_LINK_MAX(dir))
- return -EMLINK;
--
++ struct buffer_head * dir_block;
++ struct ext4_dir_entry_2 * de;
++ int err = 0;
+
-retry:
- handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
- EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
- 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
-- if (IS_ERR(handle))
-- return PTR_ERR(handle);
--
-- if (IS_DIRSYNC(dir))
-- handle->h_sync = 1;
--
-- inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+ if (IS_DIRSYNC(dir))
+ ext4_handle_sync(handle);
+
+- inode = ext4_new_inode_goal(handle, dir, S_IFDIR | mode,
+- ext4_dentry_goal(dir->i_sb, dentry));
- err = PTR_ERR(inode);
- if (IS_ERR(inode))
- goto out_stop;
-+ int err = 0;
-
+-
inode->i_op = &ext4_dir_inode_operations;
inode->i_fop = &ext4_dir_operations;
inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
- dir_block = ext4_bread (handle, inode, 0, 1, &err);
+ dir_block = ext4_bread(handle, inode, 0, 1, &err);
- if (!dir_block)
- goto out_clear_inode;
+ if (!dir_block) {
BUFFER_TRACE(dir_block, "get_write_access");
ext4_journal_get_write_access(handle, dir_block);
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
-@@ -1907,7 +1917,7 @@ retry:
- de = ext4_next_entry(de);
- de->inode = cpu_to_le32(dir->i_ino);
- de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
-- EXT4_DIR_REC_LEN(1));
-+ EXT4_DIR_REC_LEN(1));
- de->name_len = 2;
- strcpy (de->name, "..");
- ext4_set_de_type(dir->i_sb, de, S_IFDIR);
-@@ -1916,9 +1926,41 @@ retry:
+@@ -1925,9 +1940,43 @@ retry:
ext4_journal_dirty_metadata(handle, dir_block);
- brelse (dir_block);
+ brelse(dir_block);
ext4_mark_inode_dirty(handle, inode);
+get_out:
+ return err;
+}
+EXPORT_SYMBOL(ext4_add_dot_dotdot);
+
-+static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
++
++static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ handle_t *handle;
-+ struct inode * inode;
++ struct inode *inode;
+ int err, retries = 0;
+
+ if (EXT4_DIR_LINK_MAX(dir))
+ if (IS_DIRSYNC(dir))
+ handle->h_sync = 1;
+
-+ inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
++ inode = ext4_new_inode_goal(handle, dir, S_IFDIR | mode,
++ ext4_dentry_goal(dir->i_sb, dentry));
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto out_stop;
+ if (err)
+ goto out_stop;
+
- err = ext4_add_entry (handle, dentry, inode);
+ err = ext4_add_entry(handle, dentry, inode);
if (err) {
-out_clear_inode:
clear_nlink(inode);
ext4_mark_inode_dirty(handle, inode);
- iput (inode);
-
+ iput(inode);
/* tunables */
unsigned long s_stripe;
-- unsigned long s_mb_stream_request;
+- unsigned int s_mb_stream_request;
+ unsigned long s_mb_small_req;
+ unsigned long s_mb_large_req;
- unsigned long s_mb_max_to_scan;
- unsigned long s_mb_min_to_scan;
- unsigned long s_mb_stats;
- unsigned long s_mb_order2_reqs;
+ unsigned int s_mb_max_to_scan;
+ unsigned int s_mb_min_to_scan;
+ unsigned int s_mb_stats;
+ unsigned int s_mb_order2_reqs;
+ unsigned long *s_mb_prealloc_table;
+ unsigned long s_mb_prealloc_table_size;
- unsigned long s_mb_group_prealloc;
+ unsigned int s_mb_group_prealloc;
/* where last allocation was done - for stream allocation */
unsigned long s_mb_last_group;
Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
int ext4_mb_init(struct super_block *sb, int needs_recovery)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
-@@ -2542,15 +2562,59 @@
+@@ -2542,13 +2562,55 @@
sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN;
sbi->s_mb_min_to_scan = MB_DEFAULT_MIN_TO_SCAN;
sbi->s_mb_stats = MB_DEFAULT_STATS;
+ i = sbi->s_mb_prealloc_table_size * sizeof(unsigned long);
+ sbi->s_mb_prealloc_table = kmalloc(i, GFP_NOFS);
+ if (sbi->s_mb_prealloc_table == NULL) {
-+ clear_opt(sbi->s_mount_opt, MBALLOC);
+ kfree(sbi->s_mb_offsets);
+ kfree(sbi->s_mb_maxs);
+ return -ENOMEM;
+ i = sbi->s_mb_prealloc_table_size * sizeof(unsigned long);
+ sbi->s_mb_prealloc_table = kmalloc(i, GFP_NOFS);
+ if (sbi->s_mb_prealloc_table == NULL) {
-+ clear_opt(sbi->s_mount_opt, MBALLOC);
+ kfree(sbi->s_mb_offsets);
+ kfree(sbi->s_mb_maxs);
+ return -ENOMEM;
+ sbi->s_mb_group_prealloc = sbi->s_stripe * 4;
+ }
- i = sizeof(struct ext4_locality_group) * num_possible_cpus();
- sbi->s_locality_groups = kmalloc(i, GFP_KERNEL);
+ sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group);
if (sbi->s_locality_groups == NULL) {
- clear_opt(sbi->s_mount_opt, MBALLOC);
+ kfree(sbi->s_mb_prealloc_table);
kfree(sbi->s_mb_offsets);
kfree(sbi->s_mb_maxs);
return -ENOMEM;
-@@ -2725,10 +2789,82 @@
+@@ -2725,8 +2789,82 @@
#define EXT4_MB_MAX_TO_SCAN_NAME "max_to_scan"
#define EXT4_MB_MIN_TO_SCAN_NAME "min_to_scan"
#define EXT4_MB_ORDER2_REQ "order2_req"
+#define EXT4_MB_LARGE_REQ "large_req"
+#define EXT4_MB_PREALLOC_TABLE "prealloc_table"
#define EXT4_MB_GROUP_PREALLOC "group_prealloc"
-
++
+static int ext4_mb_prealloc_table_proc_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ prev = value;
+ num++;
+ }
-
++
+ new_table = kmalloc(num * sizeof(*new_table), GFP_KERNEL);
+ if (new_table == NULL)
+ return -ENOMEM;
#define MB_PROC_FOPS(name) \
static int ext4_mb_##name##_proc_show(struct seq_file *m, void *v) \
-@@ -2774,7 +2910,8 @@
- MB_PROC_FOPS(max_to_scan);
- MB_PROC_FOPS(min_to_scan);
- MB_PROC_FOPS(order2_reqs);
--MB_PROC_FOPS(stream_request);
-+MB_PROC_FOPS(small_req);
-+MB_PROC_FOPS(large_req);
- MB_PROC_FOPS(group_prealloc);
-
- #define MB_PROC_HANDLER(name, var) \
@@ -2795,6 +2932,7 @@
mode_t mode = S_IFREG | S_IRUGO | S_IWUSR;
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct proc_dir_entry *proc;
+ struct proc_dir_entry *proc_entry;
- char devname[64];
-
- if (proc_root_ext4 == NULL) {
-@@ -2808,15 +2946,29 @@
- MB_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, max_to_scan);
- MB_PROC_HANDLER(EXT4_MB_MIN_TO_SCAN_NAME, min_to_scan);
- MB_PROC_HANDLER(EXT4_MB_ORDER2_REQ, order2_reqs);
-- MB_PROC_HANDLER(EXT4_MB_STREAM_REQ, stream_request);
-+ MB_PROC_HANDLER(EXT4_MB_SMALL_REQ, small_req);
-+ MB_PROC_HANDLER(EXT4_MB_LARGE_REQ, large_req);
- MB_PROC_HANDLER(EXT4_MB_GROUP_PREALLOC, group_prealloc);
+ if (sbi->s_proc == NULL)
+ return -EINVAL;
+@@ -2808,13 +2946,28 @@
+ EXT4_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, mb_max_to_scan);
+ EXT4_PROC_HANDLER(EXT4_MB_MIN_TO_SCAN_NAME, mb_min_to_scan);
+ EXT4_PROC_HANDLER(EXT4_MB_ORDER2_REQ, mb_order2_reqs);
+- EXT4_PROC_HANDLER(EXT4_MB_STREAM_REQ, mb_stream_request);
++ EXT4_PROC_HANDLER(EXT4_MB_SMALL_REQ, mb_small_req);
++ EXT4_PROC_HANDLER(EXT4_MB_LARGE_REQ, mb_large_req);
+ EXT4_PROC_HANDLER(EXT4_MB_GROUP_PREALLOC, mb_group_prealloc);
++
+ proc_entry = create_proc_entry(EXT4_MB_PREALLOC_TABLE, S_IFREG |
-+ S_IRUGO | S_IWUSR, sbi->s_mb_proc);
++ S_IRUGO | S_IWUSR, sbi->s_proc);
+ if (proc_entry == NULL) {
+ printk(KERN_ERR "EXT4-fs: unable to create %s\n",
+ EXT4_MB_PREALLOC_TABLE);
return 0;
err_out:
- printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname);
- remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
-- remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MB_PREALLOC_TABLE, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MB_LARGE_REQ, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MB_SMALL_REQ, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
+ remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_proc);
+- remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_proc);
++ remove_proc_entry(EXT4_MB_PREALLOC_TABLE, sbi->s_proc);
++ remove_proc_entry(EXT4_MB_LARGE_REQ, sbi->s_proc);
++ remove_proc_entry(EXT4_MB_SMALL_REQ, sbi->s_proc);
+ remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_proc);
+ remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_proc);
+ remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc);
@@ -2838,7 +2990,9 @@
- bdevname(sb->s_bdev, devname);
- remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
-- remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MB_PREALLOC_TABLE, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MB_LARGE_REQ, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MB_SMALL_REQ, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
+
+ remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_proc);
+- remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_proc);
++ remove_proc_entry(EXT4_MB_PREALLOC_TABLE, sbi->s_proc);
++ remove_proc_entry(EXT4_MB_LARGE_REQ, sbi->s_proc);
++ remove_proc_entry(EXT4_MB_SMALL_REQ, sbi->s_proc);
+ remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_proc);
+ remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_proc);
+ remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc);
@@ -3032,11 +3186,12 @@
ext4_mb_normalize_request(struct ext4_allocation_context *ac,
struct ext4_allocation_request *ar)
@@ -3185,7 +3326,6 @@
}
BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
- start > ac->ac_o_ex.fe_logical);
-- BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
+ start > ac->ac_o_ex.fe_logical);
+- BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
/* now prepare goal request */
BUG_ON(ac->ac_lg != NULL);
/*
* locality group prealloc space are per cpu. The reason for having
+Index: linux-2.6.27.21-0.1/fs/ext4/inode.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/inode.c 2009-05-28 11:12:42.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/inode.c 2009-05-28 11:16:48.000000000 +0530
+@@ -2442,14 +2442,14 @@
+ return -EROFS;
+
+ /*
+- * Make sure nr_to_write is >= sbi->s_mb_stream_request
++ * Make sure nr_to_write is >= sbi->s_mb_small_req
+ * This make sure small files blocks are allocated in
+ * single attempt. This ensure that small files
+ * get less fragmented.
+ */
+- if (wbc->nr_to_write < sbi->s_mb_stream_request) {
+- nr_to_writebump = sbi->s_mb_stream_request - wbc->nr_to_write;
+- wbc->nr_to_write = sbi->s_mb_stream_request;
++ if (wbc->nr_to_write < sbi->s_mb_small_req) {
++ nr_to_writebump = sbi->s_mb_small_req - wbc->nr_to_write;
++ wbc->nr_to_write = sbi->s_mb_small_req;
+ }
+ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+ range_whole = 1;
@@ -1057,7 +1057,6 @@ unsigned long ext4_count_free_inodes (st
if (!gdp)
continue;
- desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
+ desc_count += ext4_free_inodes_count(sb, gdp);
- cond_resched();
}
return desc_count;
--- linux-2.6.18-128.1.6.orig/fs/ext4/super.c 2009-07-24 01:33:54.000000000 -0400
+++ linux-2.6.18-128.1.6/fs/ext4/super.c 2009-07-24 01:35:28.000000000 -0400
@@ -3461,6 +3461,8 @@ static int __init init_ext4_fs(void)
- err = register_filesystem(&ext4dev_fs_type);
- if (err)
goto out;
+ }
+ #endif
+
+ printk(KERN_INFO "ldiskfs created from ""ext""4-2.6-rhel5\n");
return 0;
out:
destroy_inodecache();
+--- /dev/null 2009-09-21 17:11:24.467285554 +0800
++++ linux-2.6.27.21-0.1/fs/ext4/fiemap.h
+@@ -0,0 +1,2 @@
++
++#include_next <fiemap.h>
-Index: linux-2.6.18.i386/fs/ext4/ialloc.c
+Index: linux-stage/fs/ext4/ialloc.c
===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/ialloc.c
-+++ linux-2.6.18.i386/fs/ext4/ialloc.c
-@@ -576,7 +576,8 @@ static int find_group_other(struct super
+--- linux-stage.orig/fs/ext4/ialloc.c
++++ linux-stage/fs/ext4/ialloc.c
+@@ -675,7 +675,8 @@ err_ret:
* For other inodes, search forward from the parent directory's block
* group to find a free inode.
*/
--struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
-+struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode,
-+ unsigned long goal)
+-struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
++struct inode *ext4_new_inode_goal(handle_t *handle, struct inode *dir,
++ int mode, unsigned goal)
{
struct super_block *sb;
- struct buffer_head *bitmap_bh = NULL;
-@@ -607,6 +608,43 @@ struct inode *ext4_new_inode(handle_t *h
+ struct buffer_head *inode_bitmap_bh = NULL;
+@@ -706,6 +707,14 @@ struct inode *ext4_new_inode(handle_t *h
sbi = EXT4_SB(sb);
es = sbi->s_es;
-+ if (goal) {
++ if (goal && goal <= le32_to_cpu(es->s_inodes_count)) {
+ group = (goal - 1) / EXT4_INODES_PER_GROUP(sb);
+ ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb);
-+ err = -EIO;
+
-+ gdp = ext4_get_group_desc(sb, group, &bh2);
-+ if (!gdp)
-+ goto fail;
-+
-+ bitmap_bh = ext4_read_inode_bitmap(sb, group);
-+ if (!bitmap_bh)
-+ goto fail;
-+
-+ BUFFER_TRACE(bh, "get_write_access");
-+ err = ext4_journal_get_write_access(handle, bitmap_bh);
-+ if (err)
-+ goto fail;
-+
-+ if (ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
-+ ino, bitmap_bh->b_data)) {
-+ printk(KERN_ERR "goal inode %lu unavailable\n", goal);
-+ /* Oh well, we tried. */
-+ goto continue_allocation;
-+ }
-+
-+ BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
-+ err = ext4_journal_dirty_metadata(handle, bitmap_bh);
-+ if (err)
-+ goto fail;
-+
-+ /* We've shortcircuited the allocation system successfully,
-+ * now finish filling in the inode.
-+ */
-+ goto got;
++ ret2 = 0;
++ goto got_group;
+ }
+
-+continue_allocation:
if (sbi->s_log_groups_per_flex) {
ret2 = find_group_flex(sb, dir, &group);
goto got_group;
-Index: linux-2.6.18.i386/fs/ext4/namei.c
-===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/namei.c
-+++ linux-2.6.18.i386/fs/ext4/namei.c
-@@ -104,6 +104,7 @@ struct dx_entry
- __le32 block;
- };
+@@ -724,7 +733,7 @@ got_group:
+ if (ret2 == -1)
+ goto out;
-+
- /*
- * dx_root_info is laid out so that if it should somehow get overlaid by a
- * dirent the two low bits of the hash version will be zero. Therefore, the
-@@ -149,6 +150,14 @@ struct dx_map_entry
+- for (i = 0; i < sbi->s_groups_count; i++) {
++ for (i = 0; i < sbi->s_groups_count; i++, ino = 0) {
+ err = -EIO;
+
+ gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
+@@ -736,8 +745,6 @@ got_group:
+ if (!inode_bitmap_bh)
+ goto fail;
+
+- ino = 0;
+-
+ repeat_in_this_group:
+ ino = ext4_find_next_zero_bit((unsigned long *)
+ inode_bitmap_bh->b_data,
+Index: linux-stage/fs/ext4/namei.c
+===================================================================
+--- linux-stage.orig/fs/ext4/namei.c
++++ linux-stage/fs/ext4/namei.c
+@@ -149,6 +149,17 @@ struct dx_map_entry
u16 size;
};
++/*
++ * dentry_param used by ext4_new_inode_wantedi()
++ */
+#define LVFS_DENTRY_PARAM_MAGIC 20070216UL
+struct lvfs_dentry_params
+{
-+ unsigned long p_inum;
-+ void *p_ptr;
-+ u32 magic;
++ unsigned long ldp_inum;
++ unsigned long ldp_flags;
++ u32 ldp_magic;
+};
+
static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
- static inline unsigned dx_get_hash (struct dx_entry *entry);
-@@ -1708,6 +1717,20 @@ static int ext4_add_nondir(handle_t *han
+ static inline unsigned dx_get_hash(struct dx_entry *entry);
+@@ -1716,6 +1727,19 @@ static int ext4_add_nondir(handle_t *han
return err;
}
-+static struct inode * ext4_new_inode_wantedi(handle_t *handle, struct inode *dir,
-+ int mode, struct dentry *dentry)
++static unsigned ext4_dentry_goal(struct super_block *sb, struct dentry *dentry)
+{
-+ unsigned long inum = 0;
++ unsigned inum = EXT4_SB(sb)->s_inode_goal;
+
+ if (dentry->d_fsdata != NULL) {
+ struct lvfs_dentry_params *param = dentry->d_fsdata;
+
-+ if (param->magic == LVFS_DENTRY_PARAM_MAGIC)
-+ inum = param->p_inum;
++ if (param->ldp_magic == LVFS_DENTRY_PARAM_MAGIC)
++ inum = param->ldp_inum;
+ }
-+ return ext4_new_inode(handle, dir, mode, inum);
++ return inum;
+}
+
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
-@@ -1733,7 +1756,7 @@ retry:
+@@ -1741,7 +1766,8 @@ retry:
if (IS_DIRSYNC(dir))
handle->h_sync = 1;
- inode = ext4_new_inode (handle, dir, mode);
-+ inode = ext4_new_inode_wantedi (handle, dir, mode, dentry);
++ inode = ext4_new_inode_goal(handle, dir, mode,
++ ext4_dentry_goal(dir->i_sb, dentry));
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
inode->i_op = &ext4_file_inode_operations;
-@@ -1767,7 +1790,7 @@ retry:
+@@ -1775,7 +1800,8 @@ retry:
if (IS_DIRSYNC(dir))
handle->h_sync = 1;
-- inode = ext4_new_inode (handle, dir, mode);
-+ inode = ext4_new_inode_wantedi (handle, dir, mode, dentry);
+- inode = ext4_new_inode(handle, dir, mode);
++ inode = ext4_new_inode_goal(handle, dir, mode,
++ ext4_dentry_goal(dir->i_sb, dentry));
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, inode->i_mode, rdev);
-@@ -1803,7 +1826,7 @@ retry:
+@@ -1811,7 +1836,8 @@ retry:
if (IS_DIRSYNC(dir))
handle->h_sync = 1;
-- inode = ext4_new_inode (handle, dir, S_IFDIR | mode);
-+ inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+- inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
++ inode = ext4_new_inode_goal(handle, dir, S_IFDIR | mode,
++ ext4_dentry_goal(dir->i_sb, dentry));
err = PTR_ERR(inode);
if (IS_ERR(inode))
goto out_stop;
-@@ -2203,7 +2226,7 @@ retry:
+@@ -2211,7 +2236,8 @@ retry:
if (IS_DIRSYNC(dir))
handle->h_sync = 1;
-- inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
-+ inode = ext4_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
+- inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
++ inode = ext4_new_inode_goal(handle, dir, S_IFLNK|S_IRWXUGO,
++ ext4_dentry_goal(dir->i_sb, dentry));
err = PTR_ERR(inode);
if (IS_ERR(inode))
goto out_stop;
-Index: linux-2.6.18.i386/fs/ext4/ext4.h
+Index: linux-stage/fs/ext4/ext4.h
===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/ext4.h
-+++ linux-2.6.18.i386/fs/ext4/ext4.h
-@@ -1013,7 +1013,8 @@ extern int ext4fs_dirhash(const char *na
+--- linux-stage.orig/fs/ext4/ext4.h
++++ linux-stage/fs/ext4/ext4.h
+@@ -1032,7 +1032,14 @@ extern int ext4fs_dirhash(const char *na
dx_hash_info *hinfo);
/* ialloc.c */
--extern struct inode * ext4_new_inode (handle_t *, struct inode *, int);
-+extern struct inode * ext4_new_inode (handle_t *, struct inode *, int,
-+ unsigned long);
- extern void ext4_free_inode (handle_t *, struct inode *);
- extern struct inode * ext4_orphan_get (struct super_block *, unsigned long);
- extern unsigned long ext4_count_free_inodes (struct super_block *);
-Index: linux-2.6.18.i386/fs/ext4/migrate.c
+-extern struct inode * ext4_new_inode(handle_t *, struct inode *, int);
++extern struct inode *ext4_new_inode_goal(handle_t *handle, struct inode *dir,
++ int mode, unsigned goal);
++static inline struct inode *ext4_new_inode(handle_t *handle, struct inode *dir,
++ int mode)
++{
++ return ext4_new_inode_goal(handle, dir, mode,
++ EXT4_SB(dir->i_sb)->s_inode_goal);
++}
+ extern void ext4_free_inode(handle_t *, struct inode *);
+ extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
+ extern unsigned long ext4_count_free_inodes(struct super_block *);
+Index: linux-stage/fs/ext4/super.c
===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/migrate.c
-+++ linux-2.6.18.i386/fs/ext4/migrate.c
-@@ -485,7 +485,7 @@ int ext4_ext_migrate(struct inode *inode
+--- linux-stage.orig/fs/ext4/super.c
++++ linux-stage/fs/ext4/super.c
+@@ -560,6 +560,7 @@ static void ext4_put_super(struct super_
+ }
+ if (sbi->s_proc) {
+ remove_proc_entry("inode_readahead_blks", sbi->s_proc);
++ remove_proc_entry("inode_goal", sbi->s_proc);
+ remove_proc_entry(sb->s_id, ext4_proc_root);
}
- tmp_inode = ext4_new_inode(handle,
- inode->i_sb->s_root->d_inode,
-- S_IFREG);
-+ S_IFREG, 0);
- if (IS_ERR(tmp_inode)) {
- retval = -ENOMEM;
- ext4_journal_stop(handle);
+
+@@ -2274,6 +2275,11 @@ static int ext4_fill_super(struct super_
+ p->proc_fops = &ext4_ui_proc_fops;
+ p->data = &sbi->s_inode_readahead_blks;
+ }
++ p = create_proc_entry("inode_goal", 0644, sbi->s_proc);
++ if (p) {
++ p->proc_fops = &ext4_ui_proc_fops,
++ p->data = &sbi->s_inode_goal;
++ }
+ }
+ #endif
+
+@@ -2553,6 +2558,7 @@ failed_mount2:
+ failed_mount:
+ if (sbi->s_proc) {
+ remove_proc_entry("inode_readahead_blks", sbi->s_proc);
++ remove_proc_entry("inode_goal", sbi->s_proc);
+ remove_proc_entry(sb->s_id, ext4_proc_root);
+ }
+ #ifdef CONFIG_QUOTA
+Index: linux-stage/fs/ext4/ext4_sb.h
+===================================================================
+--- linux-stage.orig/fs/ext4/ext4_sb.h
++++ linux-stage/fs/ext4/ext4_sb.h
+@@ -53,6 +53,7 @@ struct ext4_sb_info {
+ int s_inode_size;
+ int s_first_ino;
+ unsigned int s_inode_readahead_blks;
++ unsigned int s_inode_goal;
+ spinlock_t s_next_gen_lock;
+ u32 s_next_generation;
+ u32 s_hash_seed[4];
+
struct ext4_dir_entry_2
** res_dir);
extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
-- struct inode *inode);
+- struct inode *inode);
+ struct inode *inode, const void *, const void *);
extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
+++ b/fs/ext4/namei.c
@@ -177,7 +177,8 @@ static unsigned dx_get_count (struct dx_
static unsigned dx_get_limit (struct dx_entry *entries);
- static void dx_set_count (struct dx_entry *entries, unsigned value);
- static void dx_set_limit (struct dx_entry *entries, unsigned value);
--static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
+ static void dx_set_count(struct dx_entry *entries, unsigned value);
+ static void dx_set_limit(struct dx_entry *entries, unsigned value);
+-static unsigned dx_root_limit(struct inode *dir, unsigned infosize);
+static inline unsigned dx_root_limit(__u32 blocksize,
+ struct ext4_dir_entry_2 *dot_de, unsigned infosize);
- static unsigned dx_node_limit (struct inode *dir);
+ static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(struct dentry *dentry,
struct inode *dir,
@@ -218,11 +219,12 @@ ext4_next_entry(struct ext4_dir_entry_2
((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
}
--static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
+-static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize)
+static inline unsigned dx_root_limit(__u32 blocksize,
+ struct ext4_dir_entry_2 *dot_de, unsigned infosize)
{
return entry_space / sizeof(struct dx_entry);
}
- static inline unsigned dx_node_limit (struct inode *dir)
+ static inline unsigned dx_node_limit(struct inode *dir)
{
- unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);
+ unsigned entry_space = dir->i_sb->s_blocksize - __EXT4_DIR_REC_LEN(0);
@@ -1399,6 +1415,12 @@ static int add_dirent_to_buf(handle_t *h
de->inode = 0;
de->name_len = namelen;
- memcpy (de->name, name, namelen);
+ memcpy(de->name, name, namelen);
+ if (data) {
+ de->name[namelen] = 0;
+ memcpy(&de->name[namelen + 1], data, *(char *) data);
/* Initialize @inode as a subdirectory of @dir, and add the
* "." and ".." entries into the first directory block. */
int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
-- struct inode *inode)
+- struct inode *inode)
+ struct inode *inode,
+ const void *data1, const void *data2)
- {
+ {
struct buffer_head * dir_block;
- struct ext4_dir_entry_2 * de;
+ struct ext4_dir_entry_2 * de;
- int err = 0;
+ int err = 0, dot_reclen;
- inode->i_op = &ext4_dir_inode_operations;
- inode->i_fop = &ext4_dir_operations;
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
@@ -1993,16 +2029,34 @@ int ext4_add_dot_dotdot(handle_t *handle
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
de->inode = cpu_to_le32(inode->i_ino);
de->name_len = 1;
- de->rec_len = ext4_rec_len_to_disk(EXT4_DIR_REC_LEN(de->name_len));
- strcpy (de->name, ".");
+ strcpy(de->name, ".");
ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+ /* get packed fid data*/
+ data1 = ext4_dentry_get_data(dir->i_sb,
de = ext4_next_entry(de);
de->inode = cpu_to_le32(dir->i_ino);
de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
-- EXT4_DIR_REC_LEN(1));
+- EXT4_DIR_REC_LEN(1));
+ dot_reclen);
de->name_len = 2;
- strcpy (de->name, "..");
+ strcpy(de->name, "..");
ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+ data2 = ext4_dentry_get_data(dir->i_sb,
+ (struct ext4_dentry_param *) data2);
sb = inode->i_sb;
- if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
+ if (inode->i_size < __EXT4_DIR_REC_LEN(1) + __EXT4_DIR_REC_LEN(2) ||
- !(bh = ext4_bread (NULL, inode, 0, 0, &err))) {
+ !(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
if (err)
ext4_error(inode->i_sb, __func__,
/*
@@ -2764,6 +2765,8 @@ struct inode *ext4_iget(struct super_blo
+ ei->i_acl = EXT4_ACL_NOT_CACHED;
ei->i_default_acl = EXT4_ACL_NOT_CACHED;
#endif
- ei->i_block_alloc_info = NULL;
+ if (ext4_iopen_get_inode(inode))
+ return inode;
===================================================================
--- linux-2.6.18-128.1.6.orig/fs/ext4/super.c
+++ linux-2.6.18-128.1.6/fs/ext4/super.c
-@@ -888,6 +888,7 @@ enum {
- Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
- Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
- Opt_mballoc, Opt_nomballoc, Opt_stripe,
+@@ -888,7 +888,8 @@ enum {
+
+ Opt_usrquota, Opt_grpquota, Opt_i_version,
+ Opt_stripe, Opt_delalloc, Opt_nodelalloc,
+- Opt_inode_readahead_blks, Opt_journal_ioprio
++ Opt_inode_readahead_blks, Opt_journal_ioprio,
+ Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
};
+ if (ext4_check_for_iopen(dir, dentry))
+ return NULL;
+
- bh = ext4_find_entry(dentry, &de);
+ bh = ext4_find_entry(dir, &dentry->d_name, &de);
inode = NULL;
if (bh) {
@@ -1062,7 +1066,8 @@ static struct dentry *ext4_lookup(struct
ext4_mark_inode_dirty(handle, inode);
- d_instantiate(dentry, inode);
+ iopen_d_instantiate(dentry, inode);
+ unlock_new_inode(inode);
return 0;
}
- drop_nlink(inode);
@@ -1868,7 +1873,7 @@ out_clear_inode:
ext4_inc_count(handle, dir);
ext4_update_dx_flag(dir);
ext4_mark_inode_dirty(handle, dir);
- d_instantiate(dentry, inode);
+ iopen_d_instantiate(dentry, inode);
+ unlock_new_inode(inode);
out_stop:
ext4_journal_stop(handle);
- if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
@@ -2134,10 +2139,6 @@ static int ext4_rmdir (struct inode * di
inode->i_nlink);
inode->i_version++;
+ return err;
+}
+
- static int ext4_link (struct dentry * old_dentry,
- struct inode * dir, struct dentry *dentry)
+ static int ext4_link(struct dentry *old_dentry,
+ struct inode *dir, struct dentry *dentry)
{
-@@ -2293,7 +2311,8 @@ retry:
+@@ -2293,14 +2311,8 @@ retry:
ext4_inc_count(handle, inode);
atomic_inc(&inode->i_count);
-- err = ext4_add_nondir(handle, dentry, inode);
+- err = ext4_add_entry(handle, dentry, inode);
+- if (!err) {
+- ext4_mark_inode_dirty(handle, inode);
+- d_instantiate(dentry, inode);
+- } else {
+- drop_nlink(inode);
+- iput(inode);
+- }
+ err = ext4_add_link(handle, dentry, inode);
+ ext4_orphan_del(handle, inode);
ext4_journal_stop(handle);
obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o
--ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-+ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+-ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
++ext4-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 extents.o \
ext4_jbd2.o migrate.o mballoc.o
===================================================================
--- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
+++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
-@@ -18,6 +18,7 @@
-
- #include <linux/types.h>
- #include <linux/blkdev.h>
-+#include <linux/jbd2.h>
- #include "ext4_i.h"
-
- #define EXT4_SUPER_MAGIC 0xEF53
@@ -537,6 +538,8 @@ do { \
#define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
#define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */
- #define EXT4_MOUNT_MBALLOC 0x4000000 /* Buddy allocation support */
-+#define EXT4_MOUNT_IOPEN 0x8000000 /* Allow access via iopen */
-+#define EXT4_MOUNT_IOPEN_NOPRIV 0x10000000 /* Make iopen world-readable */
+ #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
+ #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
++#define EXT4_MOUNT_IOPEN 0x20000000 /* Allow access via iopen */
++#define EXT4_MOUNT_IOPEN_NOPRIV 0x40000000 /* Make iopen world-readable */
+
/* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
#ifndef _LINUX_EXT2_FS_H
- #define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt
ext4-filterdata-rhel5.patch
ext4-inode-version-rhel5.patch
ext4-mmp-rhel5.patch
-ext4-fiemap-2.6-rhel5.patch
ext4-lookup-dotdot-rhel5.patch
ext4-max-dir-size-rhel5.patch
ext4-print-inum-in-htree-warning-rhel5.patch
ext4-xattr-no-update-ctime-rhel5.patch
ext4-prealloc-rhel5.patch
ext4-mballoc-extra-checks-rhel5.patch
-ext4-mballoc-handle-dev-paths-rhel5.patch
ext4-big-endian-check-2.6-rhel5.patch
ext4-alloc-policy-2.6-rhel5.patch
ext4-misc-rhel5.patch
ext4-convert-group-lock-rhel5.patch
ext4-force_over_8tb-rhel5.patch
-ext4_ext_search_right-fix.patch
-ext4-pa_lock-typo.patch
ext4-pdir-fix.patch
ext4-osd-iop-common.patch
ext4-osd-iam-exports.patch
ext4-dynlocks-common.patch
ext4-dynlocks-2.6-rhel5.patch
ext4-hash-indexed-dir-dotdot-update.patch
+ext4-ext_generation-sles11.patch
ext4-kill-dx_root.patch
ext4_data_in_dirent.patch
-ext4-add-ext4_itable_unused_count.patch
+ext4-extents-mount-option-rhel5.patch
ext3-inode-version-2.6.18-vanilla.patch
ext3-ea-expand-lose-block.patch
ext3-mmp-2.6.18-vanilla.patch
-ext3-fiemap-2.6-rhel5.patch
ext3-statfs-2.6-rhel5.patch
ext3-lookup-dotdot-2.6.9.patch
ext3-max-dir-size.patch