diff options
author | Sage Weil <sage@newdream.net> | 2010-02-26 12:37:33 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-26 12:37:33 -0500 |
commit | c99eb1c7263a44e63161a041a778b345b5cf0b6a (patch) | |
tree | 7c1a303b30e8aadc0514af07748d25efd7fb2669 /fs/ceph/osd_client.c | |
parent | e80a52d14f868059e8ec790c9fae88cdb8a1df98 (diff) |
ceph: remove fragile __map_osds optimization
We used to try to avoid freeing and then reallocating the osd
struct. This is a bit fragile due to potential interactions with
other references (beyond o_requests), and may be the cause of
this crash:
[120633.442358] BUG: unable to handle kernel NULL pointer dereference at (null)
[120633.443292] IP: [<ffffffff812549b6>] rb_erase+0x11d/0x277
[120633.443292] PGD f7ff3067 PUD f7f53067 PMD 0
[120633.443292] Oops: 0000 [#1] PREEMPT SMP
[120633.443292] last sysfs file: /sys/kernel/uevent_seqnum
[120633.443292] CPU 1
[120633.443292] Modules linked in: ceph fan ac battery psmouse ehci_hcd ide_pci_generic ohci_hcd thermal processor button
[120633.443292] Pid: 3023, comm: ceph-msgr/1 Not tainted 2.6.32-rc2 #12 H8SSL
[120633.443292] RIP: 0010:[<ffffffff812549b6>] [<ffffffff812549b6>] rb_erase+0x11d/0x277
[120633.443292] RSP: 0018:ffff8800f7b13a50 EFLAGS: 00010246
[120633.443292] RAX: ffff880022907819 RBX: ffff880022907818 RCX: 0000000000000000
[120633.443292] RDX: ffff8800f7b13a80 RSI: ffff8800f587eb48 RDI: 0000000000000000
[120633.443292] RBP: ffff8800f7b13a60 R08: 0000000000000000 R09: 0000000000000004
[120633.443292] R10: 0000000000000000 R11: ffff8800c4441000 R12: ffff8800f587eb48
[120633.443292] R13: ffff8800f58eaa00 R14: ffff8800f413c000 R15: 0000000000000001
[120633.443292] FS: 00007fbef6e226e0(0000) GS:ffff880009200000(0000) knlGS:0000000000000000
[120633.443292] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
[120633.443292] CR2: 0000000000000000 CR3: 00000000f7c53000 CR4: 00000000000006e0
[120633.443292] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[120633.443292] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[120633.443292] Process ceph-msgr/1 (pid: 3023, threadinfo ffff8800f7b12000, task ffff8800f5858b40)
[120633.443292] Stack:
[120633.443292] ffff8800f413c000 ffff8800f587e9c0 ffff8800f7b13a80 ffffffffa0098a86
[120633.443292] <0> 00000000000006f1 0000000000000000 ffff8800f7b13af0 ffffffffa009959b
[120633.443292] <0> ffff8800f413c000 ffff880022a68400 ffff880022a68400 ffff8800f587e9c0
[120633.443292] Call Trace:
[120633.443292] [<ffffffffa0098a86>] __remove_osd+0x4d/0xbc [ceph]
[120633.443292] [<ffffffffa009959b>] __map_osds+0x199/0x4fa [ceph]
[120633.443292] [<ffffffffa00999f4>] ? __send_request+0xf8/0x186 [ceph]
[120633.443292] [<ffffffffa0099beb>] kick_requests+0x169/0x3cb [ceph]
[120633.443292] [<ffffffffa009a8c1>] ceph_osdc_handle_map+0x370/0x522 [ceph]
Since we're probably screwed anyway if a small kmalloc is
failing, don't bother with trying to be clever here.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/osd_client.c')
-rw-r--r-- | fs/ceph/osd_client.c | 21 |
1 files changed, 4 insertions, 17 deletions
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index ffd819c5a5dd..3a631f27cc9e 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c | |||
@@ -615,7 +615,6 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
615 | struct ceph_pg pgid; | 615 | struct ceph_pg pgid; |
616 | int o = -1; | 616 | int o = -1; |
617 | int err; | 617 | int err; |
618 | struct ceph_osd *newosd = NULL; | ||
619 | 618 | ||
620 | dout("map_osds %p tid %lld\n", req, req->r_tid); | 619 | dout("map_osds %p tid %lld\n", req, req->r_tid); |
621 | err = ceph_calc_object_layout(&reqhead->layout, req->r_oid, | 620 | err = ceph_calc_object_layout(&reqhead->layout, req->r_oid, |
@@ -639,25 +638,15 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
639 | if (req->r_osd) { | 638 | if (req->r_osd) { |
640 | __cancel_request(req); | 639 | __cancel_request(req); |
641 | list_del_init(&req->r_osd_item); | 640 | list_del_init(&req->r_osd_item); |
642 | if (list_empty(&req->r_osd->o_requests)) { | ||
643 | /* try to re-use r_osd if possible */ | ||
644 | newosd = get_osd(req->r_osd); | ||
645 | __remove_osd(osdc, newosd); | ||
646 | } | ||
647 | req->r_osd = NULL; | 641 | req->r_osd = NULL; |
648 | } | 642 | } |
649 | 643 | ||
650 | req->r_osd = __lookup_osd(osdc, o); | 644 | req->r_osd = __lookup_osd(osdc, o); |
651 | if (!req->r_osd && o >= 0) { | 645 | if (!req->r_osd && o >= 0) { |
652 | if (newosd) { | 646 | err = -ENOMEM; |
653 | req->r_osd = newosd; | 647 | req->r_osd = create_osd(osdc); |
654 | newosd = NULL; | 648 | if (!req->r_osd) |
655 | } else { | 649 | goto out; |
656 | err = -ENOMEM; | ||
657 | req->r_osd = create_osd(osdc); | ||
658 | if (!req->r_osd) | ||
659 | goto out; | ||
660 | } | ||
661 | 650 | ||
662 | dout("map_osds osd %p is osd%d\n", req->r_osd, o); | 651 | dout("map_osds osd %p is osd%d\n", req->r_osd, o); |
663 | req->r_osd->o_osd = o; | 652 | req->r_osd->o_osd = o; |
@@ -674,8 +663,6 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
674 | err = 1; /* osd changed */ | 663 | err = 1; /* osd changed */ |
675 | 664 | ||
676 | out: | 665 | out: |
677 | if (newosd) | ||
678 | put_osd(newosd); | ||
679 | return err; | 666 | return err; |
680 | } | 667 | } |
681 | 668 | ||