rpms/kernel/devel kernel.spec, 1.439, 1.440 linux-2.6-ext4-stable-queue.patch, 1.2, 1.3 linux-2.6-ext4-linus-git.patch, 1.1, NONE

Eric Sandeen (sandeen) fedora-extras-commits at redhat.com
Wed Feb 20 21:18:04 UTC 2008


Author: sandeen

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv5628

Modified Files:
	kernel.spec linux-2.6-ext4-stable-queue.patch 
Removed Files:
	linux-2.6-ext4-linus-git.patch 
Log Message:
* Wed Feb 20 2008 Eric Sandeen <sandeen at redhat.com>
- More ext4 updates/fixes from the "stable" ext4 patchqueue



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.439
retrieving revision 1.440
diff -u -r1.439 -r1.440
--- kernel.spec	19 Feb 2008 16:20:31 -0000	1.439
+++ kernel.spec	20 Feb 2008 21:17:17 -0000	1.440
@@ -630,8 +630,7 @@
 Patch2021: linux-2.6-netdev-smc91c92_cs-fix-station-addr.patch
 
 # ext4 patches
-Patch2100: linux-2.6-ext4-linus-git.patch
-Patch2101: linux-2.6-ext4-stable-queue.patch
+Patch2100: linux-2.6-ext4-stable-queue.patch
 
 # linux1394 git patches
 Patch2200: linux-2.6-firewire-git-update.patch
@@ -1134,8 +1133,6 @@
 ApplyPatch nouveau-drm.patch
 ApplyPatch linux-2.6-ppc32-ucmpdi2.patch
 
-# ext4dev from Linus' upstream git tree, slated for 2.6.25
-#ApplyPatch linux-2.6-ext4-linus-git.patch
 # ext4dev stable patch queue, slated for 2.6.25
 ApplyPatch linux-2.6-ext4-stable-queue.patch
 
@@ -1733,6 +1730,9 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL} -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.conf %{with_xen} xen
 
 %changelog
+* Wed Feb 20 2008 Eric Sandeen <sandeen at redhat.com>
+- More ext4 updates/fixes from the "stable" ext4 patchqueue
+
 * Tue Feb 19 2008 Kyle McMartin <kmcmartin at redhat.com>
 - Linux 2.6.25-rc2-git2
 

linux-2.6-ext4-stable-queue.patch:

Index: linux-2.6-ext4-stable-queue.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-ext4-stable-queue.patch,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- linux-2.6-ext4-stable-queue.patch	12 Feb 2008 06:18:04 -0000	1.2
+++ linux-2.6-ext4-stable-queue.patch	20 Feb 2008 21:17:17 -0000	1.3
@@ -1,67 +1,491 @@
-mballoc.c is a whole lot of static functions, which gcc seems to
-really like to inline.
-
-With the changes below, on x86, I can at least get from:
-
-432 ext4_mb_new_blocks
-240 ext4_mb_free_blocks
-208 ext4_mb_discard_group_preallocations
-188 ext4_mb_seq_groups_show
-164 ext4_mb_init_cache
-152 ext4_mb_release_inode_pa
-136 ext4_mb_seq_history_show
-...
-
-to
-
-220 ext4_mb_free_blocks
-188 ext4_mb_seq_groups_show
-176 ext4_mb_regular_allocator
-164 ext4_mb_init_cache
-156 ext4_mb_new_blocks
-152 ext4_mb_release_inode_pa
-136 ext4_mb_seq_history_show
-124 ext4_mb_release_group_pa
-...
-
-which still has some big functions in there, but not 432 bytes!
-
-I wonder if a zone would make sense for struct ext4_allocation_context,
-it's 108 bytes by itself.
-
-I haven't honestly done any investigation of any performance
-impact of the noinlines; FWIW xfs just took control of inlining,
-and marked almost every non-trivial function as noinline, (although
-the xfs situation was a little more dire) and I don't think they had
-any noticeable performance impact.
-
-Signed-off-by: Eric Sandeen <sandeen at redhat.com>
-
----
-
-Index: linux-2.6.24-rc6-mm1/fs/ext4/mballoc.c
-===================================================================
---- linux-2.6.24-rc6-mm1.orig/fs/ext4/mballoc.c
-+++ linux-2.6.24-rc6-mm1/fs/ext4/mballoc.c
-@@ -1146,7 +1146,7 @@ out:
+Index: linux-2.6.24.noarch/fs/ext4/dir.c
+===================================================================
+--- linux-2.6.24.noarch.orig/fs/ext4/dir.c
++++ linux-2.6.24.noarch/fs/ext4/dir.c
+@@ -46,7 +46,7 @@ const struct file_operations ext4_dir_op
+ #ifdef CONFIG_COMPAT
+ 	.compat_ioctl	= ext4_compat_ioctl,
+ #endif
+-	.fsync		= ext4_sync_file,	/* BKL held */
++	.fsync		= ext4_sync_file,
+ 	.release	= ext4_release_dir,
+ };
+ 
+Index: linux-2.6.24.noarch/fs/ext4/inode.c
+===================================================================
+--- linux-2.6.24.noarch.orig/fs/ext4/inode.c
++++ linux-2.6.24.noarch/fs/ext4/inode.c
+@@ -403,6 +403,7 @@ static ext4_fsblk_t ext4_find_near(struc
+ 	__le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data;
+ 	__le32 *p;
+ 	ext4_fsblk_t bg_start;
++	ext4_fsblk_t last_block;
+ 	ext4_grpblk_t colour;
+ 
+ 	/* Try to find previous block */
+@@ -420,8 +421,13 @@ static ext4_fsblk_t ext4_find_near(struc
+ 	 * into the same cylinder group then.
+ 	 */
+ 	bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group);
+-	colour = (current->pid % 16) *
++	last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1;
++
++	if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block)
++		colour = (current->pid % 16) *
+ 			(EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
++	else
++		colour = (current->pid % 16) * ((last_block - bg_start) / 16);
+ 	return bg_start + colour;
+ }
+ 
+@@ -768,7 +774,6 @@ err_out:
+  *
+  * `handle' can be NULL if create == 0.
+  *
+- * The BKL may not be held on entry here.  Be sure to take it early.
+  * return > 0, # of blocks mapped or allocated.
+  * return = 0, if plain lookup failed.
+  * return < 0, error case.
+@@ -903,11 +908,34 @@ out:
+  */
+ #define DIO_CREDITS 25
+ 
++
++/*
++ * ext4 get_block() wrapper function
++ * It first do a look up, returns if the blocks already mapped. Otherwise
++ * it takes the write sem and do block allocation
++ *
++ * If file type is extents based, call with ext4_ext_get_blocks()
++ * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping
++ * based files
++ *
++ * return > 0, number of of blocks already mapped/allocated
++ *          if create==0 and these are pre-allocated blocks
++ *          	 buffer head is unmapped
++ *          otherwise blocks are mapped
++ *
++ * return = 0, if plain look up failed (blocks have not been allocated)
++ *          buffer head is unmapped
++ *
++ * return < 0, error case.
++ */
+ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
+ 			unsigned long max_blocks, struct buffer_head *bh,
+ 			int create, int extend_disksize)
+ {
+ 	int retval;
++
++	clear_buffer_mapped(bh);
++
+ 	/*
+ 	 * Try to see if we can get  the block without requesting
+ 	 * for new file system block.
+@@ -921,12 +949,27 @@ int ext4_get_blocks_wrap(handle_t *handl
+ 				inode, block, max_blocks, bh, 0, 0);
+ 	}
+ 	up_read((&EXT4_I(inode)->i_data_sem));
+-	if (!create || (retval > 0))
++
++	/* If it is only a block(s) look up */
++	if (!create)
++		return retval;
++
++	/*
++	 * Returns if the blocks have already allocated
++	 *
++	 * Note that if blocks have been preallocated
++	 * ext4_ext_get_block() returns with buffer head unmapped.
++	 * Write to a preallocated space needs to split
++	 * the preallocated extents, thus needs to update
++	 * i_data
++	 */
++	if (retval > 0 && buffer_mapped(bh))
+ 		return retval;
+ 
+ 	/*
+-	 * We need to allocate new blocks which will result
+-	 * in i_data update
++	 * New blocks and preallocation handling will possiblely result
++	 * in i_data update, take the write sem, and call get_blocks()
++	 * with create = 1
+ 	 */
+ 	down_write((&EXT4_I(inode)->i_data_sem));
+ 	/*
+@@ -3461,3 +3504,9 @@ int ext4_change_inode_journal_flag(struc
+ 
+ 	return err;
+ }
++
++int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page)
++{
++	return block_page_mkwrite(vma, page, ext4_get_block);
++}
++
+Index: linux-2.6.24.noarch/fs/ext4/extents.c
+===================================================================
+--- linux-2.6.24.noarch.orig/fs/ext4/extents.c
++++ linux-2.6.24.noarch/fs/ext4/extents.c
+@@ -148,6 +148,7 @@ static ext4_fsblk_t ext4_ext_find_goal(s
+ {
+ 	struct ext4_inode_info *ei = EXT4_I(inode);
+ 	ext4_fsblk_t bg_start;
++	ext4_fsblk_t last_block;
+ 	ext4_grpblk_t colour;
+ 	int depth;
+ 
+@@ -169,8 +170,13 @@ static ext4_fsblk_t ext4_ext_find_goal(s
+ 	/* OK. use inode's group */
+ 	bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) +
+ 		le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block);
+-	colour = (current->pid % 16) *
++	last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1;
++
++	if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block)
++		colour = (current->pid % 16) *
+ 			(EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
++	else
++		colour = (current->pid % 16) * ((last_block - bg_start) / 16);
+ 	return bg_start + colour + block;
+ }
+ 
+@@ -349,7 +355,7 @@ static void ext4_ext_show_leaf(struct in
+ #define ext4_ext_show_leaf(inode,path)
+ #endif
+ 
+-static void ext4_ext_drop_refs(struct ext4_ext_path *path)
++void ext4_ext_drop_refs(struct ext4_ext_path *path)
+ {
+ 	int depth = path->p_depth;
+ 	int i;
+@@ -2168,6 +2174,10 @@ static int ext4_ext_convert_to_initializ
+ 	newblock = iblock - ee_block + ext_pblock(ex);
+ 	ex2 = ex;
+ 
++	err = ext4_ext_get_access(handle, inode, path + depth);
++	if (err)
++		goto out;
++
+ 	/* ex1: ee_block to iblock - 1 : uninitialized */
+ 	if (iblock > ee_block) {
+ 		ex1 = ex;
+@@ -2200,16 +2210,20 @@ static int ext4_ext_convert_to_initializ
+ 		newdepth = ext_depth(inode);
+ 		if (newdepth != depth) {
+ 			depth = newdepth;
+-			path = ext4_ext_find_extent(inode, iblock, NULL);
++			ext4_ext_drop_refs(path);
++			path = ext4_ext_find_extent(inode, iblock, path);
+ 			if (IS_ERR(path)) {
+ 				err = PTR_ERR(path);
+-				path = NULL;
+ 				goto out;
+ 			}
+ 			eh = path[depth].p_hdr;
+ 			ex = path[depth].p_ext;
+ 			if (ex2 != &newex)
+ 				ex2 = ex;
++
++			err = ext4_ext_get_access(handle, inode, path + depth);
++			if (err)
++				goto out;
+ 		}
+ 		allocated = max_blocks;
+ 	}
+@@ -2230,9 +2244,6 @@ static int ext4_ext_convert_to_initializ
+ 	ex2->ee_len = cpu_to_le16(allocated);
+ 	if (ex2 != ex)
+ 		goto insert;
+-	err = ext4_ext_get_access(handle, inode, path + depth);
+-	if (err)
+-		goto out;
+ 	/*
+ 	 * New (initialized) extent starts from the first block
+ 	 * in the current extent. i.e., ex2 == ex
+@@ -2276,9 +2287,22 @@ out:
+ }
+ 
+ /*
++ * Block allocation/map/preallocation routine for extents based files
++ *
++ *
+  * Need to be called with
+  * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
+  * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
++ *
++ * return > 0, number of of blocks already mapped/allocated
++ *          if create == 0 and these are pre-allocated blocks
++ *          	buffer head is unmapped
++ *          otherwise blocks are mapped
++ *
++ * return = 0, if plain look up failed (blocks have not been allocated)
++ *          buffer head is unmapped
++ *
++ * return < 0, error case.
+  */
+ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
+ 			ext4_lblk_t iblock,
+@@ -2623,7 +2647,7 @@ long ext4_fallocate(struct inode *inode,
+ 	 * modify 1 super block, 1 block bitmap and 1 group descriptor.
+ 	 */
+ 	credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3;
+-	down_write((&EXT4_I(inode)->i_data_sem));
++	mutex_lock(&inode->i_mutex);
+ retry:
+ 	while (ret >= 0 && ret < max_blocks) {
+ 		block = block + ret;
+@@ -2634,16 +2658,17 @@ retry:
+ 			break;
+ 		}
+ 
+-		ret = ext4_ext_get_blocks(handle, inode, block,
++		ret = ext4_get_blocks_wrap(handle, inode, block,
+ 					  max_blocks, &map_bh,
+ 					  EXT4_CREATE_UNINITIALIZED_EXT, 0);
+-		WARN_ON(ret <= 0);
+ 		if (ret <= 0) {
+-			ext4_error(inode->i_sb, "ext4_fallocate",
+-				    "ext4_ext_get_blocks returned error: "
+-				    "inode#%lu, block=%u, max_blocks=%lu",
++#ifdef EXT4FS_DEBUG
++			WARN_ON(ret <= 0);
++			printk(KERN_ERR "%s: ext4_ext_get_blocks "
++				    "returned error inode#%lu, block=%u, "
++				    "max_blocks=%lu", __func__,
+ 				    inode->i_ino, block, max_blocks);
+-			ret = -EIO;
++#endif
+ 			ext4_mark_inode_dirty(handle, inode);
+ 			ret2 = ext4_journal_stop(handle);
+ 			break;
+@@ -2680,7 +2705,6 @@ retry:
+ 	if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+ 		goto retry;
+ 
+-	up_write((&EXT4_I(inode)->i_data_sem));
+ 	/*
+ 	 * Time to update the file size.
+ 	 * Update only when preallocation was requested beyond the file size.
+@@ -2692,21 +2716,18 @@ retry:
+ 			 * if no error, we assume preallocation succeeded
+ 			 * completely
+ 			 */
+-			mutex_lock(&inode->i_mutex);
+ 			i_size_write(inode, offset + len);
+ 			EXT4_I(inode)->i_disksize = i_size_read(inode);
+-			mutex_unlock(&inode->i_mutex);
+ 		} else if (ret < 0 && nblocks) {
+ 			/* Handle partial allocation scenario */
+ 			loff_t newsize;
+ 
+-			mutex_lock(&inode->i_mutex);
+ 			newsize  = (nblocks << blkbits) + i_size_read(inode);
+ 			i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits));
+ 			EXT4_I(inode)->i_disksize = i_size_read(inode);
+-			mutex_unlock(&inode->i_mutex);
+ 		}
+ 	}
+ 
++	mutex_unlock(&inode->i_mutex);
+ 	return ret > 0 ? ret2 : ret;
+ }
+Index: linux-2.6.24.noarch/fs/ext4/mballoc.c
+===================================================================
+--- linux-2.6.24.noarch.orig/fs/ext4/mballoc.c
++++ linux-2.6.24.noarch/fs/ext4/mballoc.c
+@@ -627,21 +627,19 @@ static ext4_fsblk_t ext4_grp_offs_to_blo
+ 	return block;
+ }
+ 
++static inline void *mb_correct_addr_and_bit(int *bit, void *addr)
++{
+ #if BITS_PER_LONG == 64
+-#define mb_correct_addr_and_bit(bit, addr)		\
+-{							\
+-	bit += ((unsigned long) addr & 7UL) << 3;	\
+-	addr = (void *) ((unsigned long) addr & ~7UL);	\
+-}
++	*bit += ((unsigned long) addr & 7UL) << 3;
++	addr = (void *) ((unsigned long) addr & ~7UL);
+ #elif BITS_PER_LONG == 32
+-#define mb_correct_addr_and_bit(bit, addr)		\
+-{							\
+-	bit += ((unsigned long) addr & 3UL) << 3;	\
+-	addr = (void *) ((unsigned long) addr & ~3UL);	\
+-}
++	*bit += ((unsigned long) addr & 3UL) << 3;
++	addr = (void *) ((unsigned long) addr & ~3UL);
+ #else
+ #error "how many bits you are?!"
+ #endif
++	return addr;
++}
+ 
+ static inline int mb_test_bit(int bit, void *addr)
+ {
+@@ -649,34 +647,54 @@ static inline int mb_test_bit(int bit, v
+ 	 * ext4_test_bit on architecture like powerpc
+ 	 * needs unsigned long aligned address
+ 	 */
+-	mb_correct_addr_and_bit(bit, addr);
++	addr = mb_correct_addr_and_bit(&bit, addr);
+ 	return ext4_test_bit(bit, addr);
+ }
+ 
+ static inline void mb_set_bit(int bit, void *addr)
+ {
+-	mb_correct_addr_and_bit(bit, addr);
++	addr = mb_correct_addr_and_bit(&bit, addr);
+ 	ext4_set_bit(bit, addr);
+ }
+ 
+ static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr)
+ {
+-	mb_correct_addr_and_bit(bit, addr);
++	addr = mb_correct_addr_and_bit(&bit, addr);
+ 	ext4_set_bit_atomic(lock, bit, addr);
+ }
+ 
+ static inline void mb_clear_bit(int bit, void *addr)
+ {
+-	mb_correct_addr_and_bit(bit, addr);
++	addr = mb_correct_addr_and_bit(&bit, addr);
+ 	ext4_clear_bit(bit, addr);
+ }
+ 
+ static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr)
+ {
+-	mb_correct_addr_and_bit(bit, addr);
++	addr = mb_correct_addr_and_bit(&bit, addr);
+ 	ext4_clear_bit_atomic(lock, bit, addr);
+ }
+ 
++static inline int mb_find_next_zero_bit(void *addr, int max, int start)
++{
++	int fix = 0;
++	addr = mb_correct_addr_and_bit(&fix, addr);
++	max += fix;
++	start += fix;
++
++	return ext4_find_next_zero_bit(addr, max, start) - fix;
++}
++
++static inline int mb_find_next_bit(void *addr, int max, int start)
++{
++	int fix = 0;
++	addr = mb_correct_addr_and_bit(&fix, addr);
++	max += fix;
++	start += fix;
++
++	return ext4_find_next_bit(addr, max, start) - fix;
++}
++
+ static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
+ {
+ 	char *bb;
+@@ -906,7 +924,7 @@ static void ext4_mb_mark_free_simple(str
+ 	unsigned short chunk;
+ 	unsigned short border;
+ 
+-	BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb));
++	BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb));
+ 
+ 	border = 2 << sb->s_blocksize_bits;
+ 
+@@ -946,12 +964,12 @@ static void ext4_mb_generate_buddy(struc
+ 
+ 	/* initialize buddy from bitmap which is aggregation
+ 	 * of on-disk bitmap and preallocations */
+-	i = ext4_find_next_zero_bit(bitmap, max, 0);
++	i = mb_find_next_zero_bit(bitmap, max, 0);
+ 	grp->bb_first_free = i;
+ 	while (i < max) {
+ 		fragments++;
+ 		first = i;
+-		i = ext4_find_next_bit(bitmap, max, i);
++		i = mb_find_next_bit(bitmap, max, i);
+ 		len = i - first;
+ 		free += len;
+ 		if (len > 1)
+@@ -959,7 +977,7 @@ static void ext4_mb_generate_buddy(struc
+ 		else
+ 			grp->bb_counters[0]++;
+ 		if (i < max)
+-			i = ext4_find_next_zero_bit(bitmap, max, i);
++			i = mb_find_next_zero_bit(bitmap, max, i);
+ 	}
+ 	grp->bb_fragments = fragments;
+ 
+@@ -967,6 +985,10 @@ static void ext4_mb_generate_buddy(struc
+ 		ext4_error(sb, __FUNCTION__,
+ 			"EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n",
+ 			group, free, grp->bb_free);
++		/*
++		 * If we intent to continue, we consider group descritor
++		 * corrupt and update bb_free using bitmap value
++		 */
+ 		grp->bb_free = free;
+ 	}
+ 
+@@ -1146,8 +1168,9 @@ out:
  	return err;
  }
  
 -static int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
-+static noinline int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
- 		struct ext4_buddy *e4b)
+-		struct ext4_buddy *e4b)
++static noinline int
++ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
++					struct ext4_buddy *e4b)
  {
  	struct ext4_sb_info *sbi = EXT4_SB(sb);
-@@ -1937,7 +1937,7 @@ static int ext4_mb_good_group(struct ext
+ 	struct inode *inode = sbi->s_buddy_cache;
+@@ -1778,7 +1801,7 @@ static void ext4_mb_simple_scan_group(st
+ 		buddy = mb_find_buddy(e4b, i, &max);
+ 		BUG_ON(buddy == NULL);
+ 
+-		k = ext4_find_next_zero_bit(buddy, max, 0);
++		k = mb_find_next_zero_bit(buddy, max, 0);
+ 		BUG_ON(k >= max);
+ 
+ 		ac->ac_found++;
+@@ -1818,11 +1841,11 @@ static void ext4_mb_complex_scan_group(s
+ 	i = e4b->bd_info->bb_first_free;
+ 
+ 	while (free && ac->ac_status == AC_STATUS_CONTINUE) {
+-		i = ext4_find_next_zero_bit(bitmap,
++		i = mb_find_next_zero_bit(bitmap,
+ 						EXT4_BLOCKS_PER_GROUP(sb), i);
+ 		if (i >= EXT4_BLOCKS_PER_GROUP(sb)) {
+ 			/*
+-			 * IF we corrupt the bitmap  we won't find any
++			 * IF we have corrupt bitmap, we won't find any
+ 			 * free blocks even though group info says we
+ 			 * we have free blocks
+ 			 */
+@@ -1838,6 +1861,12 @@ static void ext4_mb_complex_scan_group(s
+ 			ext4_error(sb, __FUNCTION__, "%d free blocks as per "
+ 					"group info. But got %d blocks\n",
+ 					free, ex.fe_len);
++			/*
++			 * The number of free blocks differs. This mostly
++			 * indicate that the bitmap is corrupt. So exit
++			 * without claiming the space.
++			 */
++			break;
+ 		}
+ 
+ 		ext4_mb_measure_extent(ac, &ex, e4b);
+@@ -1937,7 +1966,8 @@ static int ext4_mb_good_group(struct ext
  	return 0;
  }
  
 -static int ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
-+static noinline int ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
++static noinline int
++ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
  {
  	ext4_group_t group;
  	ext4_group_t i;
-@@ -2444,7 +2444,7 @@ static void ext4_mb_history_init(struct 
+@@ -2444,7 +2474,7 @@ static void ext4_mb_history_init(struct 
  	/* if we can't allocate history, then we simple won't use it */
  }
  
@@ -70,7 +494,7 @@
  {
  	struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
  	struct ext4_mb_history h;
-@@ -2780,7 +2780,7 @@ int ext4_mb_release(struct super_block *
+@@ -2780,7 +2810,7 @@ int ext4_mb_release(struct super_block *
  	return 0;
  }
  
@@ -79,25 +503,27 @@
  {
  	struct ext4_sb_info *sbi = EXT4_SB(sb);
  	int err;
-@@ -3001,7 +3001,7 @@ void exit_ext4_mballoc(void)
+@@ -3001,7 +3031,8 @@ void exit_ext4_mballoc(void)
   * Check quota and mark choosed space (ac->ac_b_ex) non-free in bitmaps
   * Returns 0 if success or error code
   */
 -static int ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
-+static noinline int ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
++static noinline int
++ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
  				handle_t *handle)
  {
  	struct buffer_head *bitmap_bh = NULL;
-@@ -3118,7 +3118,7 @@ static void ext4_mb_normalize_group_requ
+@@ -3118,7 +3149,8 @@ static void ext4_mb_normalize_group_requ
   * Normalization means making request better in terms of
   * size and alignment
   */
 -static void ext4_mb_normalize_request(struct ext4_allocation_context *ac,
-+static noinline void ext4_mb_normalize_request(struct ext4_allocation_context *ac,
++static noinline void
++ext4_mb_normalize_request(struct ext4_allocation_context *ac,
  				struct ext4_allocation_request *ar)
  {
  	int bsbits, max;
-@@ -3384,7 +3384,7 @@ static void ext4_mb_use_group_pa(struct 
+@@ -3384,7 +3416,7 @@ static void ext4_mb_use_group_pa(struct 
  /*
   * search goal blocks in preallocated space
   */
@@ -106,7 +532,7 @@
  {
  	struct ext4_inode_info *ei = EXT4_I(ac->ac_inode);
  	struct ext4_locality_group *lg;
-@@ -3551,7 +3551,7 @@ static void ext4_mb_put_pa(struct ext4_a
+@@ -3551,7 +3583,7 @@ static void ext4_mb_put_pa(struct ext4_a
  /*
   * creates new preallocated space for given inode
   */
@@ -115,7 +541,7 @@
  {
  	struct super_block *sb = ac->ac_sb;
  	struct ext4_prealloc_space *pa;
-@@ -3638,7 +3638,7 @@ static int ext4_mb_new_inode_pa(struct e
+@@ -3638,7 +3670,7 @@ static int ext4_mb_new_inode_pa(struct e
  /*
   * creates new preallocated space for locality group inodes belongs to
   */
@@ -124,7 +550,7 @@
  {
  	struct super_block *sb = ac->ac_sb;
  	struct ext4_locality_group *lg;
-@@ -3711,7 +3711,7 @@ static int ext4_mb_new_preallocation(str
+@@ -3711,7 +3743,7 @@ static int ext4_mb_new_preallocation(str
   * the caller MUST hold group/inode locks.
   * TODO: optimize the case when there are no in-core structures yet
   */
@@ -133,7 +559,31 @@
  				struct buffer_head *bitmap_bh,
  				struct ext4_prealloc_space *pa)
  {
-@@ -3779,7 +3779,7 @@ static int ext4_mb_release_inode_pa(stru
+@@ -3740,10 +3772,10 @@ static int ext4_mb_release_inode_pa(stru
+ 	}
+ 
+ 	while (bit < end) {
+-		bit = ext4_find_next_zero_bit(bitmap_bh->b_data, end, bit);
++		bit = mb_find_next_zero_bit(bitmap_bh->b_data, end, bit);
+ 		if (bit >= end)
+ 			break;
+-		next = ext4_find_next_bit(bitmap_bh->b_data, end, bit);
++		next = mb_find_next_bit(bitmap_bh->b_data, end, bit);
+ 		if (next > end)
+ 			next = end;
+ 		start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit +
+@@ -3771,6 +3803,10 @@ static int ext4_mb_release_inode_pa(stru
+ 			(unsigned long) pa->pa_len);
+ 		ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n",
+ 						free, pa->pa_free);
++		/*
++		 * pa is already deleted so we use the value obtained
++		 * from the bitmap and continue.
++		 */
+ 	}
+ 	atomic_add(free, &sbi->s_mb_discarded);
+ 	if (ac)
+@@ -3779,7 +3815,7 @@ static int ext4_mb_release_inode_pa(stru
  	return err;
  }
  
@@ -142,7 +592,7 @@
  				struct ext4_prealloc_space *pa)
  {
  	struct ext4_allocation_context *ac;
-@@ -3821,7 +3821,7 @@ static int ext4_mb_release_group_pa(stru
+@@ -3821,7 +3857,7 @@ static int ext4_mb_release_group_pa(stru
   * - how many do we discard
   *   1) how many requested
   */
@@ -151,22 +601,210 @@
  					ext4_group_t group, int needed)
  {
  	struct ext4_group_info *grp = ext4_get_group_info(sb, group);
-@@ -4143,7 +4143,7 @@ static void ext4_mb_group_or_file(struct
+@@ -4143,7 +4179,8 @@ static void ext4_mb_group_or_file(struct
  	mutex_lock(&ac->ac_lg->lg_mutex);
  }
  
 -static int ext4_mb_initialize_context(struct ext4_allocation_context *ac,
-+static noinline int ext4_mb_initialize_context(struct ext4_allocation_context *ac,
++static noinline int
++ext4_mb_initialize_context(struct ext4_allocation_context *ac,
  				struct ext4_allocation_request *ar)
  {
  	struct super_block *sb = ar->inode->i_sb;
-@@ -4374,7 +4374,7 @@ static void ext4_mb_poll_new_transaction
+@@ -4374,7 +4411,8 @@ static void ext4_mb_poll_new_transaction
  	ext4_mb_free_committed_blocks(sb);
  }
  
 -static int ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
-+static noinline int ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
++static noinline int
++ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
  			  ext4_group_t group, ext4_grpblk_t block, int count)
  {
  	struct ext4_group_info *db = e4b->bd_info;
-
+Index: linux-2.6.24.noarch/fs/ext4/namei.c
+===================================================================
+--- linux-2.6.24.noarch.orig/fs/ext4/namei.c
++++ linux-2.6.24.noarch/fs/ext4/namei.c
+@@ -1804,12 +1804,8 @@ retry:
+ 	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);
+-	if (!dir_block) {
+-		ext4_dec_count(handle, inode); /* is this nlink == 0? */
+-		ext4_mark_inode_dirty(handle, inode);
+-		iput (inode);
+-		goto out_stop;
+-	}
++	if (!dir_block)
++		goto out_clear_inode;
+ 	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;
+@@ -1832,7 +1828,8 @@ retry:
+ 	ext4_mark_inode_dirty(handle, inode);
+ 	err = ext4_add_entry (handle, dentry, inode);
+ 	if (err) {
+-		inode->i_nlink = 0;
++out_clear_inode:
++		clear_nlink(inode);
+ 		ext4_mark_inode_dirty(handle, inode);
+ 		iput (inode);
+ 		goto out_stop;
+@@ -2164,7 +2161,7 @@ static int ext4_unlink(struct inode * di
+ 	dir->i_ctime = dir->i_mtime = ext4_current_time(dir);
+ 	ext4_update_dx_flag(dir);
+ 	ext4_mark_inode_dirty(handle, dir);
+-	ext4_dec_count(handle, inode);
++	drop_nlink(inode);
+ 	if (!inode->i_nlink)
+ 		ext4_orphan_add(handle, inode);
+ 	inode->i_ctime = ext4_current_time(inode);
+@@ -2214,7 +2211,7 @@ retry:
+ 		err = __page_symlink(inode, symname, l,
+ 				mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
+ 		if (err) {
+-			ext4_dec_count(handle, inode);
++			clear_nlink(inode);
+ 			ext4_mark_inode_dirty(handle, inode);
+ 			iput (inode);
+ 			goto out_stop;
+@@ -2223,7 +2220,6 @@ retry:
+ 		inode->i_op = &ext4_fast_symlink_inode_operations;
+ 		memcpy((char*)&EXT4_I(inode)->i_data,symname,l);
+ 		inode->i_size = l-1;
+-		EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL;
+ 	}
+ 	EXT4_I(inode)->i_disksize = inode->i_size;
+ 	err = ext4_add_nondir(handle, dentry, inode);
+@@ -2407,7 +2403,7 @@ static int ext4_rename (struct inode * o
+ 		ext4_dec_count(handle, old_dir);
+ 		if (new_inode) {
+ 			/* checked empty_dir above, can't have another parent,
+-			 * ext3_dec_count() won't work for many-linked dirs */
++			 * ext4_dec_count() won't work for many-linked dirs */
+ 			new_inode->i_nlink = 0;
+ 		} else {
+ 			ext4_inc_count(handle, new_dir);
+Index: linux-2.6.24.noarch/fs/ext4/migrate.c
+===================================================================
+--- linux-2.6.24.noarch.orig/fs/ext4/migrate.c
++++ linux-2.6.24.noarch/fs/ext4/migrate.c
+@@ -43,6 +43,7 @@ static int finish_range(handle_t *handle
+ 
+ 	if (IS_ERR(path)) {
+ 		retval = PTR_ERR(path);
++		path = NULL;
+ 		goto err_out;
+ 	}
+ 
+@@ -74,6 +75,10 @@ static int finish_range(handle_t *handle
+ 	}
+ 	retval = ext4_ext_insert_extent(handle, inode, path, &newext);
+ err_out:
++	if (path) {
++		ext4_ext_drop_refs(path);
++		kfree(path);
++	}
+ 	lb->first_pblock = 0;
+ 	return retval;
+ }
+Index: linux-2.6.24.noarch/include/linux/ext4_fs_extents.h
+===================================================================
+--- linux-2.6.24.noarch.orig/include/linux/ext4_fs_extents.h
++++ linux-2.6.24.noarch/include/linux/ext4_fs_extents.h
+@@ -227,5 +227,6 @@ extern int ext4_ext_search_left(struct i
+ 						ext4_lblk_t *, ext4_fsblk_t *);
+ extern int ext4_ext_search_right(struct inode *, struct ext4_ext_path *,
+ 						ext4_lblk_t *, ext4_fsblk_t *);
++extern void ext4_ext_drop_refs(struct ext4_ext_path *);
+ #endif /* _LINUX_EXT4_EXTENTS */
+ 
+Index: linux-2.6.24.noarch/fs/ext4/file.c
+===================================================================
+--- linux-2.6.24.noarch.orig/fs/ext4/file.c
++++ linux-2.6.24.noarch/fs/ext4/file.c
+@@ -123,6 +123,23 @@ force_commit:
+ 	return ret;
+ }
+ 
++static struct vm_operations_struct ext4_file_vm_ops = {
++	.fault		= filemap_fault,
++	.page_mkwrite   = ext4_page_mkwrite,
++};
++
++static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
++{
++	struct address_space *mapping = file->f_mapping;
++
++	if (!mapping->a_ops->readpage)
++		return -ENOEXEC;
++	file_accessed(file);
++	vma->vm_ops = &ext4_file_vm_ops;
++	vma->vm_flags |= VM_CAN_NONLINEAR;
++	return 0;
++}
++
+ const struct file_operations ext4_file_operations = {
+ 	.llseek		= generic_file_llseek,
+ 	.read		= do_sync_read,
+@@ -133,7 +150,7 @@ const struct file_operations ext4_file_o
+ #ifdef CONFIG_COMPAT
+ 	.compat_ioctl	= ext4_compat_ioctl,
+ #endif
+-	.mmap		= generic_file_mmap,
++	.mmap		= ext4_file_mmap,
+ 	.open		= generic_file_open,
+ 	.release	= ext4_release_file,
+ 	.fsync		= ext4_sync_file,
+Index: linux-2.6.24.noarch/include/linux/ext4_fs.h
+===================================================================
+--- linux-2.6.24.noarch.orig/include/linux/ext4_fs.h
++++ linux-2.6.24.noarch/include/linux/ext4_fs.h
+@@ -1047,6 +1047,7 @@ extern void ext4_set_aops(struct inode *
+ extern int ext4_writepage_trans_blocks(struct inode *);
+ extern int ext4_block_truncate_page(handle_t *handle, struct page *page,
+ 		struct address_space *mapping, loff_t from);
++extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page);
+ 
+ /* ioctl.c */
+ extern int ext4_ioctl (struct inode *, struct file *, unsigned int,
+Index: linux-2.6.24.noarch/fs/ext4/ialloc.c
+===================================================================
+--- linux-2.6.24.noarch.orig/fs/ext4/ialloc.c
++++ linux-2.6.24.noarch/fs/ext4/ialloc.c
+@@ -702,7 +702,12 @@ got:
+ 	ei->i_dir_start_lookup = 0;
+ 	ei->i_disksize = 0;
+ 
+-	ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL;
++	/*
++	 * Don't inherit extent flag from directory. We set extent flag on
++	 * newly created directory and file only if -o extent mount option is
++	 * specified
++	 */
++	ei->i_flags = EXT4_I(dir)->i_flags & ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL);
+ 	if (S_ISLNK(mode))
+ 		ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);
+ 	/* dirsync only applies to directories */
+@@ -745,12 +750,15 @@ got:
+ 		goto fail_free_drop;
+ 	}
+ 	if (test_opt(sb, EXTENTS)) {
+-		EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
+-		ext4_ext_tree_init(handle, inode);
+-		err = ext4_update_incompat_feature(handle, sb,
+-						EXT4_FEATURE_INCOMPAT_EXTENTS);
+-		if (err)
+-			goto fail;
++		/* set extent flag only for diretory and file */
++		if (S_ISDIR(mode) || S_ISREG(mode)) {
++			EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
++			ext4_ext_tree_init(handle, inode);
++			err = ext4_update_incompat_feature(handle, sb,
++					EXT4_FEATURE_INCOMPAT_EXTENTS);
++			if (err)
++				goto fail;
++		}
+ 	}
+ 
+ 	ext4_debug("allocating inode %lu\n", inode->i_ino);


--- linux-2.6-ext4-linus-git.patch DELETED ---




More information about the fedora-extras-commits mailing list