New: oops in extent code via ext4_fallocate]
Subsystems (3)
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.
Quoted 11 lines · Eric Sandeen
The
BUG_ONis: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 32776Haven'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
Quoted 22 lines · Aneesh Kumar K.V
Quoted 10 lines · Eric Sandeen
The
BUG_ONis: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 32776Haven't looked further into it yet.
Not able to reproduce. Why is it calling
ext4_ext_search_leftfor that value of logical ?ext4_ext_get_blocksshould have found that the logical belong to an already existing extent and return from there. It should have returned from2365 if (create ==
EXT4_CREATE_UNINITIALIZED_EXT)
2366 goto out;
Quoted 5 lines
root@qemu-image:/ext4# /root/testfallocate -f a 0 100root@qemu-image:/ext4# /root/truncate ./a 50root@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
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]
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_64fsx_linux, fs_inode, fsstress on ppc64
fs/ext4/extents.c +8 -6
@@ -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
@@ -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
@@ -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
@@ -144,8 +144,8 @@ struct dx_map_entryu16 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
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
PATCH 1/1 ext4: use ext4_ext_get_actual_len instead of directly using ext4_extent.ee_len
In reply to Eric Sandeenext4 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
@@ -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
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@@ -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
@@ -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);