aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index fd9656b5fdb9..8c90a39c2a91 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -264,7 +264,7 @@ struct rbd_device {
264 spinlock_t lock; /* queue lock */ 264 spinlock_t lock; /* queue lock */
265 265
266 struct rbd_image_header header; 266 struct rbd_image_header header;
267 atomic_t exists; 267 unsigned long flags;
268 struct rbd_spec *spec; 268 struct rbd_spec *spec;
269 269
270 char *header_name; 270 char *header_name;
@@ -292,6 +292,12 @@ struct rbd_device {
292 unsigned long open_count; 292 unsigned long open_count;
293}; 293};
294 294
295/* Flag bits for rbd_dev->flags */
296
297enum rbd_dev_flags {
298 RBD_DEV_FLAG_EXISTS, /* mapped snapshot has not been deleted */
299};
300
295static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ 301static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */
296 302
297static LIST_HEAD(rbd_dev_list); /* devices */ 303static LIST_HEAD(rbd_dev_list); /* devices */
@@ -782,7 +788,8 @@ static int rbd_dev_set_mapping(struct rbd_device *rbd_dev)
782 goto done; 788 goto done;
783 rbd_dev->mapping.read_only = true; 789 rbd_dev->mapping.read_only = true;
784 } 790 }
785 atomic_set(&rbd_dev->exists, 1); 791 set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags);
792
786done: 793done:
787 return ret; 794 return ret;
788} 795}
@@ -1877,9 +1884,14 @@ static void rbd_request_fn(struct request_queue *q)
1877 rbd_assert(rbd_dev->spec->snap_id == CEPH_NOSNAP); 1884 rbd_assert(rbd_dev->spec->snap_id == CEPH_NOSNAP);
1878 } 1885 }
1879 1886
1880 /* Quit early if the snapshot has disappeared */ 1887 /*
1881 1888 * Quit early if the mapped snapshot no longer
1882 if (!atomic_read(&rbd_dev->exists)) { 1889 * exists. It's still possible the snapshot will
1890 * have disappeared by the time our request arrives
1891 * at the osd, but there's no sense in sending it if
1892 * we already know.
1893 */
1894 if (!test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags)) {
1883 dout("request for non-existent snapshot"); 1895 dout("request for non-existent snapshot");
1884 rbd_assert(rbd_dev->spec->snap_id != CEPH_NOSNAP); 1896 rbd_assert(rbd_dev->spec->snap_id != CEPH_NOSNAP);
1885 result = -ENXIO; 1897 result = -ENXIO;
@@ -2571,7 +2583,7 @@ struct rbd_device *rbd_dev_create(struct rbd_client *rbdc,
2571 return NULL; 2583 return NULL;
2572 2584
2573 spin_lock_init(&rbd_dev->lock); 2585 spin_lock_init(&rbd_dev->lock);
2574 atomic_set(&rbd_dev->exists, 0); 2586 rbd_dev->flags = 0;
2575 INIT_LIST_HEAD(&rbd_dev->node); 2587 INIT_LIST_HEAD(&rbd_dev->node);
2576 INIT_LIST_HEAD(&rbd_dev->snaps); 2588 INIT_LIST_HEAD(&rbd_dev->snaps);
2577 init_rwsem(&rbd_dev->header_rwsem); 2589 init_rwsem(&rbd_dev->header_rwsem);
@@ -3200,10 +3212,17 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
3200 if (snap_id == CEPH_NOSNAP || (snap && snap->id > snap_id)) { 3212 if (snap_id == CEPH_NOSNAP || (snap && snap->id > snap_id)) {
3201 struct list_head *next = links->next; 3213 struct list_head *next = links->next;
3202 3214
3203 /* Existing snapshot not in the new snap context */ 3215 /*
3204 3216 * A previously-existing snapshot is not in
3217 * the new snap context.
3218 *
3219 * If the now missing snapshot is the one the
3220 * image is mapped to, clear its exists flag
3221 * so we can avoid sending any more requests
3222 * to it.
3223 */
3205 if (rbd_dev->spec->snap_id == snap->id) 3224 if (rbd_dev->spec->snap_id == snap->id)
3206 atomic_set(&rbd_dev->exists, 0); 3225 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags);
3207 rbd_remove_snap_dev(snap); 3226 rbd_remove_snap_dev(snap);
3208 dout("%ssnap id %llu has been removed\n", 3227 dout("%ssnap id %llu has been removed\n",
3209 rbd_dev->spec->snap_id == snap->id ? 3228 rbd_dev->spec->snap_id == snap->id ?