diff options
author | Sage Weil <sage@newdream.net> | 2010-03-29 00:22:50 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-03-29 00:23:56 -0400 |
commit | 94aa8ae13db2ecf2ec1b4e65a65d3fe92b468e0e (patch) | |
tree | 07ab734202675a9ff3bb991d9732a392061eacee | |
parent | 23ab15ad7a9d042afa7303b735b6e24faa607241 (diff) |
ceph: fix use after free on mds __unregister_request
There was a use after free in __unregister_request that would trigger
whenever the request map held the last reference. This appears to have
triggered an oops during 'umount -f' when requests are being torn down.
Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r-- | fs/ceph/mds_client.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 5268d404963c..5c7920be6420 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -532,7 +532,6 @@ static void __unregister_request(struct ceph_mds_client *mdsc, | |||
532 | dout("__unregister_request %p tid %lld\n", req, req->r_tid); | 532 | dout("__unregister_request %p tid %lld\n", req, req->r_tid); |
533 | rb_erase(&req->r_node, &mdsc->request_tree); | 533 | rb_erase(&req->r_node, &mdsc->request_tree); |
534 | RB_CLEAR_NODE(&req->r_node); | 534 | RB_CLEAR_NODE(&req->r_node); |
535 | ceph_mdsc_put_request(req); | ||
536 | 535 | ||
537 | if (req->r_unsafe_dir) { | 536 | if (req->r_unsafe_dir) { |
538 | struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir); | 537 | struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir); |
@@ -541,6 +540,8 @@ static void __unregister_request(struct ceph_mds_client *mdsc, | |||
541 | list_del_init(&req->r_unsafe_dir_item); | 540 | list_del_init(&req->r_unsafe_dir_item); |
542 | spin_unlock(&ci->i_unsafe_lock); | 541 | spin_unlock(&ci->i_unsafe_lock); |
543 | } | 542 | } |
543 | |||
544 | ceph_mdsc_put_request(req); | ||
544 | } | 545 | } |
545 | 546 | ||
546 | /* | 547 | /* |