Skip to contentSkip to conversation

New: oops in extent code via ext4_fallocate]

Fwd: In review Eric Sandeen 3 participants 8 messages Jan 11, 2008 – Jan 15, 2008 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

http://bugzilla.kernel.org/show_bug.cgi?id=9732

Summary: oops in extent code via ext4_fallocate
Product: File System
Version: 2.5
KernelVersion: 2.6.24-rc7
Platform: All
OS/Version: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: ext4
AssignedTo: [email protected]
ReportedBy: [email protected]

Latest working kernel version: Unknown
Earliest failing kernel version: 2.6.24-rc7
Distribution: Fedora Rawhide
Hardware Environment: x86_64
Software Environment:
Problem Description:

a simple fallocate; truncate; fallocate series oopses the kernel.

2.6.24-rc7 with the latest ext4 patch stack as of about Jan 9, 2008, minus delalloc patches.

Steps to reproduce, using the test program at
http://oss.sgi.com/archives/xfs/2007-07/msg00092.html

[root@bear-05 sdb8]# touch testfile [root@bear-05 sdb8]# ./testfallocate -f testfile 0 65536 Trying to preallocate blocks (offset=0, len=65536) fallocate system call succedded ! ret=0
# FALLOCATE TEST REPORT #
New blocks preallocated = 16.
Number of bytes preallocated = 65536 Old file size = 0, New file size 65536. Old num blocks = 0, New num blocks 64.

### TESTS PASSED ###
[root@bear-05 sdb8]# ls -lh testfile; du -hc testfile -rw-r--r-- 1 root root 64K Jan 11 14:12 testfile
64K testfile
64K total
[root@bear-05 sdb8]# /root/truncate testfile 32768 Truncating testfile to 32768
[root@bear-05 sdb8]# ls -lh testfile; du -hc testfile -rw-r--r-- 1 root root 32K Jan 11 14:12 testfile
32K testfile
32K total
[root@bear-05 sdb8]# ./testfallocate -f testfile 0 65536 Trying to preallocate blocks (offset=0, len=65536) Segmentation fault

and yields:
EXT4-fs: file extents enabled
EXT4-fs: mballoc enabled

------------[ cut here ]------------
kernel BUG at fs/ext4/extents.c:1056!
invalid opcode: 0000 [1] SMP 
CPU 2 
Modules linked in: ext4dev jbd2 crc16 autofs4 hidp nfs lockd nfs_acl rfcomm

l2cap bluetooth sunrpc ipv6 cpufreq_ondemand dm_multipath video output sbs sbshc battery ac power_supply parport_pc lp parport sg pata_acpi cfi_cmdset_0002 ata_generic cfi_util button jedec_probe serio_raw cfi_probe tg3 gen_probe ck804xrom mtd rtc_cmos chipreg pata_amd map_funcs k8temp libata hwmon i2c_nforce2 shpchp i2c_core pcspkr dm_snapshot dm_zero dm_mirror dm_mod qla2xxx scsi_transport_fc scsi_tgt mptspi mptscsih mptbase scsi_transport_spi sd_mod scsi_mod ext3 jbd mbcache ehci_hcd ohci_hcd uhci_hcd
Pid: 3554, comm: testfallocate Not tainted 2.6.24-0.147.rc7.git2.fc9 #1

RIP: 0010:[<ffffffff88364497>]  [<ffffffff88364497>]
:ext4dev:ext4_ext_search_left+0x97/0xbc
RSP: 0018:ffff81012dc65cf0  EFLAGS: 00010287
RAX: 0000000000008008 RBX: ffff81012dc65d78 RCX: 0000000000000000
RDX: ffff81012dc65d90 RSI: ffff81012e5f37e0 RDI: ffff81012e04c00c
RBP: ffff81012e04c180 R08: 0000000000000008 R09: 0000000000000000
R10: 0000000000000000 R11: ffff81012dc65d98 R12: 0000000000000008
R13: ffff81012e04c180 R14: 0000000000000008 R15: 0000000000000000
FS:  00002aaaaaab96f0(0000) GS:ffff81013fc01a28(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 000000327d0414a0 CR3: 0000000130ce8000 CR4: 00000000000006a0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process testfallocate (pid: 3554, threadinfo ffff81012dc64000, task
ffff81012dd5a000)
Stack:  ffffffff88366073 ffff8101349e71d0 ffffffff81053c91 000000022dcc30b8
 ffff81012dc65e88 0000000000000008 ffff81012e549000 ffff81012dcc30b8
 ffff81012dcc3090 ffff81012e04c000 ffff81012dcc30b8 0000000000000008
Call Trace:
 [<ffffffff88366073>] :ext4dev:ext4_ext_get_blocks+0x5ba/0x8c1
 [<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
 [<ffffffff812748f6>] _spin_unlock+0x17/0x20
 [<ffffffff883400a6>] :jbd2:start_this_handle+0x4e0/0x4fe
 [<ffffffff88366564>] :ext4dev:ext4_fallocate+0x175/0x39a
 [<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
 [<ffffffff81056480>] __lock_acquire+0x4e7/0xc4d
 [<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
 [<ffffffff810a8de7>] sys_fallocate+0xe4/0x10d
 [<ffffffff8100c043>] tracesys+0xd5/0xda


Code: 0f 0b eb fe ff c8 89 02 0f b7 47 06 8b 4f 08 0f b7 57 04 48 
RIP  [<ffffffff88364497>] :ext4dev:ext4_ext_search_left+0x97/0xbc
 RSP <ffff81012dc65cf0>
---[ end trace 9a60a6a6c694770a ]---

SysRq : Resetting

The BUG_ON is:

        BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));

where these were the values:

        logical 8 ee_block 0 ee_len 32776

Haven't looked further into it yet.

Signature · 3 lines
Configure bugmail: http://bugzilla.kernel.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You reported the bug, or are watching the reporter.
#1 lore raw
Quoted 11 lines · Eric Sandeen

The BUG_ON is:

        BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));

where these were the values:

        logical 8 ee_block 0 ee_len 32776

Haven't looked further into it yet.

Not able to reproduce. Why is it calling ext4_ext_search_left for that value of logical ? ext4_ext_get_blocks should have found that the logical belong to an already existing extent and return from there. It should have returned from

2365 if (create == EXT4_CREATE_UNINITIALIZED_EXT)
2366 goto out;

root@qemu-image:/ext4# /root/testfallocate  -f a 0 100
# FALLOCATE TEST REPORT #
        New blocks preallocated = 0.
        Number of bytes preallocated = 0
        Old file size = 100, New file size 100.
        Old num blocks = 4, New num blocks 4.

### TESTS PASSED ###

root@qemu-image:/ext4# ls -alh a
-rw-r--r-- 1 root root 100 Jan  9 16:23 a
root@qemu-image:/ext4# /root/truncate  ./a 50
root@qemu-image:/ext4# ls -alh a
-rw-r--r-- 1 root root 50 Jan  9 16:23 a
root@qemu-image:/ext4# /root/testfallocate  -f a 0 100
# FALLOCATE TEST REPORT #
        New blocks preallocated = 0.
        Number of bytes preallocated = 0
        Old file size = 50, New file size 100.
        Old num blocks = 4, New num blocks 4.

### TESTS PASSED ###

root@qemu-image:/ext4# ls -alh a
-rw-r--r-- 1 root root 100 Jan  9 16:23 a
root@qemu-image:/ext4# more /proc/mounts  | grep ext4dev
/dev/hdc /ext4 ext4dev rw,nodelalloc,data=writeback 0 0
root@qemu-image:/ext4#

The third fallocate should result in calling ext4_ext_get_blocks two times. The first call with logical 0 and max 100 and it will return with allocated 50. Then call again with logical 50 and max 50.

Something else is wrong.

-aneesh

#2 lore raw
Quoted 22 lines · Aneesh Kumar K.V
Quoted 10 lines · Eric Sandeen

The BUG_ON is:

        BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));

where these were the values:

        logical 8 ee_block 0 ee_len 32776

Haven't looked further into it yet.

Not able to reproduce. Why is it calling ext4_ext_search_left for that value of logical ? ext4_ext_get_blocks should have found that the logical belong to an already existing extent and return from there. It should have returned from

2365 if (create == EXT4_CREATE_UNINITIALIZED_EXT)
2366 goto out;

Quoted 5 lines
root@qemu-image:/ext4# /root/testfallocate  -f a 0 100
root@qemu-image:/ext4# /root/truncate  ./a 50
root@qemu-image:/ext4# /root/testfallocate  -f a 0 100

This isn't exercising extents code at all, all your sizes are all within the first block. Try the numbers I have in the bug?

Or more simply,

[root@bear-05 sdb8]# ./testfallocate -f testfile 0 32768 [root@bear-05 sdb8]# ./testfallocate -f testfile 16384 65536

or

[root@bear-05 sdb8]# ./testfallocate -f testfile 0 16384 [root@bear-05 sdb8]# ./testfallocate -f testfile 32768 65536

-Eric

#3 lore raw
Quoted 2 lines · Eric Sandeen

[root@bear-05 sdb8]# ./testfallocate -f testfile 0 32768 [root@bear-05 sdb8]# ./testfallocate -f testfile 16384 65536

(oh, for completeness I started with a fresh 0 length, 0 size file):

# rm -f testfile; touch testfile
<testfallocate tests>

-Eric

A message that is not in the archive (sent off-list or not yet received): [email protected]

#5 lore raw

Re: checkpatch.pl warnings

Quoted 4 lines · Mingming Cao

Hi Guys,

Could you check the checkpatch.pl warnings and see if it make sense to fix them? Thanks!

Quoted 12 lines
cmm@kernel:~/fs/ext4/stylecheck$ grep "has style problems" *
linux-2.6.24-rc7-48-bit-i_blocks.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext3-4-migrate.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext4_export_iov_shorten_from_kernel_for_ext4.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext4-journal_chksum-2.6.20.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext4_rec_len_overflow_with_64kblk_fix-v2.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext4_store_maxbytes_for_bitmaped_files.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-inode-version-ext4.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-jbd-stats-through-procfs.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-large-file-blocktype.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-mballoc-core.patch.out:Your patch has style problems, please review.  If any of these errors

Fixed the checkpatch.pl warning for all the patches in the patch queue. The diff is attached below for review.

patch queue at
http://www.radian.org/~kvaneesh/ext4/jan-15-2008/
http://www.radian.org/~kvaneesh/ext4/jan-15-2008/patch-queue.tar

This include the complete patch queue.

Tested with
----------
fsx_linux, fs_inode, fsstress on x86_64
fsx_linux, fs_inode, fsstress on ppc64

fs/ext4/extents.c +8 -6
index 1e46997..2ea7ef4 100644
@@ -1798,8 +1798,9 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
 		printk(KERN_INFO "strange request: removal %u-%u from %u:%u\n",
 			from, to, le32_to_cpu(ex->ee_block), ee_len);
 	} else {
-		printk(KERN_INFO "strange request: removal(2) %u-%u from %u:%u\n",
-			from, to, le32_to_cpu(ex->ee_block), ee_len);
+		printk(KERN_INFO "strange request: removal(2) "
+				"%u-%u from %u:%u\n",
+				from, to, le32_to_cpu(ex->ee_block), ee_len);
 	}
 	return 0;
 }
@@ -2140,10 +2141,11 @@ void ext4_ext_release(struct super_block *sb)
  *   b> Splits in two extents: Write is happening at either end of the extent
  *   c> Splits in three extents: Somone is writing in middle of the extent
  */
-static int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode,
-					struct ext4_ext_path *path,
-					ext4_lblk_t iblock,
-					unsigned long max_blocks)
+static int ext4_ext_convert_to_initialized(handle_t *handle,
+						struct inode *inode,
+						struct ext4_ext_path *path,
+						ext4_lblk_t iblock,
+						unsigned long max_blocks)
 {
 	struct ext4_extent *ex, newex;
 	struct ext4_extent *ex1 = NULL;
fs/ext4/inode.c +3 -2
index f7dc5f3..6bb788d 100644
@@ -751,7 +751,8 @@ err_out:
 	for (i = 1; i <= num; i++) {
 		BUFFER_TRACE(where[i].bh, "call jbd2_journal_forget");
 		ext4_journal_forget(handle, where[i].bh);
-		ext4_free_blocks(handle,inode,le32_to_cpu(where[i-1].key),1, 0);
+		ext4_free_blocks(handle, inode,
+					le32_to_cpu(where[i-1].key), 1, 0);
 	}
 	ext4_free_blocks(handle, inode, le32_to_cpu(where[num].key), blks, 0);
 
@@ -2829,7 +2830,7 @@ static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
 				EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
 		/* we are using combined 48 bit field */
 		i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
-						le32_to_cpu(raw_inode->i_blocks_lo);
+					le32_to_cpu(raw_inode->i_blocks_lo);
 		if (ei->i_flags & EXT4_HUGE_FILE_FL) {
 			/* i_blocks represent file system block size */
 			return i_blocks  << (inode->i_blkbits - 9);
fs/ext4/mballoc.c +59 -51

347 lines not on this page · raw message

fs/ext4/migrate.c +15 -12
index 0e4bffe..1d4d6e0 100644
@@ -40,7 +40,7 @@ static int finish_range(handle_t *handle, struct inode *inode,
 
 	/* Add the extent to temp inode*/
 	newext.ee_block = cpu_to_le32(lb->first_block);
-	newext.ee_len   = cpu_to_le16(lb->last_block - lb->first_block +1);
+	newext.ee_len   = cpu_to_le16(lb->last_block - lb->first_block + 1);
 	ext4_ext_store_pblock(&newext, lb->first_pblock);
 	path = ext4_ext_find_extent(inode, lb->first_block, NULL);
 
@@ -69,13 +69,16 @@ static int finish_range(handle_t *handle, struct inode *inode,
 
 	}
 
-	if (needed && (retval = ext4_journal_extend(handle, needed)) != 0) {
-		/*
-		 * IF not able to extend the journal restart the journal
-		 */
-		retval = ext4_journal_restart(handle, needed);
-		if (retval)
-			goto err_out;
+	if (needed) {
+		retval = ext4_journal_extend(handle, needed);
+		if (retval != 0) {
+			/*
+			 * IF not able to extend the journal restart the journal
+			 */
+			retval = ext4_journal_restart(handle, needed);
+			if (retval)
+				goto err_out;
+		}
 	}
 
 	retval = ext4_ext_insert_extent(handle, inode, path, &newext);
@@ -336,8 +339,8 @@ static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode,
 	 * One credit accounted for writing the
 	 * i_data field of the original inode
 	 */
-	if ((retval = ext4_journal_extend(handle, 1)) != 0) {
-
+	retval = ext4_journal_extend(handle, 1);
+	if (retval != 0) {
 		retval = ext4_journal_restart(handle, 1);
 		if (retval)
 			goto err_out;
@@ -439,7 +442,7 @@ static int free_ext_block(handle_t *handle, struct inode *inode)
 	return retval;
 
 }
-int ext4_ext_migrate(struct inode * inode, struct file * filp,
+int ext4_ext_migrate(struct inode *inode, struct file *filp,
 				unsigned int cmd, unsigned long arg)
 {
 	handle_t *handle;
@@ -503,7 +506,7 @@ int ext4_ext_migrate(struct inode * inode, struct file * filp,
 	ext4_journal_stop(handle);
 
 	ei = EXT4_I(inode);
-        i_data = ei->i_data;
+	i_data = ei->i_data;
 	memset(&lb, 0, sizeof(lb));
 
 	/* 32 bit block address 4 bytes */
fs/ext4/namei.c +14 -12
index c8adca7..67b6d8a 100644
@@ -144,8 +144,8 @@ struct dx_map_entry
 	u16 size;
 };
 
-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 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);
 static void dx_set_hash (struct dx_entry *entry, unsigned value);
 static unsigned dx_get_count (struct dx_entry *entries);
@@ -166,7 +166,7 @@ static void dx_sort_map(struct dx_map_entry *map, unsigned count);
 static struct ext4_dir_entry_2 *dx_move_dirents (char *from, char *to,
 		struct dx_map_entry *offsets, int count);
 static struct ext4_dir_entry_2* dx_pack_dirents (char *base, int size);
-static void dx_insert_block (struct dx_frame *frame,
+static void dx_insert_block(struct dx_frame *frame,
 					u32 hash, ext4_lblk_t block);
 static int ext4_htree_next_block(struct inode *dir, __u32 hash,
 				 struct dx_frame *frame,
@@ -182,12 +182,12 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
  * Mask them off for now.
  */
 
-static inline ext4_lblk_t dx_get_block (struct dx_entry *entry)
+static inline ext4_lblk_t dx_get_block(struct dx_entry *entry)
 {
 	return le32_to_cpu(entry->block) & 0x00ffffff;
 }
 
-static inline void dx_set_block (struct dx_entry *entry, ext4_lblk_t value)
+static inline void dx_set_block(struct dx_entry *entry, ext4_lblk_t value)
 {
 	entry->block = cpu_to_le32(value);
 }
@@ -298,8 +298,8 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
 	printk("%i indexed blocks...\n", count);
 	for (i = 0; i < count; i++, entries++)
 	{
-		ext4_lblk_t block = dx_get_block(entries),
-						hash = i? dx_get_hash(entries): 0;
+		ext4_lblk_t block = dx_get_block(entries);
+		ext4_lblk_t hash  = i ? dx_get_hash(entries): 0;
 		u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
 		struct stats stats;
 		printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
@@ -553,7 +553,7 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash,
  */
 static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *p)
 {
-	return (struct ext4_dir_entry_2 *)((char*)p +
+	return (struct ext4_dir_entry_2 *)((char *)p +
 		ext4_rec_len_from_disk(p->rec_len));
 }
 
@@ -571,7 +571,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
 	struct ext4_dir_entry_2 *de, *top;
 	int err, count = 0;
 
-	dxtrace(printk("In htree dirblock_to_tree: block %lu\n",
+	dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n",
 							(unsigned long)block));
 	if (!(bh = ext4_bread (NULL, dir, block, 0, &err)))
 		return err;
@@ -915,7 +915,8 @@ restart:
 		if (!buffer_uptodate(bh)) {
 			/* read error, skip block & hope for the best */
 			ext4_error(sb, __FUNCTION__, "reading directory #%lu "
-				   "offset %lu", dir->i_ino, (unsigned long)block);
+				   "offset %lu", dir->i_ino,
+				   (unsigned long)block);
 			brelse(bh);
 			goto next;
 		}
@@ -1221,7 +1222,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
 	split = count - move;
 	hash2 = map[split].hash;
 	continued = hash2 == map[split - 1].hash;
-	dxtrace(printk("Split block %lu at %x, %i/%i\n",
+	dxtrace(printk(KERN_INFO "Split block %lu at %x, %i/%i\n",
 			(unsigned long)dx_get_block(frame->at),
 					hash2, split, count-split));
 
@@ -1830,7 +1831,8 @@ retry:
 	ext4_set_de_type(dir->i_sb, de, S_IFDIR);
 	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));
+	de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
+						EXT4_DIR_REC_LEN(1));
 	de->name_len = 2;
 	strcpy (de->name, "..");
 	ext4_set_de_type(dir->i_sb, de, S_IFDIR);
fs/ext4/super.c +5 -5
index 0314355..3d7256e 100644
@@ -888,7 +888,7 @@ enum {
 	Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
 	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
 	Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
-	Opt_grpquota, Opt_extents, Opt_noextents,Opt_i_version,
+	Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
 	Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc,
 };
 
@@ -1120,11 +1120,11 @@ static int parse_options (char *options, struct super_block *sb,
 			*journal_devnum = option;
 			break;
 		case Opt_journal_checksum:
-			set_opt (sbi->s_mount_opt, JOURNAL_CHECKSUM);
+			set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
 			break;
 		case Opt_journal_async_commit:
-			set_opt (sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT);
-			set_opt (sbi->s_mount_opt, JOURNAL_CHECKSUM);
+			set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT);
+			set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
 			break;
 		case Opt_noload:
 			set_opt (sbi->s_mount_opt, NOLOAD);
@@ -1295,7 +1295,7 @@ clear_qf_name:
 			clear_opt (sbi->s_mount_opt, EXTENTS);
 			break;
 		case Opt_i_version:
-			set_opt (sbi->s_mount_opt, I_VERSION);
+			set_opt(sbi->s_mount_opt, I_VERSION);
 			sb->s_flags |= MS_I_VERSION;
 			break;
 		case Opt_nodelalloc:
fs/jbd2/journal.c +1 -1
index 1eff534..2a9fde6 100644
@@ -66,7 +66,6 @@ EXPORT_SYMBOL(jbd2_journal_update_format);
 EXPORT_SYMBOL(jbd2_journal_check_used_features);
 EXPORT_SYMBOL(jbd2_journal_check_available_features);
 EXPORT_SYMBOL(jbd2_journal_set_features);
-EXPORT_SYMBOL(jbd2_journal_clear_features);
 EXPORT_SYMBOL(jbd2_journal_create);
 EXPORT_SYMBOL(jbd2_journal_load);
 EXPORT_SYMBOL(jbd2_journal_destroy);
@@ -1606,6 +1605,7 @@ int jbd2_journal_clear_features(journal_t *journal, unsigned long compat,
 
 	return 1;
 }
+EXPORT_SYMBOL(jbd2_journal_clear_features);
 
 /**
  * int jbd2_journal_update_format () - Update on-disk journal structure.
fs/read_write.c +0 -1
index 3fc2cad..dfaee3f 100644
@@ -450,7 +450,6 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
 	}
 	return seg;
 }
-
 EXPORT_SYMBOL(iov_shorten);
 
 ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
include/linux/ext4_fs.h +59 -25

119 lines not on this page · raw message

include/linux/ext4_fs_extents.h +1 -1
index 36b9bb0..56d0ec6 100644
@@ -219,7 +219,7 @@ extern int ext4_ext_try_to_merge(struct inode *inode,
 				 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 struct ext4_ext_path * ext4_ext_find_extent(struct inode *, ext4_lblk_t,
+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 *,
 						ext4_lblk_t *, ext4_fsblk_t *);
include/linux/ext4_fs_sb.h +0 -4
index 3bc6583..abaae2c 100644
@@ -144,9 +144,5 @@ struct ext4_sb_info {
 	/* locality groups */
 	struct ext4_locality_group *s_locality_groups;
 };
-#define EXT4_GROUP_INFO(sb, group)					   \
-	EXT4_SB(sb)->s_group_info[(group) >> EXT4_DESC_PER_BLOCK_BITS(sb)] \
-				 [(group) & (EXT4_DESC_PER_BLOCK(sb) - 1)]
-
 
 #endif	/* _LINUX_EXT4_FS_SB */
include/linux/jbd2.h +1 -2
index 6eed2b4..a2645c2 100644
@@ -162,8 +162,7 @@ typedef struct journal_header_s
 /*
  * Commit block header for storing transactional checksums:
  */
-struct commit_header
-{
+struct commit_header {
 	__be32		h_magic;
 	__be32          h_blocktype;
 	__be32          h_sequence;
#6 lore raw

Re: checkpatch.pl warnings

Quoted 18 lines · Aneesh Kumar K.V
Quoted 4 lines · Mingming Cao

Hi Guys,

Could you check the checkpatch.pl warnings and see if it make sense to fix them? Thanks!

Quoted 12 lines
cmm@kernel:~/fs/ext4/stylecheck$ grep "has style problems" *
linux-2.6.24-rc7-48-bit-i_blocks.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext3-4-migrate.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext4_export_iov_shorten_from_kernel_for_ext4.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext4-journal_chksum-2.6.20.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext4_rec_len_overflow_with_64kblk_fix-v2.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-ext4_store_maxbytes_for_bitmaped_files.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-inode-version-ext4.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-jbd-stats-through-procfs.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-large-file-blocktype.patch.out:Your patch has style problems, please review.  If any of these errors
linux-2.6.24-rc7-mballoc-core.patch.out:Your patch has style problems, please review.  If any of these errors
Quoted 2 lines

Fixed the checkpatch.pl warning for all the patches in the patch queue. The diff is attached below for review.

Thanks!

patch queue has been updated.

Mingming

#7 lore raw

PATCH 1/1 ext4: use ext4_ext_get_actual_len instead of directly using ext4_extent.ee_len

In reply to Eric Sandeen

ext4 use the extent len for encoding whether the extent is intialized or not. The helper function ext4_ext_get_actual_len should be used to get the actual length of the extent.

Fix the below kernel BUG
http://bugzilla.kernel.org/show_bug.cgi?id=9732

kernel BUG at fs/ext4/extents.c:1056!
....

Call Trace:
[<ffffffff88366073>] :ext4dev:ext4_ext_get_blocks+0x5ba/0x8c1
[<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
[<ffffffff812748f6>] _spin_unlock+0x17/0x20
[<ffffffff883400a6>] :jbd2:start_this_handle+0x4e0/0x4fe
[<ffffffff88366564>] :ext4dev:ext4_fallocate+0x175/0x39a
[<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
[<ffffffff81056480>] __lock_acquire+0x4e7/0xc4d
[<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
[<ffffffff810a8de7>] sys_fallocate+0xe4/0x10d
[<ffffffff8100c043>] tracesys+0xd5/0xda
---
 fs/ext4/extents.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)
fs/ext4/extents.c +14 -12
index 81bce98..4269cc6 100644
@@ -1029,7 +1029,7 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 {
 	struct ext4_extent_idx *ix;
 	struct ext4_extent *ex;
-	int depth;
+	int depth, ee_len;
 
 	BUG_ON(path == NULL);
 	depth = path->p_depth;
@@ -1043,6 +1043,7 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 	 * first one in the file */
 
 	ex = path[depth].p_ext;
+	ee_len = ext4_ext_get_actual_len(ex);
 	if (*logical < le32_to_cpu(ex->ee_block)) {
 		BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
 		while (--depth >= 0) {
@@ -1052,10 +1053,10 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 		return 0;
 	}
 
-	BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));
+	BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
 
-	*logical = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1;
-	*phys = ext_pblock(ex) + le16_to_cpu(ex->ee_len) - 1;
+	*logical = le32_to_cpu(ex->ee_block) + ee_len - 1;
+	*phys = ext_pblock(ex) + ee_len - 1;
 	return 0;
 }
 
@@ -1075,7 +1076,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 	struct ext4_extent_idx *ix;
 	struct ext4_extent *ex;
 	ext4_fsblk_t block;
-	int depth;
+	int depth, ee_len;
 
 	BUG_ON(path == NULL);
 	depth = path->p_depth;
@@ -1089,6 +1090,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 	 * first one in the file */
 
 	ex = path[depth].p_ext;
+	ee_len = ext4_ext_get_actual_len(ex);
 	if (*logical < le32_to_cpu(ex->ee_block)) {
 		BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
 		while (--depth >= 0) {
@@ -1100,7 +1102,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 		return 0;
 	}
 
-	BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));
+	BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
 
 	if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
 		/* next allocated block in this leaf */
@@ -1315,7 +1317,7 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
 	if (ext1_ee_len + ext2_ee_len > max_len)
 		return 0;
 #ifdef AGGRESSIVE_TEST
-	if (le16_to_cpu(ex1->ee_len) >= 4)
+	if (ext1_ee_len >= 4)
 		return 0;
 #endif
 
@@ -1555,7 +1557,7 @@ has_space:
 	nearex = path[depth].p_ext;
 	nearex->ee_block = newext->ee_block;
 	ext4_ext_store_pblock(nearex, ext_pblock(newext));
-	nearex->ee_len = newext->ee_len;
+	nearex->ee_len = ext4_ext_get_actual_len(newext);
 
 merge:
 	/* try to merge extents to the right */
@@ -2310,7 +2312,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 				   - le32_to_cpu(newex.ee_block)
 				   + ext_pblock(&newex);
 			/* number of remaining blocks in the extent */
-			allocated = le16_to_cpu(newex.ee_len) -
+			allocated = ext4_ext_get_actual_len(&newex) -
 					(iblock - le32_to_cpu(newex.ee_block));
 			goto out;
 		} else {
@@ -2426,7 +2428,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 	newex.ee_len = cpu_to_le16(max_blocks);
 	err = ext4_ext_check_overlap(inode, &newex, path);
 	if (err)
-		allocated = le16_to_cpu(newex.ee_len);
+		allocated = ext4_ext_get_actual_len(&newex);
 	else
 		allocated = max_blocks;
 
@@ -2458,7 +2460,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 		 * but otherwise we'd need to call it every free() */
 		ext4_mb_discard_inode_preallocations(inode);
 		ext4_free_blocks(handle, inode, ext_pblock(&newex),
-					le16_to_cpu(newex.ee_len), 0);
+					ext4_ext_get_actual_len(&newex), 0);
 		goto out2;
 	}
 
@@ -2467,7 +2469,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 
 	/* previous routine could use block we allocated */
 	newblock = ext_pblock(&newex);
-	allocated = le16_to_cpu(newex.ee_len);
+	allocated = ext4_ext_get_actual_len(&newex);
 outnew:
 	__set_bit(BH_New, &bh_result->b_state);
 
Signature · 1 line
1.5.4.rc2.60.gb2e62-dirty
#8 lore raw

Re: [PATCH] ext4: use ext4_ext_get_actual_len instead of directly using ext4_extent.ee_len

Quoted 74 lines · Aneesh Kumar K.V
 fs/ext4/extents.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)
fs/ext4/extents.c +9 -7
index 81bce98..4269cc6 100644
@@ -1029,7 +1029,7 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 {
 	struct ext4_extent_idx *ix;
 	struct ext4_extent *ex;
-	int depth;
+	int depth, ee_len;
 
 	BUG_ON(path == NULL);
 	depth = path->p_depth;
@@ -1043,6 +1043,7 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 	 * first one in the file */
 
 	ex = path[depth].p_ext;
+	ee_len = ext4_ext_get_actual_len(ex);
 	if (*logical < le32_to_cpu(ex->ee_block)) {
 		BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
 		while (--depth >= 0) {
@@ -1052,10 +1053,10 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 		return 0;
 	}
 
-	BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));
+	BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
 
-	*logical = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1;
-	*phys = ext_pblock(ex) + le16_to_cpu(ex->ee_len) - 1;
+	*logical = le32_to_cpu(ex->ee_block) + ee_len - 1;
+	*phys = ext_pblock(ex) + ee_len - 1;
 	return 0;
 }
 
@@ -1075,7 +1076,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 	struct ext4_extent_idx *ix;
 	struct ext4_extent *ex;
 	ext4_fsblk_t block;
-	int depth;
+	int depth, ee_len;
 
 	BUG_ON(path == NULL);
 	depth = path->p_depth;
@@ -1089,6 +1090,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 	 * first one in the file */
 
 	ex = path[depth].p_ext;
+	ee_len = ext4_ext_get_actual_len(ex);
 	if (*logical < le32_to_cpu(ex->ee_block)) {
 		BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
 		while (--depth >= 0) {
@@ -1100,7 +1102,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 		return 0;
 	}
 
-	BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));
+	BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
 
 	if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
 		/* next allocated block in this leaf */
@@ -1315,7 +1317,7 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
 	if (ext1_ee_len + ext2_ee_len > max_len)
 		return 0;
 #ifdef AGGRESSIVE_TEST
-	if (le16_to_cpu(ex1->ee_len) >= 4)
+	if (ext1_ee_len >= 4)
 		return 0;
 #endif
 

fs/ext4/extents.c has_space: · line 1563

Quoted 8 lines
fs/ext4/extents.c +1 -1
@@ -1555,7 +1557,7 @@ has_space:
 	nearex = path[depth].p_ext;
 	nearex->ee_block = newext->ee_block;
 	ext4_ext_store_pblock(nearex, ext_pblock(newext));
-	nearex->ee_len = newext->ee_len;
+	nearex->ee_len = ext4_ext_get_actual_len(newext);
 
 merge:
 	/* try to merge extents to the right */

This change is not needed. ext4_ext_try_to_merge check whether the extent is uninitialized or not and zero out the blocks if we are merging.

fs/ext4/extents.c int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, · line 2314

Quoted 4 lines
fs/ext4/extents.c +0 -0
@@ -2310,7 +2312,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 				   - le32_to_cpu(newex.ee_block)
 				   + ext_pblock(&newex);
 			/* number of remaining blocks in the extent */

New patch is attached below.

-aneesh

et4: Get the actual length of extent

From: Aneesh Kumar K.V <[email protected]>

ext4 use the extent len for encoding whether the extent is intialized or not. The helper function ext4_ext_get_actual_len should be used to get the actual length of the extent.

Fix the below kernel BUG
http://bugzilla.kernel.org/show_bug.cgi?id=9732

kernel BUG at fs/ext4/extents.c:1056!
....

Call Trace:
[<ffffffff88366073>] :ext4dev:ext4_ext_get_blocks+0x5ba/0x8c1
[<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
[<ffffffff812748f6>] _spin_unlock+0x17/0x20
[<ffffffff883400a6>] :jbd2:start_this_handle+0x4e0/0x4fe
[<ffffffff88366564>] :ext4dev:ext4_fallocate+0x175/0x39a
[<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
[<ffffffff81056480>] __lock_acquire+0x4e7/0xc4d
[<ffffffff81053c91>] lock_release_holdtime+0x27/0x49
[<ffffffff810a8de7>] sys_fallocate+0xe4/0x10d
[<ffffffff8100c043>] tracesys+0xd5/0xda

---

 fs/ext4/extents.c |   24 +++++++++++++-----------
 1 files changed, 13 insertions(+), 11 deletions(-)
fs/ext4/extents.c +13 -11
index 81bce98..1e46997 100644
@@ -1029,7 +1029,7 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 {
 	struct ext4_extent_idx *ix;
 	struct ext4_extent *ex;
-	int depth;
+	int depth, ee_len;
 
 	BUG_ON(path == NULL);
 	depth = path->p_depth;
@@ -1043,6 +1043,7 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 	 * first one in the file */
 
 	ex = path[depth].p_ext;
+	ee_len = ext4_ext_get_actual_len(ex);
 	if (*logical < le32_to_cpu(ex->ee_block)) {
 		BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
 		while (--depth >= 0) {
@@ -1052,10 +1053,10 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
 		return 0;
 	}
 
-	BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));
+	BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
 
-	*logical = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1;
-	*phys = ext_pblock(ex) + le16_to_cpu(ex->ee_len) - 1;
+	*logical = le32_to_cpu(ex->ee_block) + ee_len - 1;
+	*phys = ext_pblock(ex) + ee_len - 1;
 	return 0;
 }
 
@@ -1075,7 +1076,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 	struct ext4_extent_idx *ix;
 	struct ext4_extent *ex;
 	ext4_fsblk_t block;
-	int depth;
+	int depth, ee_len;
 
 	BUG_ON(path == NULL);
 	depth = path->p_depth;
@@ -1089,6 +1090,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 	 * first one in the file */
 
 	ex = path[depth].p_ext;
+	ee_len = ext4_ext_get_actual_len(ex);
 	if (*logical < le32_to_cpu(ex->ee_block)) {
 		BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
 		while (--depth >= 0) {
@@ -1100,7 +1102,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 		return 0;
 	}
 
-	BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));
+	BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
 
 	if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
 		/* next allocated block in this leaf */
@@ -1315,7 +1317,7 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
 	if (ext1_ee_len + ext2_ee_len > max_len)
 		return 0;
 #ifdef AGGRESSIVE_TEST
-	if (le16_to_cpu(ex1->ee_len) >= 4)
+	if (ext1_ee_len >= 4)
 		return 0;
 #endif
 
@@ -2310,7 +2312,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 				   - le32_to_cpu(newex.ee_block)
 				   + ext_pblock(&newex);
 			/* number of remaining blocks in the extent */
-			allocated = le16_to_cpu(newex.ee_len) -
+			allocated = ext4_ext_get_actual_len(&newex) -
 					(iblock - le32_to_cpu(newex.ee_block));
 			goto out;
 		} else {
@@ -2426,7 +2428,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 	newex.ee_len = cpu_to_le16(max_blocks);
 	err = ext4_ext_check_overlap(inode, &newex, path);
 	if (err)
-		allocated = le16_to_cpu(newex.ee_len);
+		allocated = ext4_ext_get_actual_len(&newex);
 	else
 		allocated = max_blocks;
 
@@ -2458,7 +2460,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 		 * but otherwise we'd need to call it every free() */
 		ext4_mb_discard_inode_preallocations(inode);
 		ext4_free_blocks(handle, inode, ext_pblock(&newex),
-					le16_to_cpu(newex.ee_len), 0);
+					ext4_ext_get_actual_len(&newex), 0);
 		goto out2;
 	}
 
@@ -2467,7 +2469,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 
 	/* previous routine could use block we allocated */
 	newblock = ext_pblock(&newex);
-	allocated = le16_to_cpu(newex.ee_len);
+	allocated = ext4_ext_get_actual_len(&newex);
 outnew:
 	__set_bit(BH_New, &bh_result->b_state);