diff options
author | Wengang Wang <wen.gang.wang@oracle.com> | 2014-04-03 17:47:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-03 19:20:57 -0400 |
commit | 9c339255cb01806efbaec3d296f3e44c9357d574 (patch) | |
tree | b3585e2ce1ee94516d8aa7cf00bc280526be925b /fs/ocfs2/xattr.c | |
parent | 43b10a20372d9a1c08391f33f1c8bd86179ddc5f (diff) |
ocfs2: pass "new" parameter to ocfs2_init_xattr_bucket
This patch fixes the following crash:
kernel BUG at fs/ocfs2/uptodate.c:530!
Modules linked in: ocfs2(F) ocfs2_dlmfs ocfs2_stack_o2cb ocfs2_dlm ocfs2_nodemanager ocfs2_stackglue configfs bridge xen_pciback xen_netback xen_blkback xen_gntalloc xen_gntdev xen_evtchn xenfs xen_privcmd sunrpc 8021q garp stp llc bonding be2iscsi iscsi_boot_sysfs bnx2i cnic uio cxgb4i cxgb4 cxgb3i libcxgbi cxgb3 mdio ib_iser rdma_cm ib_cm iw_cm ib_sa ib_mad ib_core ib_addr ipv6 iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi iTCO_wdt iTCO_vendor_support dcdbas coretemp freq_table mperf microcode pcspkr serio_raw bnx2 lpc_ich mfd_core i5k_amb i5000_edac edac_core e1000e sg shpchp ext4(F) jbd2(F) mbcache(F) dm_round_robin(F) sr_mod(F) cdrom(F) usb_storage(F) sd_mod(F) crc_t10dif(F) pata_acpi(F) ata_generic(F) ata_piix(F) mptsas(F) mptscsih(F) mptbase(F) scsi_transport_sas(F) radeon(F)
ttm(F) drm_kms_helper(F) drm(F) hwmon(F) i2c_algo_bit(F) i2c_core(F) dm_multipath(F) dm_mirror(F) dm_region_hash(F) dm_log(F) dm_mod(F)
CPU 5
Pid: 21303, comm: xattr-test Tainted: GF W 3.8.13-30.el6uek.x86_64 #2 Dell Inc. PowerEdge 1950/0M788G
RIP: ocfs2_set_new_buffer_uptodate+0x51/0x60 [ocfs2]
Process xattr-test (pid: 21303, threadinfo ffff880017aca000, task ffff880016a2c480)
Call Trace:
ocfs2_init_xattr_bucket+0x8a/0x120 [ocfs2]
ocfs2_cp_xattr_bucket+0xbb/0x1b0 [ocfs2]
ocfs2_extend_xattr_bucket+0x20a/0x2f0 [ocfs2]
ocfs2_add_new_xattr_bucket+0x23e/0x4b0 [ocfs2]
ocfs2_xattr_set_entry_index_block+0x13c/0x3d0 [ocfs2]
ocfs2_xattr_block_set+0xf9/0x220 [ocfs2]
__ocfs2_xattr_set_handle+0x118/0x710 [ocfs2]
ocfs2_xattr_set+0x691/0x880 [ocfs2]
ocfs2_xattr_user_set+0x46/0x50 [ocfs2]
generic_setxattr+0x96/0xa0
__vfs_setxattr_noperm+0x7b/0x170
vfs_setxattr+0xbc/0xc0
setxattr+0xde/0x230
sys_fsetxattr+0xc6/0xf0
system_call_fastpath+0x16/0x1b
Code: 41 80 0c 24 01 48 89 df e8 7d f0 ff ff 4c 89 e6 48 89 df e8 a2 fe ff ff 48 89 df e8 3a f0 ff ff 48 8b 1c 24 4c 8b 64 24 08 c9 c3 <0f> 0b eb fe 90 90 90 90 90 90 90 90 90 90 90 55 48 89 e5 66 66
RIP ocfs2_set_new_buffer_uptodate+0x51/0x60 [ocfs2]
It hit the BUG_ON() in ocfs2_set_new_buffer_uptodate():
void ocfs2_set_new_buffer_uptodate(struct ocfs2_caching_info *ci,
struct buffer_head *bh)
{
/* This should definitely *not* exist in our cache */
if (ocfs2_buffer_cached(ci, bh))
printk(KERN_ERR "bh->b_blocknr: %lu @ %p\n", bh->b_blocknr, bh);
BUG_ON(ocfs2_buffer_cached(ci, bh));
set_buffer_uptodate(bh);
ocfs2_metadata_cache_io_lock(ci);
ocfs2_set_buffer_uptodate(ci, bh);
ocfs2_metadata_cache_io_unlock(ci);
}
The problem here is:
We cached a block, but the buffer_head got reused. When we are to pick
up this block again, a new buffer_head created with UPTODATE flag
cleared. ocfs2_buffer_uptodate() returned false since no UPTODATE is
set on the buffer_head. so we set this block to cache as a NEW block,
then it failed at asserting block is not in cache.
The fix is to add a new parameter indicating the bucket is a new
allocated or not to ocfs2_init_xattr_bucket().
ocfs2_init_xattr_bucket() assert block not cached accordingly.
Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
Cc: Joel Becker <jlbec@evilplan.org>
Reviewed-by: Mark Fasheh <mfasheh@suse.de>
Cc: Joe Jin <joe.jin@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r-- | fs/ocfs2/xattr.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 14b8c46b4fbb..016f01df3825 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -369,7 +369,7 @@ static void ocfs2_xattr_bucket_free(struct ocfs2_xattr_bucket *bucket) | |||
369 | * them fully. | 369 | * them fully. |
370 | */ | 370 | */ |
371 | static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket, | 371 | static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket, |
372 | u64 xb_blkno) | 372 | u64 xb_blkno, int new) |
373 | { | 373 | { |
374 | int i, rc = 0; | 374 | int i, rc = 0; |
375 | 375 | ||
@@ -383,9 +383,16 @@ static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket, | |||
383 | } | 383 | } |
384 | 384 | ||
385 | if (!ocfs2_buffer_uptodate(INODE_CACHE(bucket->bu_inode), | 385 | if (!ocfs2_buffer_uptodate(INODE_CACHE(bucket->bu_inode), |
386 | bucket->bu_bhs[i])) | 386 | bucket->bu_bhs[i])) { |
387 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(bucket->bu_inode), | 387 | if (new) |
388 | bucket->bu_bhs[i]); | 388 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(bucket->bu_inode), |
389 | bucket->bu_bhs[i]); | ||
390 | else { | ||
391 | set_buffer_uptodate(bucket->bu_bhs[i]); | ||
392 | ocfs2_set_buffer_uptodate(INODE_CACHE(bucket->bu_inode), | ||
393 | bucket->bu_bhs[i]); | ||
394 | } | ||
395 | } | ||
389 | } | 396 | } |
390 | 397 | ||
391 | if (rc) | 398 | if (rc) |
@@ -4303,7 +4310,7 @@ static int ocfs2_xattr_create_index_block(struct inode *inode, | |||
4303 | 4310 | ||
4304 | trace_ocfs2_xattr_create_index_block((unsigned long long)blkno); | 4311 | trace_ocfs2_xattr_create_index_block((unsigned long long)blkno); |
4305 | 4312 | ||
4306 | ret = ocfs2_init_xattr_bucket(xs->bucket, blkno); | 4313 | ret = ocfs2_init_xattr_bucket(xs->bucket, blkno, 1); |
4307 | if (ret) { | 4314 | if (ret) { |
4308 | mlog_errno(ret); | 4315 | mlog_errno(ret); |
4309 | goto out; | 4316 | goto out; |
@@ -4647,7 +4654,7 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, | |||
4647 | * Even if !new_bucket_head, we're overwriting t_bucket. Thus, | 4654 | * Even if !new_bucket_head, we're overwriting t_bucket. Thus, |
4648 | * there's no need to read it. | 4655 | * there's no need to read it. |
4649 | */ | 4656 | */ |
4650 | ret = ocfs2_init_xattr_bucket(t_bucket, new_blk); | 4657 | ret = ocfs2_init_xattr_bucket(t_bucket, new_blk, new_bucket_head); |
4651 | if (ret) { | 4658 | if (ret) { |
4652 | mlog_errno(ret); | 4659 | mlog_errno(ret); |
4653 | goto out; | 4660 | goto out; |
@@ -4813,7 +4820,7 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode, | |||
4813 | * Even if !t_is_new, we're overwriting t_bucket. Thus, | 4820 | * Even if !t_is_new, we're overwriting t_bucket. Thus, |
4814 | * there's no need to read it. | 4821 | * there's no need to read it. |
4815 | */ | 4822 | */ |
4816 | ret = ocfs2_init_xattr_bucket(t_bucket, t_blkno); | 4823 | ret = ocfs2_init_xattr_bucket(t_bucket, t_blkno, t_is_new); |
4817 | if (ret) | 4824 | if (ret) |
4818 | goto out; | 4825 | goto out; |
4819 | 4826 | ||
@@ -6840,7 +6847,7 @@ static int ocfs2_reflink_xattr_bucket(handle_t *handle, | |||
6840 | break; | 6847 | break; |
6841 | } | 6848 | } |
6842 | 6849 | ||
6843 | ret = ocfs2_init_xattr_bucket(args->new_bucket, new_blkno); | 6850 | ret = ocfs2_init_xattr_bucket(args->new_bucket, new_blkno, 1); |
6844 | if (ret) { | 6851 | if (ret) { |
6845 | mlog_errno(ret); | 6852 | mlog_errno(ret); |
6846 | break; | 6853 | break; |