Skip to content

Commit

Permalink
rbd: store snapshot id instead of index
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Josh Durgin authored and Alex Elder committed May 14, 2012
1 parent 403f24d commit 77dfe99
Showing 1 changed file with 5 additions and 22 deletions.
27 changes: 5 additions & 22 deletions drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,7 @@ struct rbd_device {
/* protects updating the header */
struct rw_semaphore header_rwsem;
char snap_name[RBD_MAX_SNAP_NAME_LEN];
u32 cur_snap; /* index+1 of current snapshot within snap context
0 - for the head */
u64 snap_id; /* current snapshot id */
int read_only;

struct list_head node;
Expand Down Expand Up @@ -554,21 +553,6 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
return -ENOMEM;
}

static int snap_index(struct rbd_image_header *header, int snap_num)
{
return header->total_snaps - snap_num;
}

static u64 cur_snap_id(struct rbd_device *rbd_dev)
{
struct rbd_image_header *header = &rbd_dev->header;

if (!rbd_dev->cur_snap)
return 0;

return header->snapc->snaps[snap_index(header, rbd_dev->cur_snap)];
}

static int snap_by_name(struct rbd_image_header *header, const char *snap_name,
u64 *seq, u64 *size)
{
Expand Down Expand Up @@ -607,16 +591,15 @@ static int rbd_header_set_snap(struct rbd_device *dev, u64 *size)
snapc->seq = header->snap_seq;
else
snapc->seq = 0;
dev->cur_snap = 0;
dev->snap_id = CEPH_NOSNAP;
dev->read_only = 0;
if (size)
*size = header->image_size;
} else {
ret = snap_by_name(header, dev->snap_name, &snapc->seq, size);
if (ret < 0)
goto done;

dev->cur_snap = header->total_snaps - ret;
dev->snap_id = snapc->seq;
dev->read_only = 1;
}

Expand Down Expand Up @@ -1522,7 +1505,7 @@ static void rbd_rq_fn(struct request_queue *q)
coll, cur_seg);
else
rbd_req_read(rq, rbd_dev,
cur_snap_id(rbd_dev),
rbd_dev->snap_id,
ofs,
op_size, bio,
coll, cur_seg);
Expand Down Expand Up @@ -1657,7 +1640,7 @@ static int rbd_header_add_snap(struct rbd_device *dev,
struct ceph_mon_client *monc;

/* we should create a snapshot only if we're pointing at the head */
if (dev->cur_snap)
if (dev->snap_id != CEPH_NOSNAP)
return -EINVAL;

monc = &dev->rbd_client->client->monc;
Expand Down

0 comments on commit 77dfe99

Please sign in to comment.