diff options
| author | Josh Durgin <josh.durgin@dreamhost.com> | 2011-11-21 20:11:12 -0500 |
|---|---|---|
| committer | Alex Elder <elder@dreamhost.com> | 2012-03-22 11:47:52 -0400 |
| commit | c666601a935b94cc0f3310339411b6940de751ba (patch) | |
| tree | da8afdd9c553dc349f1a1cdd94ab05d4b5dc5449 /drivers/block/rbd.c | |
| parent | 3489b42a72a41d477665ab37f196ae9257180abb (diff) | |
rbd: move snap_rwsem to the device, rename to header_rwsem
A new temporary header is allocated each time the header changes, but
only the changed properties are copied over. We don't need a new
semaphore for each header update.
This addresses http://tracker.newdream.net/issues/2174
Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
Reviewed-by: Alex Elder <elder@dreamhost.com>
Diffstat (limited to 'drivers/block/rbd.c')
| -rw-r--r-- | drivers/block/rbd.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 6bbd5af1f029..013c7a549fb6 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -82,7 +82,6 @@ struct rbd_image_header { | |||
| 82 | __u8 obj_order; | 82 | __u8 obj_order; |
| 83 | __u8 crypt_type; | 83 | __u8 crypt_type; |
| 84 | __u8 comp_type; | 84 | __u8 comp_type; |
| 85 | struct rw_semaphore snap_rwsem; | ||
| 86 | struct ceph_snap_context *snapc; | 85 | struct ceph_snap_context *snapc; |
| 87 | size_t snap_names_len; | 86 | size_t snap_names_len; |
| 88 | u64 snap_seq; | 87 | u64 snap_seq; |
| @@ -173,6 +172,8 @@ struct rbd_device { | |||
| 173 | struct ceph_osd_event *watch_event; | 172 | struct ceph_osd_event *watch_event; |
| 174 | struct ceph_osd_request *watch_request; | 173 | struct ceph_osd_request *watch_request; |
| 175 | 174 | ||
| 175 | /* protects updating the header */ | ||
| 176 | struct rw_semaphore header_rwsem; | ||
| 176 | char snap_name[RBD_MAX_SNAP_NAME_LEN]; | 177 | char snap_name[RBD_MAX_SNAP_NAME_LEN]; |
| 177 | u32 cur_snap; /* index+1 of current snapshot within snap context | 178 | u32 cur_snap; /* index+1 of current snapshot within snap context |
| 178 | 0 - for the head */ | 179 | 0 - for the head */ |
| @@ -502,7 +503,6 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
| 502 | if (!header->snapc) | 503 | if (!header->snapc) |
| 503 | return -ENOMEM; | 504 | return -ENOMEM; |
| 504 | 505 | ||
| 505 | init_rwsem(&header->snap_rwsem); | ||
| 506 | header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); | 506 | header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); |
| 507 | if (snap_count) { | 507 | if (snap_count) { |
| 508 | header->snap_names = kmalloc(header->snap_names_len, | 508 | header->snap_names = kmalloc(header->snap_names_len, |
| @@ -597,7 +597,7 @@ static int rbd_header_set_snap(struct rbd_device *dev, u64 *size) | |||
| 597 | 597 | ||
| 598 | BUILD_BUG_ON(sizeof (dev->snap_name) < sizeof (RBD_SNAP_HEAD_NAME)); | 598 | BUILD_BUG_ON(sizeof (dev->snap_name) < sizeof (RBD_SNAP_HEAD_NAME)); |
| 599 | 599 | ||
| 600 | down_write(&header->snap_rwsem); | 600 | down_write(&dev->header_rwsem); |
| 601 | 601 | ||
| 602 | if (!memcmp(dev->snap_name, RBD_SNAP_HEAD_NAME, | 602 | if (!memcmp(dev->snap_name, RBD_SNAP_HEAD_NAME, |
| 603 | sizeof (RBD_SNAP_HEAD_NAME))) { | 603 | sizeof (RBD_SNAP_HEAD_NAME))) { |
| @@ -620,7 +620,7 @@ static int rbd_header_set_snap(struct rbd_device *dev, u64 *size) | |||
| 620 | 620 | ||
| 621 | ret = 0; | 621 | ret = 0; |
| 622 | done: | 622 | done: |
| 623 | up_write(&header->snap_rwsem); | 623 | up_write(&dev->header_rwsem); |
| 624 | return ret; | 624 | return ret; |
| 625 | } | 625 | } |
| 626 | 626 | ||
| @@ -887,7 +887,6 @@ static int rbd_do_request(struct request *rq, | |||
| 887 | struct timespec mtime = CURRENT_TIME; | 887 | struct timespec mtime = CURRENT_TIME; |
| 888 | struct rbd_request *req_data; | 888 | struct rbd_request *req_data; |
| 889 | struct ceph_osd_request_head *reqhead; | 889 | struct ceph_osd_request_head *reqhead; |
| 890 | struct rbd_image_header *header = &dev->header; | ||
| 891 | struct ceph_osd_client *osdc; | 890 | struct ceph_osd_client *osdc; |
| 892 | 891 | ||
| 893 | req_data = kzalloc(sizeof(*req_data), GFP_NOIO); | 892 | req_data = kzalloc(sizeof(*req_data), GFP_NOIO); |
| @@ -905,13 +904,13 @@ static int rbd_do_request(struct request *rq, | |||
| 905 | 904 | ||
| 906 | dout("rbd_do_request obj=%s ofs=%lld len=%lld\n", obj, len, ofs); | 905 | dout("rbd_do_request obj=%s ofs=%lld len=%lld\n", obj, len, ofs); |
| 907 | 906 | ||
| 908 | down_read(&header->snap_rwsem); | 907 | down_read(&dev->header_rwsem); |
| 909 | 908 | ||
| 910 | osdc = &dev->rbd_client->client->osdc; | 909 | osdc = &dev->rbd_client->client->osdc; |
| 911 | req = ceph_osdc_alloc_request(osdc, flags, snapc, ops, | 910 | req = ceph_osdc_alloc_request(osdc, flags, snapc, ops, |
| 912 | false, GFP_NOIO, pages, bio); | 911 | false, GFP_NOIO, pages, bio); |
| 913 | if (!req) { | 912 | if (!req) { |
| 914 | up_read(&header->snap_rwsem); | 913 | up_read(&dev->header_rwsem); |
| 915 | ret = -ENOMEM; | 914 | ret = -ENOMEM; |
| 916 | goto done_pages; | 915 | goto done_pages; |
| 917 | } | 916 | } |
| @@ -946,7 +945,7 @@ static int rbd_do_request(struct request *rq, | |||
| 946 | snapc, | 945 | snapc, |
| 947 | &mtime, | 946 | &mtime, |
| 948 | req->r_oid, req->r_oid_len); | 947 | req->r_oid, req->r_oid_len); |
| 949 | up_read(&header->snap_rwsem); | 948 | up_read(&dev->header_rwsem); |
| 950 | 949 | ||
| 951 | if (linger_req) { | 950 | if (linger_req) { |
| 952 | ceph_osdc_set_request_linger(osdc, req); | 951 | ceph_osdc_set_request_linger(osdc, req); |
| @@ -1718,7 +1717,7 @@ static int __rbd_update_snaps(struct rbd_device *rbd_dev) | |||
| 1718 | /* resized? */ | 1717 | /* resized? */ |
| 1719 | set_capacity(rbd_dev->disk, h.image_size / SECTOR_SIZE); | 1718 | set_capacity(rbd_dev->disk, h.image_size / SECTOR_SIZE); |
| 1720 | 1719 | ||
| 1721 | down_write(&rbd_dev->header.snap_rwsem); | 1720 | down_write(&rbd_dev->header_rwsem); |
| 1722 | 1721 | ||
| 1723 | snap_seq = rbd_dev->header.snapc->seq; | 1722 | snap_seq = rbd_dev->header.snapc->seq; |
| 1724 | if (rbd_dev->header.total_snaps && | 1723 | if (rbd_dev->header.total_snaps && |
| @@ -1743,7 +1742,7 @@ static int __rbd_update_snaps(struct rbd_device *rbd_dev) | |||
| 1743 | 1742 | ||
| 1744 | ret = __rbd_init_snaps_header(rbd_dev); | 1743 | ret = __rbd_init_snaps_header(rbd_dev); |
| 1745 | 1744 | ||
| 1746 | up_write(&rbd_dev->header.snap_rwsem); | 1745 | up_write(&rbd_dev->header_rwsem); |
| 1747 | 1746 | ||
| 1748 | return ret; | 1747 | return ret; |
| 1749 | } | 1748 | } |
| @@ -2380,8 +2379,9 @@ static ssize_t rbd_add(struct bus_type *bus, | |||
| 2380 | spin_lock_init(&rbd_dev->lock); | 2379 | spin_lock_init(&rbd_dev->lock); |
| 2381 | INIT_LIST_HEAD(&rbd_dev->node); | 2380 | INIT_LIST_HEAD(&rbd_dev->node); |
| 2382 | INIT_LIST_HEAD(&rbd_dev->snaps); | 2381 | INIT_LIST_HEAD(&rbd_dev->snaps); |
| 2382 | init_rwsem(&rbd_dev->header_rwsem); | ||
| 2383 | 2383 | ||
| 2384 | init_rwsem(&rbd_dev->header.snap_rwsem); | 2384 | init_rwsem(&rbd_dev->header_rwsem); |
| 2385 | 2385 | ||
| 2386 | /* generate unique id: find highest unique id, add one */ | 2386 | /* generate unique id: find highest unique id, add one */ |
| 2387 | rbd_id_get(rbd_dev); | 2387 | rbd_id_get(rbd_dev); |
