do R/W tests on JFFS2 and suffer segmentation fault
Robert Liu
robertliu at wiscore.com
Mon Feb 20 20:17:26 EST 2006
Hi, All:
I am doing some read/write tests on JFFS2 partition, and find there may be
a bug in jffs2_remove_from_hash_table().
My platform is Intel IXP-based board with 32MB NAND flash.
The testing script is:
[code]
#!/bin/sh
START=`date`
it=1
run=1000
while [ $it -le $run ]; do
echo "#$it (`date`)"
dd if=/dev/mem of=data bs=4k count=1280
sleep 1
sync
# md5sum data
dd if=data of=/dev/null
sleep 1
rm -f data
sync
sleep 1
it=`expr "$it" + 1`
done
echo "START: $START"
echo " END: `date`"
[/code]
Tests sometimes failed with segmentation fault.
I set the JFFS2 debug level to 1, and add several debug infomation in
jffs2_remove_from_hash_table().
It seems jffs2 try to remove an entry with prev is 0x200200 and next is
0x100100.
the modification of jffs2_remove_from_hash_table()
void jffs2_remove_from_hash_table(struct jffs2_sb_info *c, struct
jffs2_eraseblock *jeb, uint8_t flag)
{
struct jffs2_blocks_bucket *hash_table;
uint32_t index, *current_index_p, i;
if (flag == 1) {
hash_table = c->used_blocks;
current_index_p = &(c->used_blocks_current_index);
D1(printk(KERN_DEBUG "c: %X, jeb: %X, index: %d\n",
(int) c, (int) jeb, (jeb->erase_count >> BUCKET_RANGE_BIT_LEN)););
D1(printk(KERN_DEBUG "hash_table: %X, curr_index_p:
%X(%d)\n", (int) hash_table, (int) current_index_p, *current_index_p););
D1(index = (jeb->erase_count >> BUCKET_RANGE_BIT_LEN););
D1(printk(KERN_DEBUG "index: %d, num: %d, hash_list:
%X\n", index, hash_table[index].number, (int) &jeb->hash_list););
D1(printk(KERN_DEBUG "prev_entry: %X,
next_entry:%X\n",(int) ((struct list_head *) (&jeb->hash_list))->prev,
(int) ((struct list_head *) (&jeb->hash_list))->next););
}else if (flag == 2) {
hash_table = c->free_blocks;
current_index_p = &(c->free_blocks_current_index);
}else {
return;
}
index = (jeb->erase_count >> BUCKET_RANGE_BIT_LEN);
if (index >= HASH_SIZE) {
return;
}
hash_table[index].number--;
list_del(&jeb->hash_list);
if (hash_table[index].number == 0) {
for (i = index + 1; i < HASH_SIZE; i++) {
D1(if (flag == 1) printk(KERN_DEBUG "i: %d,
table[i].number: %d\n", i, hash_table[i].number););
if (hash_table[i].number != 0) {
*current_index_p = i;
break;
}
}
if (i == HASH_SIZE) {
*current_index_p = HASH_SIZE;
}
D1(if (flag == 1) printk(KERN_DEBUG "i: %d,
curr_index_p: %d\n", i, *current_index_p););
}
return;
}
I past some of the kernel log. If more infomation is needed, please tell me.
[log]
Feb 20 17:16:05 kernel: jffs2_reserve_space(): Requested 0x2c bytes
Feb 20 17:16:05 kernel: jffs2_reserve_space(): alloc sem got
Feb 20 17:16:05 kernel: [JFFS2 DBG] (818) jffs2_do_reserve_space:
minsize=44 , jeb->free=1024 ,summary->size=72 , sumsize=28
Feb 20 17:16:05 kernel: jffs2_do_reserve_space(): Giving 0x374 bytes at
0x417c00
Feb 20 17:16:05 kernel: jffs2_write_dirent(ino #1, name at *0xc02f5fd0
"data"->ino #0, name_crc 0x8cb72c7f)
Feb 20 17:16:05 kernel: [JFFS2 DBG] (818) jffs2_sum_add_mem: dirent (0)
added to summary
Feb 20 17:16:05 kernel: jffs2_add_physical_node_ref(): Node at
0x417c00(2), size 0x2c
Feb 20 17:16:05 kernel: [JFFS2 DBG] (818) jffs2_add_fd_to_list: add
dirent "data", ino #0
Feb 20 17:16:05 kernel: [JFFS2 DBG] (818) jffs2_add_fd_to_list: marking
old dirent "data", ino #63 bsolete
Feb 20 17:16:05 kernel: Obsoleting node at 0x0094e844 of len 0x2c:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x0094c000 not moved anywhere.
(free 0x00000000, dirty 0x0000268c, used 0x00001974)
Feb 20 17:16:05 kernel: jffs2_complete_reservation()
Feb 20 17:16:05 kernel: jffs2_thread_should_wake(): nr_free_blocks 1417,
nr_erasing_blocks 1, dirty_size 0x4907b0: no
Feb 20 17:16:05 kernel: jffs2_clear_inode(): ino #63 mode 100644
Feb 20 17:16:05 kernel: [JFFS2 DBG] (818) jffs2_kill_fragtree: killing
Feb 20 17:16:05 kernel: Obsoleting node at 0x0094e870 of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x0094c000 not moved anywhere.
(free 0x00000000, dirty 0x000036d0, used 0x00000930)
Feb 20 17:16:05 kernel: Obsoleting node at 0x00948000 of len 0xa38:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00948000 is freshly dirtied.
Removing from clean list...
Feb 20 17:16:05 kernel: ...and adding to dirty_list
Feb 20 17:16:05 kernel: Obsoleting node at 0x0094f8b4 of len 0x650:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x0094c000 not moved anywhere.
(free 0x00000000, dirty 0x00003d20, used 0x000002e0)
Feb 20 17:16:05 kernel: Obsoleting node at 0x00949a7c of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00948000 not moved anywhere.
(free 0x00000000, dirty 0x00001a7c, used 0x00002584)
Feb 20 17:16:05 kernel: Obsoleting node at 0x0094bb04 of len 0x478:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00948000 not moved anywhere.
(free 0x00000000, dirty 0x00001ef4, used 0x0000210c)
Feb 20 17:16:05 kernel: Obsoleting node at 0x0094aac0 of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00948000 is now very dirty.
Removing from dirty list...
Feb 20 17:16:05 kernel: ...and adding to very_dirty_list
Feb 20 17:16:05 kernel: Obsoleting node at 0x00948a38 of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00948000 not moved anywhere.
(free 0x00000000, dirty 0x00003f7c, used 0x00000084)
Feb 20 17:16:05 kernel: Obsoleting node at 0x00944c10 of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00944000 is freshly dirtied.
Removing from clean list...
Feb 20 17:16:05 kernel: ...and adding to dirty_list
Feb 20 17:16:05 kernel: Obsoleting node at 0x00946c98 of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00944000 is now very dirty.
Removing from dirty list...
Feb 20 17:16:05 kernel: ...and adding to very_dirty_list
Feb 20 17:16:05 kernel: Obsoleting node at 0x00945c54 of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00944000 not moved anywhere.
(free 0x00000000, dirty 0x000030cc, used 0x00000f34)
Feb 20 17:16:05 kernel: Obsoleting node at 0x00940000 of len 0xde8:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00940000 is freshly dirtied.
Removing from clean list...
Feb 20 17:16:05 kernel: ...and adding to dirty_list
Feb 20 17:16:05 kernel: Obsoleting node at 0x00941e2c of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00940000 not moved anywhere.
(free 0x00000000, dirty 0x00001e2c, used 0x000021d4)
Feb 20 17:16:05 kernel: Obsoleting node at 0x00940de8 of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00940000 is now very dirty.
Removing from dirty list...
Feb 20 17:16:05 kernel: ...and adding to very_dirty_list
Feb 20 17:16:05 kernel: Obsoleting node at 0x00947cdc of len 0x2a0:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00944000 not moved anywhere.
(free 0x00000000, dirty 0x0000336c, used 0x00000c94)
Feb 20 17:16:05 kernel: Obsoleting node at 0x00944000 of len 0xc10:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00944000 not moved anywhere.
(free 0x00000000, dirty 0x00003f7c, used 0x00000084)
Feb 20 17:16:05 kernel: Obsoleting node at 0x00943eb4 of len 0xc8:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00940000 not moved anywhere.
(free 0x00000000, dirty 0x00002f38, used 0x000010c8)
Feb 20 17:16:05 kernel: Obsoleting node at 0x00938000 of len 0x1044:
<7>Dirtying
Feb 20 17:16:05 kernel: Eraseblock at 0x00938000 is freshly dirtied.
Removing from clean list...
Feb 20 17:16:05 kernel: ...and adding to dirty_list
Feb 20 17:16:05 kernel: Obsoleting node at 0x0093c000 of len 0xfc0:
<7>Dirtying
Feb 20 17:16:05 kernel: c1f9a948 is on list at c1a800d8
Feb 20 17:16:05 kernel: Leaving block at 0093c000 on the bad_used_list
Feb 20 17:16:05 kernel: Eraseblock at 0x0093c000 completely dirtied.
Removing from (dirty?) list...
Feb 20 17:16:05 kernel: c: C1A80000, jeb: C1F9A948, index: 0
Feb 20 17:16:05 kernel: hash_table: C1A80150, curr_index_p: C1A80148(0)
Feb 20 17:16:05 kernel: index: 0, num: 620, hash_list: C1F9A950
Feb 20 17:16:05 kernel: prev_entry: 200200, next_entry:100100
Feb 20 17:16:05 kernel: Unable to handle kernel paging request at
virtual address 00200200
Feb 20 17:16:05 kernel: pgd = c1e48000
Feb 20 17:16:05 kernel: [00200200] *pgd=00000000
Feb 20 17:16:05 kernel: Internal error: Oops: 8f5 [#1]
Feb 20 17:16:05 kernel: Modules linked in:
Feb 20 17:16:05 kernel: CPU: 0
Feb 20 17:16:05 kernel: PC is at jffs2_remove_from_hash_table+0x88/0x198
Feb 20 17:16:05 kernel: LR is at 0xc
Feb 20 17:16:05 kernel: pc : [<c010fea0>] lr : [<0000000c>] Not
tainted
Feb 20 17:16:05 kernel: sp : c1c97e50 ip : 00000000 fp : c1c97e78
Feb 20 17:16:05 kernel: r10: 000001ff r9 : c1a80148 r8 : c1f9a950
Feb 20 17:16:05 kernel: r7 : 00000001 r6 : c1a80150 r5 : c1f9a948 r4
: 00000000
Feb 20 17:16:05 kernel: r3 : 00100100 r2 : 00100100 r1 : 00200200 r0
: 00200200
Feb 20 17:16:05 kernel: Flags: nZCv IRQs on FIQs on Mode SVC_32
Segment user
Feb 20 17:16:05 kernel: Control: 39FF Table: 01E48000 DAC: 00000015
Feb 20 17:16:05 kernel: Process rm (pid: 818, stack limit = 0xc1c96190)
Feb 20 17:16:05 kernel: Stack: (0xc1c97e50 to 0xc1c98000)
Feb 20 17:16:05 kernel: 7e40:
0093c003 00000fc0 c1f9a948 c1a80000
Feb 20 17:16:05 kernel: 7e60: c17f2704 00000000 00000000 c1c97ebc
c1c97e7c c0101a44 c010fe24 c1c96000
Feb 20 17:16:05 kernel: 7e80: c1fcb854 00000000 000002cc d62f2d80
c1fcb480 c198924c c198924c c1c96000
Feb 20 17:16:05 kernel: 7ea0: c1a80000 00000000 c1c96000 4021a000
c1c97ee0 c1c97ec0 c0100694 c01016b0
Feb 20 17:16:05 kernel: 7ec0: 00000001 c1a36190 c1a80000 c1c97f44
c02f5f6c c1c97efc c1c97ee4 c0102bdc
Feb 20 17:16:05 kernel: 7ee0: c01005e8 c1a361bc 00000000 c1a361bc
c1c97f10 c1c97f00 c00bdff8 c0102b54
Feb 20 17:16:05 kernel: 7f00: c1a361bc c1c97f28 c1c97f14 c00bf23c
c00bdf00 c1a361bc c02069f0 c1c97f40
Feb 20 17:16:05 kernel: 7f20: c1c97f2c c00be4b8 c00bf168 c1c20000
00000000 c1c97fa4 c1c97f44 c00b48fc
Feb 20 17:16:05 kernel: 7f40: c00be438 c02f55dc c02d4ba0 018a2149
00000004 c1c20000 00000010 00000000
Feb 20 17:16:05 kernel: 7f60: 00000000 c1c97fac c1c97f74 c005a26c
c011f09c 00000000 c00504ac c1c97fb0
Feb 20 17:16:05 kernel: 7f80: 00000000 00000001 00000008 beffff90
0000000a c00538c4 00000000 c1c97fa8
Feb 20 17:16:05 kernel: 7fa0: c0053740 c00b47d0 00000001 c005a170
beffff90 0000003f 0000003f 00000001
Feb 20 17:16:05 kernel: 7fc0: 00000001 00000008 beffff90 00000003
befffed4 000b6854 4021a000 0000cb6c
Feb 20 17:16:05 kernel: 7fe0: 401b7fb0 befffe00 0008a860 401b7fb4
60000010 beffff90 00000000 00000000
Feb 20 17:16:05 kernel: Backtrace:
Feb 20 17:16:05 kernel: [<c010fe18>]
(jffs2_remove_from_hash_table+0x0/0x198) from [<c0101a44>]
(jffs2_mark_node_obsolete+0x3a0/0xa40)
Feb 20 17:16:05 kernel: [<c01016a4>]
(jffs2_mark_node_obsolete+0x0/0xa40) from [<c0100694>]
(jffs2_kill_fragtree+0xb8/0x104)
Feb 20 17:16:05 kernel: [<c01005dc>] (jffs2_kill_fragtree+0x0/0x104)
from [<c0102bdc>] (jffs2_do_clear_inode+0x94/0x14c)
Feb 20 17:16:05 kernel: r8 = C02F5F6C r7 = C1C97F44 r6 = C1A80000 r5
= C1A36190
Feb 20 17:16:05 kernel: r4 = 00000001
Feb 20 17:16:05 kernel: [<c0102b48>] (jffs2_do_clear_inode+0x0/0x14c)
from [<c00bdff8>] (clear_inode+0x104/0x110)
Feb 20 17:16:05 kernel: r6 = C1A361BC r5 = 00000000 r4 = C1A361BC
Feb 20 17:16:05 kernel: [<c00bdef4>] (clear_inode+0x0/0x110) from
[<c00bf23c>] (generic_delete_inode+0xe0/0x100)
Feb 20 17:16:05 kernel: r4 = C1A361BC
Feb 20 17:16:05 kernel: [<c00bf15c>] (generic_delete_inode+0x0/0x100)
from [<c00be4b8>] (iput+0x8c/0xc0)
Feb 20 17:16:05 kernel: r5 = C02069F0 r4 = C1A361BC
Feb 20 17:16:05 kernel: [<c00be42c>] (iput+0x0/0xc0) from [<c00b48fc>]
(sys_unlink+0x138/0x184)
Feb 20 17:16:05 kernel: r5 = 00000000 r4 = C1C20000
Feb 20 17:16:05 kernel: [<c00b47c4>] (sys_unlink+0x0/0x184) from
[<c0053740>] (ret_fast_syscall+0x0/0x2c)
Feb 20 17:16:05 kernel: r8 = C00538C4 r7 = 0000000A r6 = BEFFFF90 r5
= 00000008
Feb 20 17:16:05 kernel: r4 = 00000001
Feb 20 17:16:05 kernel: Code: e78c3006 e5953008 e5980004 e2811c02
(e5803000)
Feb 20 17:16:05 kernel: <7>jffs2_write_super()
Feb 20 17:16:05 kernel: jffs2_thread_should_wake(): nr_free_blocks 1417,
nr_erasing_blocks 1, dirty_size 0x49ec78: no
Feb 20 17:16:05 kernel: Starting erase of pending block 0x008bc000
Feb 20 17:16:05 kernel: Freeing all node refs for eraseblock offset
0x008bc000
Feb 20 17:16:05 kernel: Removed nodes in range 0x008bc000-0x008c0000
from ino #63
Feb 20 17:16:05 kernel: jffs2_erase_block(): erase block 0x8bc000 (range
0x8bc000-0x8c0000)
Feb 20 17:16:05 kernel: Erase completed successfully at 0x008bc000
Feb 20 17:16:05 kernel: Verifying erase at 0x008bc000
Feb 20 17:16:05 kernel: Writing eraseblock header to block at 0x008bc000
Feb 20 17:16:05 kernel: jffs2_erase_pending_blocks completed
Feb 20 17:16:05 kernel: jffs2_flush_wbuf_gc() called for ino #0...
Feb 20 17:16:05 kernel: jffs2_flush_wbuf_gc() calls gc pass
Feb 20 17:16:05 kernel: Picking block from bad_used_list to GC next
Feb 20 17:16:05 kernel: Converting wasted_size 00003e3c to dirty_size
Feb 20 17:16:05 kernel: GC from block 008cc000, used_size 000001c4,
dirty_size 00003e3c, free_size 00000000
Feb 20 17:16:05 kernel: Nextblock at 00414000, used_size 00003bf4,
dirty_size 00000000, wasted_size 00000038, free_size 000003d4
Feb 20 17:16:05 kernel: Going to garbage collect node at 0x008cc000
Feb 20 17:16:05 kernel: jffs2_garbage_collect_pass collecting from block
@0x008cc000. Node @0x008cc000(3), ino #63
[/log]
finally, sorry for my poor English.
Regards,
Robert
More information about the linux-mtd
mailing list