aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-11-09 09:43:15 -0500
committerAlex Elder <elder@inktank.com>2013-01-17 16:52:00 -0500
commitd78b650a595e23e5a115d332e3c37e019baf7703 (patch)
treed2fd5bb83a6b32f90d6cd802379feedc136d52b4 /drivers/block
parentb395e8b5b8f06399e3fe3ee016c9cf41ff665efc (diff)
rbd: make exists flag atomic
The rbd_device->exists field can be updated asynchronously, changing from set to clear if a mapped snapshot disappears from the base image's snapshot context. Currently, value of the "exists" flag is only read and modified under protection of the header semaphore, but that will change with the next patch. Making it atomic ensures this won't be a problem because the a the non-existence of device will be immediately known. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 9d49e5b888d8..2846536d446e 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -229,7 +229,7 @@ struct rbd_device {
229 spinlock_t lock; /* queue lock */ 229 spinlock_t lock; /* queue lock */
230 230
231 struct rbd_image_header header; 231 struct rbd_image_header header;
232 bool exists; 232 atomic_t exists;
233 struct rbd_spec *spec; 233 struct rbd_spec *spec;
234 234
235 char *header_name; 235 char *header_name;
@@ -751,7 +751,7 @@ static int rbd_dev_set_mapping(struct rbd_device *rbd_dev)
751 goto done; 751 goto done;
752 rbd_dev->mapping.read_only = true; 752 rbd_dev->mapping.read_only = true;
753 } 753 }
754 rbd_dev->exists = true; 754 atomic_set(&rbd_dev->exists, 1);
755done: 755done:
756 return ret; 756 return ret;
757} 757}
@@ -1671,7 +1671,7 @@ static void rbd_rq_fn(struct request_queue *q)
1671 /* Grab a reference to the snapshot context */ 1671 /* Grab a reference to the snapshot context */
1672 1672
1673 down_read(&rbd_dev->header_rwsem); 1673 down_read(&rbd_dev->header_rwsem);
1674 if (rbd_dev->exists) { 1674 if (atomic_read(&rbd_dev->exists)) {
1675 snapc = ceph_get_snap_context(rbd_dev->header.snapc); 1675 snapc = ceph_get_snap_context(rbd_dev->header.snapc);
1676 rbd_assert(snapc != NULL); 1676 rbd_assert(snapc != NULL);
1677 } 1677 }
@@ -2294,6 +2294,7 @@ struct rbd_device *rbd_dev_create(struct rbd_client *rbdc,
2294 return NULL; 2294 return NULL;
2295 2295
2296 spin_lock_init(&rbd_dev->lock); 2296 spin_lock_init(&rbd_dev->lock);
2297 atomic_set(&rbd_dev->exists, 0);
2297 INIT_LIST_HEAD(&rbd_dev->node); 2298 INIT_LIST_HEAD(&rbd_dev->node);
2298 INIT_LIST_HEAD(&rbd_dev->snaps); 2299 INIT_LIST_HEAD(&rbd_dev->snaps);
2299 init_rwsem(&rbd_dev->header_rwsem); 2300 init_rwsem(&rbd_dev->header_rwsem);
@@ -2918,7 +2919,7 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
2918 /* Existing snapshot not in the new snap context */ 2919 /* Existing snapshot not in the new snap context */
2919 2920
2920 if (rbd_dev->spec->snap_id == snap->id) 2921 if (rbd_dev->spec->snap_id == snap->id)
2921 rbd_dev->exists = false; 2922 atomic_set(&rbd_dev->exists, 0);
2922 rbd_remove_snap_dev(snap); 2923 rbd_remove_snap_dev(snap);
2923 dout("%ssnap id %llu has been removed\n", 2924 dout("%ssnap id %llu has been removed\n",
2924 rbd_dev->spec->snap_id == snap->id ? 2925 rbd_dev->spec->snap_id == snap->id ?