aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-05-01 13:43:03 -0400
committerAlex Elder <elder@inktank.com>2013-05-02 12:57:03 -0400
commit15228ede7d9437b0dcfe9331c9830b3646fdadf7 (patch)
treec7cde40606269d18896dd3a307b8cdf10e5f92df
parent33dca39f5c0c750d37d3d89ce8ae66be08280a45 (diff)
rbd: clear EXISTS flag if mapped snapshot disappears
This functionality inadvertently disappeared in the last patch. Image snapshots can get removed at just about any time. In particular it can disappear even if it is in use by an rbd client as a mapped image. The rbd client deals with such a disappearance by responding to new requests with ENXIO. This is implemented by each rbd device maintaining an EXISTS flag, which is normally set but cleared if a snapshot disappears. This patch (re-)implements the clearing of that flag. Whenever mapped image header information is refreshed, if the mapping is for a snapshot, verify the mapped snapshot is still present in the updated snapshot context. If it is not, clear the flag. It is not necessary to check this in the initial probe, because the probe will not succeed if the snapshot doesn't exist. This resolves: http://tracker.ceph.com/issues/4880 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r--drivers/block/rbd.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 0ca959f5c934..3f58aba6461f 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -3114,6 +3114,25 @@ static int rbd_dev_v1_refresh(struct rbd_device *rbd_dev)
3114 return ret; 3114 return ret;
3115} 3115}
3116 3116
3117/*
3118 * Clear the rbd device's EXISTS flag if the snapshot it's mapped to
3119 * has disappeared from the (just updated) snapshot context.
3120 */
3121static void rbd_exists_validate(struct rbd_device *rbd_dev)
3122{
3123 u64 snap_id;
3124
3125 if (!test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags))
3126 return;
3127
3128 snap_id = rbd_dev->spec->snap_id;
3129 if (snap_id == CEPH_NOSNAP)
3130 return;
3131
3132 if (rbd_dev_snap_index(rbd_dev, snap_id) == BAD_SNAP_INDEX)
3133 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags);
3134}
3135
3117static int rbd_dev_refresh(struct rbd_device *rbd_dev) 3136static int rbd_dev_refresh(struct rbd_device *rbd_dev)
3118{ 3137{
3119 u64 image_size; 3138 u64 image_size;
@@ -3126,6 +3145,10 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev)
3126 ret = rbd_dev_v1_refresh(rbd_dev); 3145 ret = rbd_dev_v1_refresh(rbd_dev);
3127 else 3146 else
3128 ret = rbd_dev_v2_refresh(rbd_dev); 3147 ret = rbd_dev_v2_refresh(rbd_dev);
3148
3149 /* If it's a mapped snapshot, validate its EXISTS flag */
3150
3151 rbd_exists_validate(rbd_dev);
3129 mutex_unlock(&ctl_mutex); 3152 mutex_unlock(&ctl_mutex);
3130 if (ret) 3153 if (ret)
3131 rbd_warn(rbd_dev, "got notification but failed to " 3154 rbd_warn(rbd_dev, "got notification but failed to "