diff options
author | Alex Elder <elder@inktank.com> | 2012-08-31 18:29:51 -0400 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2012-10-01 15:30:51 -0400 |
commit | f84344f334df8f1d41eba7cfa7eb1024da25e1fe (patch) | |
tree | fa50840800a981c6a5c9b5e52f372dbea4f81088 /drivers/block/rbd.c | |
parent | c9aadfe7860f83ee17e55fe17398f3fe948a0a84 (diff) |
rbd: separate mapping info in rbd_dev
Several fields in a struct rbd_dev are related to what is mapped, as
opposed to the actual base rbd image. If the base image is mapped
these are almost unneeded, but if a snapshot is mapped they describe
information about that snapshot.
In some contexts this can be a little bit confusing. So group these
mapping-related field into a structure to make it clear what they
are describing.
This also includes a minor change that rearranges the fields in the
in-core image header structure so that invariant fields are at the
top, followed by those that change.
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r-- | drivers/block/rbd.c | 83 |
1 files changed, 45 insertions, 38 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index eb6b7723906b..dff621060432 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -81,13 +81,15 @@ | |||
81 | * block device image metadata (in-memory version) | 81 | * block device image metadata (in-memory version) |
82 | */ | 82 | */ |
83 | struct rbd_image_header { | 83 | struct rbd_image_header { |
84 | u64 image_size; | 84 | /* These four fields never change for a given rbd image */ |
85 | char *object_prefix; | 85 | char *object_prefix; |
86 | __u8 obj_order; | 86 | __u8 obj_order; |
87 | __u8 crypt_type; | 87 | __u8 crypt_type; |
88 | __u8 comp_type; | 88 | __u8 comp_type; |
89 | struct ceph_snap_context *snapc; | ||
90 | 89 | ||
90 | /* The remaining fields need to be updated occasionally */ | ||
91 | u64 image_size; | ||
92 | struct ceph_snap_context *snapc; | ||
91 | char *snap_names; | 93 | char *snap_names; |
92 | u64 *snap_sizes; | 94 | u64 *snap_sizes; |
93 | 95 | ||
@@ -146,6 +148,13 @@ struct rbd_snap { | |||
146 | u64 id; | 148 | u64 id; |
147 | }; | 149 | }; |
148 | 150 | ||
151 | struct rbd_mapping { | ||
152 | char *snap_name; | ||
153 | u64 snap_id; | ||
154 | bool snap_exists; | ||
155 | bool read_only; | ||
156 | }; | ||
157 | |||
149 | /* | 158 | /* |
150 | * a single device | 159 | * a single device |
151 | */ | 160 | */ |
@@ -174,13 +183,8 @@ struct rbd_device { | |||
174 | 183 | ||
175 | /* protects updating the header */ | 184 | /* protects updating the header */ |
176 | struct rw_semaphore header_rwsem; | 185 | struct rw_semaphore header_rwsem; |
177 | /* name of the snapshot this device reads from */ | 186 | |
178 | char *snap_name; | 187 | struct rbd_mapping mapping; |
179 | /* id of the snapshot this device reads from */ | ||
180 | u64 snap_id; /* current snapshot id */ | ||
181 | /* whether the snap_id this device reads from still exists */ | ||
182 | bool snap_exists; | ||
183 | bool read_only; | ||
184 | 188 | ||
185 | struct list_head node; | 189 | struct list_head node; |
186 | 190 | ||
@@ -261,11 +265,11 @@ static int rbd_open(struct block_device *bdev, fmode_t mode) | |||
261 | { | 265 | { |
262 | struct rbd_device *rbd_dev = bdev->bd_disk->private_data; | 266 | struct rbd_device *rbd_dev = bdev->bd_disk->private_data; |
263 | 267 | ||
264 | if ((mode & FMODE_WRITE) && rbd_dev->read_only) | 268 | if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only) |
265 | return -EROFS; | 269 | return -EROFS; |
266 | 270 | ||
267 | rbd_get_dev(rbd_dev); | 271 | rbd_get_dev(rbd_dev); |
268 | set_device_ro(bdev, rbd_dev->read_only); | 272 | set_device_ro(bdev, rbd_dev->mapping.read_only); |
269 | 273 | ||
270 | return 0; | 274 | return 0; |
271 | } | 275 | } |
@@ -375,7 +379,7 @@ enum { | |||
375 | static match_table_t rbd_opts_tokens = { | 379 | static match_table_t rbd_opts_tokens = { |
376 | /* int args above */ | 380 | /* int args above */ |
377 | /* string args above */ | 381 | /* string args above */ |
378 | {Opt_read_only, "read_only"}, | 382 | {Opt_read_only, "mapping.read_only"}, |
379 | {Opt_read_only, "ro"}, /* Alternate spelling */ | 383 | {Opt_read_only, "ro"}, /* Alternate spelling */ |
380 | {Opt_read_write, "read_write"}, | 384 | {Opt_read_write, "read_write"}, |
381 | {Opt_read_write, "rw"}, /* Alternate spelling */ | 385 | {Opt_read_write, "rw"}, /* Alternate spelling */ |
@@ -583,13 +587,13 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
583 | header->snap_sizes = NULL; | 587 | header->snap_sizes = NULL; |
584 | } | 588 | } |
585 | 589 | ||
586 | header->image_size = le64_to_cpu(ondisk->image_size); | ||
587 | header->obj_order = ondisk->options.order; | 590 | header->obj_order = ondisk->options.order; |
588 | header->crypt_type = ondisk->options.crypt_type; | 591 | header->crypt_type = ondisk->options.crypt_type; |
589 | header->comp_type = ondisk->options.comp_type; | 592 | header->comp_type = ondisk->options.comp_type; |
590 | 593 | ||
591 | /* Allocate and fill in the snapshot context */ | 594 | /* Allocate and fill in the snapshot context */ |
592 | 595 | ||
596 | header->image_size = le64_to_cpu(ondisk->image_size); | ||
593 | size = sizeof (struct ceph_snap_context); | 597 | size = sizeof (struct ceph_snap_context); |
594 | size += snap_count * sizeof (header->snapc->snaps[0]); | 598 | size += snap_count * sizeof (header->snapc->snaps[0]); |
595 | header->snapc = kzalloc(size, GFP_KERNEL); | 599 | header->snapc = kzalloc(size, GFP_KERNEL); |
@@ -645,23 +649,24 @@ static int rbd_header_set_snap(struct rbd_device *rbd_dev, u64 *size) | |||
645 | 649 | ||
646 | down_write(&rbd_dev->header_rwsem); | 650 | down_write(&rbd_dev->header_rwsem); |
647 | 651 | ||
648 | if (!memcmp(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME, | 652 | if (!memcmp(rbd_dev->mapping.snap_name, RBD_SNAP_HEAD_NAME, |
649 | sizeof (RBD_SNAP_HEAD_NAME))) { | 653 | sizeof (RBD_SNAP_HEAD_NAME))) { |
650 | rbd_dev->snap_id = CEPH_NOSNAP; | 654 | rbd_dev->mapping.snap_id = CEPH_NOSNAP; |
651 | rbd_dev->snap_exists = false; | 655 | rbd_dev->mapping.snap_exists = false; |
652 | rbd_dev->read_only = rbd_dev->rbd_opts.read_only; | 656 | rbd_dev->mapping.read_only = rbd_dev->rbd_opts.read_only; |
653 | if (size) | 657 | if (size) |
654 | *size = rbd_dev->header.image_size; | 658 | *size = rbd_dev->header.image_size; |
655 | } else { | 659 | } else { |
656 | u64 snap_id = 0; | 660 | u64 snap_id = 0; |
657 | 661 | ||
658 | ret = snap_by_name(&rbd_dev->header, rbd_dev->snap_name, | 662 | ret = snap_by_name(&rbd_dev->header, |
663 | rbd_dev->mapping.snap_name, | ||
659 | &snap_id, size); | 664 | &snap_id, size); |
660 | if (ret < 0) | 665 | if (ret < 0) |
661 | goto done; | 666 | goto done; |
662 | rbd_dev->snap_id = snap_id; | 667 | rbd_dev->mapping.snap_id = snap_id; |
663 | rbd_dev->snap_exists = true; | 668 | rbd_dev->mapping.snap_exists = true; |
664 | rbd_dev->read_only = true; /* No choice for snapshots */ | 669 | rbd_dev->mapping.read_only = true; |
665 | } | 670 | } |
666 | 671 | ||
667 | ret = 0; | 672 | ret = 0; |
@@ -1532,7 +1537,7 @@ static void rbd_rq_fn(struct request_queue *q) | |||
1532 | size = blk_rq_bytes(rq); | 1537 | size = blk_rq_bytes(rq); |
1533 | ofs = blk_rq_pos(rq) * SECTOR_SIZE; | 1538 | ofs = blk_rq_pos(rq) * SECTOR_SIZE; |
1534 | rq_bio = rq->bio; | 1539 | rq_bio = rq->bio; |
1535 | if (do_write && rbd_dev->read_only) { | 1540 | if (do_write && rbd_dev->mapping.read_only) { |
1536 | __blk_end_request_all(rq, -EROFS); | 1541 | __blk_end_request_all(rq, -EROFS); |
1537 | continue; | 1542 | continue; |
1538 | } | 1543 | } |
@@ -1541,7 +1546,8 @@ static void rbd_rq_fn(struct request_queue *q) | |||
1541 | 1546 | ||
1542 | down_read(&rbd_dev->header_rwsem); | 1547 | down_read(&rbd_dev->header_rwsem); |
1543 | 1548 | ||
1544 | if (rbd_dev->snap_id != CEPH_NOSNAP && !rbd_dev->snap_exists) { | 1549 | if (rbd_dev->mapping.snap_id != CEPH_NOSNAP && |
1550 | !rbd_dev->mapping.snap_exists) { | ||
1545 | up_read(&rbd_dev->header_rwsem); | 1551 | up_read(&rbd_dev->header_rwsem); |
1546 | dout("request for non-existent snapshot"); | 1552 | dout("request for non-existent snapshot"); |
1547 | spin_lock_irq(q->queue_lock); | 1553 | spin_lock_irq(q->queue_lock); |
@@ -1595,7 +1601,7 @@ static void rbd_rq_fn(struct request_queue *q) | |||
1595 | coll, cur_seg); | 1601 | coll, cur_seg); |
1596 | else | 1602 | else |
1597 | rbd_req_read(rq, rbd_dev, | 1603 | rbd_req_read(rq, rbd_dev, |
1598 | rbd_dev->snap_id, | 1604 | rbd_dev->mapping.snap_id, |
1599 | ofs, | 1605 | ofs, |
1600 | op_size, bio, | 1606 | op_size, bio, |
1601 | coll, cur_seg); | 1607 | coll, cur_seg); |
@@ -1767,7 +1773,7 @@ static int rbd_header_add_snap(struct rbd_device *rbd_dev, | |||
1767 | struct ceph_mon_client *monc; | 1773 | struct ceph_mon_client *monc; |
1768 | 1774 | ||
1769 | /* we should create a snapshot only if we're pointing at the head */ | 1775 | /* we should create a snapshot only if we're pointing at the head */ |
1770 | if (rbd_dev->snap_id != CEPH_NOSNAP) | 1776 | if (rbd_dev->mapping.snap_id != CEPH_NOSNAP) |
1771 | return -EINVAL; | 1777 | return -EINVAL; |
1772 | 1778 | ||
1773 | monc = &rbd_dev->rbd_client->client->monc; | 1779 | monc = &rbd_dev->rbd_client->client->monc; |
@@ -1821,7 +1827,7 @@ static int __rbd_refresh_header(struct rbd_device *rbd_dev, u64 *hver) | |||
1821 | down_write(&rbd_dev->header_rwsem); | 1827 | down_write(&rbd_dev->header_rwsem); |
1822 | 1828 | ||
1823 | /* resized? */ | 1829 | /* resized? */ |
1824 | if (rbd_dev->snap_id == CEPH_NOSNAP) { | 1830 | if (rbd_dev->mapping.snap_id == CEPH_NOSNAP) { |
1825 | sector_t size = (sector_t) h.image_size / SECTOR_SIZE; | 1831 | sector_t size = (sector_t) h.image_size / SECTOR_SIZE; |
1826 | 1832 | ||
1827 | dout("setting size to %llu sectors", (unsigned long long) size); | 1833 | dout("setting size to %llu sectors", (unsigned long long) size); |
@@ -2004,7 +2010,7 @@ static ssize_t rbd_snap_show(struct device *dev, | |||
2004 | { | 2010 | { |
2005 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); | 2011 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); |
2006 | 2012 | ||
2007 | return sprintf(buf, "%s\n", rbd_dev->snap_name); | 2013 | return sprintf(buf, "%s\n", rbd_dev->mapping.snap_name); |
2008 | } | 2014 | } |
2009 | 2015 | ||
2010 | static ssize_t rbd_image_refresh(struct device *dev, | 2016 | static ssize_t rbd_image_refresh(struct device *dev, |
@@ -2205,11 +2211,12 @@ static int rbd_dev_snap_devs_update(struct rbd_device *rbd_dev) | |||
2205 | 2211 | ||
2206 | /* Existing snapshot not in the new snap context */ | 2212 | /* Existing snapshot not in the new snap context */ |
2207 | 2213 | ||
2208 | if (rbd_dev->snap_id == snap->id) | 2214 | if (rbd_dev->mapping.snap_id == snap->id) |
2209 | rbd_dev->snap_exists = false; | 2215 | rbd_dev->mapping.snap_exists = false; |
2210 | __rbd_remove_snap_dev(snap); | 2216 | __rbd_remove_snap_dev(snap); |
2211 | dout("%ssnap id %llu has been removed\n", | 2217 | dout("%ssnap id %llu has been removed\n", |
2212 | rbd_dev->snap_id == snap->id ? "mapped " : "", | 2218 | rbd_dev->mapping.snap_id == snap->id ? |
2219 | "mapped " : "", | ||
2213 | (unsigned long long) snap->id); | 2220 | (unsigned long long) snap->id); |
2214 | 2221 | ||
2215 | /* Done with this list entry; advance */ | 2222 | /* Done with this list entry; advance */ |
@@ -2522,18 +2529,18 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev, | |||
2522 | * The snapshot name is optional. If none is is supplied, | 2529 | * The snapshot name is optional. If none is is supplied, |
2523 | * we use the default value. | 2530 | * we use the default value. |
2524 | */ | 2531 | */ |
2525 | rbd_dev->snap_name = dup_token(&buf, &len); | 2532 | rbd_dev->mapping.snap_name = dup_token(&buf, &len); |
2526 | if (!rbd_dev->snap_name) | 2533 | if (!rbd_dev->mapping.snap_name) |
2527 | goto out_err; | 2534 | goto out_err; |
2528 | if (!len) { | 2535 | if (!len) { |
2529 | /* Replace the empty name with the default */ | 2536 | /* Replace the empty name with the default */ |
2530 | kfree(rbd_dev->snap_name); | 2537 | kfree(rbd_dev->mapping.snap_name); |
2531 | rbd_dev->snap_name | 2538 | rbd_dev->mapping.snap_name |
2532 | = kmalloc(sizeof (RBD_SNAP_HEAD_NAME), GFP_KERNEL); | 2539 | = kmalloc(sizeof (RBD_SNAP_HEAD_NAME), GFP_KERNEL); |
2533 | if (!rbd_dev->snap_name) | 2540 | if (!rbd_dev->mapping.snap_name) |
2534 | goto out_err; | 2541 | goto out_err; |
2535 | 2542 | ||
2536 | memcpy(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME, | 2543 | memcpy(rbd_dev->mapping.snap_name, RBD_SNAP_HEAD_NAME, |
2537 | sizeof (RBD_SNAP_HEAD_NAME)); | 2544 | sizeof (RBD_SNAP_HEAD_NAME)); |
2538 | } | 2545 | } |
2539 | 2546 | ||
@@ -2642,7 +2649,7 @@ err_out_client: | |||
2642 | rbd_put_client(rbd_dev); | 2649 | rbd_put_client(rbd_dev); |
2643 | err_put_id: | 2650 | err_put_id: |
2644 | if (rbd_dev->pool_name) { | 2651 | if (rbd_dev->pool_name) { |
2645 | kfree(rbd_dev->snap_name); | 2652 | kfree(rbd_dev->mapping.snap_name); |
2646 | kfree(rbd_dev->header_name); | 2653 | kfree(rbd_dev->header_name); |
2647 | kfree(rbd_dev->image_name); | 2654 | kfree(rbd_dev->image_name); |
2648 | kfree(rbd_dev->pool_name); | 2655 | kfree(rbd_dev->pool_name); |
@@ -2695,7 +2702,7 @@ static void rbd_dev_release(struct device *dev) | |||
2695 | unregister_blkdev(rbd_dev->major, rbd_dev->name); | 2702 | unregister_blkdev(rbd_dev->major, rbd_dev->name); |
2696 | 2703 | ||
2697 | /* done with the id, and with the rbd_dev */ | 2704 | /* done with the id, and with the rbd_dev */ |
2698 | kfree(rbd_dev->snap_name); | 2705 | kfree(rbd_dev->mapping.snap_name); |
2699 | kfree(rbd_dev->header_name); | 2706 | kfree(rbd_dev->header_name); |
2700 | kfree(rbd_dev->pool_name); | 2707 | kfree(rbd_dev->pool_name); |
2701 | kfree(rbd_dev->image_name); | 2708 | kfree(rbd_dev->image_name); |