aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorJosh Durgin <josh.durgin@dreamhost.com>2011-11-21 16:04:42 -0500
committerAlex Elder <elder@dreamhost.com>2012-05-14 13:12:52 -0400
commit77dfe99fe3cb0b2b0545e19e2d57b7a9134ee3c0 (patch)
treead80a6b7d9a9be1880c44e3a91f6d42f674c2fd6 /drivers/block
parent403f24d3d51760a8b9368d595fa5f48c309f1a0f (diff)
rbd: store snapshot id instead of index
When a device was open at a snapshot, and snapshots were deleted or added, data from the wrong snapshot could be read. Instead of assuming the snap context is constant, store the actual snap id when the device is initialized, and rely on the OSDs to signal an error if we try reading from a snapshot that was deleted. Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com> Reviewed-by: Alex Elder <elder@dreamhost.com> Reviewed-by: Yehuda Sadeh <yehuda@hq.newdream.net>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c27
1 files changed, 5 insertions, 22 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 5ab9f55d3e0c..c1650bdf2f6e 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -175,8 +175,7 @@ struct rbd_device {
175 /* protects updating the header */ 175 /* protects updating the header */
176 struct rw_semaphore header_rwsem; 176 struct rw_semaphore header_rwsem;
177 char snap_name[RBD_MAX_SNAP_NAME_LEN]; 177 char snap_name[RBD_MAX_SNAP_NAME_LEN];
178 u32 cur_snap; /* index+1 of current snapshot within snap context 178 u64 snap_id; /* current snapshot id */
179 0 - for the head */
180 int read_only; 179 int read_only;
181 180
182 struct list_head node; 181 struct list_head node;
@@ -554,21 +553,6 @@ err_snapc:
554 return -ENOMEM; 553 return -ENOMEM;
555} 554}
556 555
557static int snap_index(struct rbd_image_header *header, int snap_num)
558{
559 return header->total_snaps - snap_num;
560}
561
562static u64 cur_snap_id(struct rbd_device *rbd_dev)
563{
564 struct rbd_image_header *header = &rbd_dev->header;
565
566 if (!rbd_dev->cur_snap)
567 return 0;
568
569 return header->snapc->snaps[snap_index(header, rbd_dev->cur_snap)];
570}
571
572static int snap_by_name(struct rbd_image_header *header, const char *snap_name, 556static int snap_by_name(struct rbd_image_header *header, const char *snap_name,
573 u64 *seq, u64 *size) 557 u64 *seq, u64 *size)
574{ 558{
@@ -607,7 +591,7 @@ static int rbd_header_set_snap(struct rbd_device *dev, u64 *size)
607 snapc->seq = header->snap_seq; 591 snapc->seq = header->snap_seq;
608 else 592 else
609 snapc->seq = 0; 593 snapc->seq = 0;
610 dev->cur_snap = 0; 594 dev->snap_id = CEPH_NOSNAP;
611 dev->read_only = 0; 595 dev->read_only = 0;
612 if (size) 596 if (size)
613 *size = header->image_size; 597 *size = header->image_size;
@@ -615,8 +599,7 @@ static int rbd_header_set_snap(struct rbd_device *dev, u64 *size)
615 ret = snap_by_name(header, dev->snap_name, &snapc->seq, size); 599 ret = snap_by_name(header, dev->snap_name, &snapc->seq, size);
616 if (ret < 0) 600 if (ret < 0)
617 goto done; 601 goto done;
618 602 dev->snap_id = snapc->seq;
619 dev->cur_snap = header->total_snaps - ret;
620 dev->read_only = 1; 603 dev->read_only = 1;
621 } 604 }
622 605
@@ -1522,7 +1505,7 @@ static void rbd_rq_fn(struct request_queue *q)
1522 coll, cur_seg); 1505 coll, cur_seg);
1523 else 1506 else
1524 rbd_req_read(rq, rbd_dev, 1507 rbd_req_read(rq, rbd_dev,
1525 cur_snap_id(rbd_dev), 1508 rbd_dev->snap_id,
1526 ofs, 1509 ofs,
1527 op_size, bio, 1510 op_size, bio,
1528 coll, cur_seg); 1511 coll, cur_seg);
@@ -1657,7 +1640,7 @@ static int rbd_header_add_snap(struct rbd_device *dev,
1657 struct ceph_mon_client *monc; 1640 struct ceph_mon_client *monc;
1658 1641
1659 /* we should create a snapshot only if we're pointing at the head */ 1642 /* we should create a snapshot only if we're pointing at the head */
1660 if (dev->cur_snap) 1643 if (dev->snap_id != CEPH_NOSNAP)
1661 return -EINVAL; 1644 return -EINVAL;
1662 1645
1663 monc = &dev->rbd_client->client->monc; 1646 monc = &dev->rbd_client->client->monc;