diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index bf836dea113a..0ca959f5c934 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -274,14 +274,6 @@ struct rbd_img_request { #define for_each_obj_request_safe(ireq, oreq, n) \ list_for_each_entry_safe_reverse(oreq, n, &(ireq)->obj_requests, links) -struct rbd_snap { - const char *name; - u64 size; - struct list_head node; - u64 id; - u64 features; -}; - struct rbd_mapping { u64 size; u64 features; @@ -326,9 +318,6 @@ struct rbd_device { struct list_head node; - /* list of snapshots */ - struct list_head snaps; - /* sysfs related */ struct device dev; unsigned long open_count; /* protected by lock */ @@ -356,10 +345,7 @@ static DEFINE_SPINLOCK(rbd_client_list_lock); static int rbd_img_request_submit(struct rbd_img_request *img_request); -static int rbd_dev_snaps_update(struct rbd_device *rbd_dev); - static void rbd_dev_device_release(struct device *dev); -static void rbd_snap_destroy(struct rbd_snap *snap); static ssize_t rbd_add(struct bus_type *bus, const char *buf, size_t count); @@ -3075,17 +3061,6 @@ static int rbd_read_header(struct rbd_device *rbd_dev, return ret; } -static void rbd_remove_all_snaps(struct rbd_device *rbd_dev) -{ - struct rbd_snap *snap; - struct rbd_snap *next; - - list_for_each_entry_safe(snap, next, &rbd_dev->snaps, node) { - list_del(&snap->node); - rbd_snap_destroy(snap); - } -} - static void rbd_update_mapping_size(struct rbd_device *rbd_dev) { if (rbd_dev->spec->snap_id != CEPH_NOSNAP) @@ -3134,8 +3109,6 @@ static int rbd_dev_v1_refresh(struct rbd_device *rbd_dev) rbd_warn(rbd_dev, "object prefix changed (ignoring)"); kfree(h.object_prefix); - ret = rbd_dev_snaps_update(rbd_dev); - up_write(&rbd_dev->header_rwsem); return ret; @@ -3461,7 +3434,6 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc, spin_lock_init(&rbd_dev->lock); rbd_dev->flags = 0; INIT_LIST_HEAD(&rbd_dev->node); - INIT_LIST_HEAD(&rbd_dev->snaps); init_rwsem(&rbd_dev->header_rwsem); rbd_dev->spec = spec; @@ -3484,54 +3456,6 @@ static void rbd_dev_destroy(struct rbd_device *rbd_dev) kfree(rbd_dev); } -static void rbd_snap_destroy(struct rbd_snap *snap) -{ - kfree(snap->name); - kfree(snap); -} - -static struct rbd_snap *rbd_snap_create(struct rbd_device *rbd_dev, - const char *snap_name, - u64 snap_id, u64 snap_size, - u64 snap_features) -{ - struct rbd_snap *snap; - - snap = kzalloc(sizeof (*snap), GFP_KERNEL); - if (!snap) - return ERR_PTR(-ENOMEM); - - snap->name = snap_name; - snap->id = snap_id; - snap->size = snap_size; - snap->features = snap_features; - - return snap; -} - -/* - * Returns a dynamically-allocated snapshot name if successful, or a - * pointer-coded error otherwise. - */ -static const char *rbd_dev_v1_snap_info(struct rbd_device *rbd_dev, - u64 snap_id, u64 *snap_size, u64 *snap_features) -{ - const char *snap_name; - u32 which; - - which = rbd_dev_snap_index(rbd_dev, snap_id); - if (which == BAD_SNAP_INDEX) - return ERR_PTR(-ENOENT); - snap_name = _rbd_dev_v1_snap_name(rbd_dev, which); - if (!snap_name) - return ERR_PTR(-ENOMEM); - - *snap_size = rbd_dev->header.snap_sizes[which]; - *snap_features = 0; /* No features for v1 */ - - return snap_name; -} - /* * Get the size and object order for an image snapshot, or if * snap_id is CEPH_NOSNAP, gets this information for the base @@ -3883,10 +3807,6 @@ static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) * When an image being mapped (not a parent) is probed, we have the * pool name and pool id, image name and image id, and the snapshot * name. The only thing we're missing is the snapshot id. - * - * The set of snapshots for an image is not known until they have - * been read by rbd_dev_snaps_update(), so we can't completely fill - * in this information until after that has been called. */ static int rbd_dev_spec_update(struct rbd_device *rbd_dev) { @@ -4065,45 +3985,6 @@ out: return snap_name; } -static const char *rbd_dev_v2_snap_info(struct rbd_device *rbd_dev, - u64 snap_id, u64 *snap_size, u64 *snap_features) -{ - u64 size; - u64 features; - const char *snap_name; - int ret; - - ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, NULL, &size); - if (ret) - goto out_err; - - ret = _rbd_dev_v2_snap_features(rbd_dev, snap_id, &features); - if (ret) - goto out_err; - - snap_name = rbd_dev_v2_snap_name(rbd_dev, snap_id); - if (!IS_ERR(snap_name)) { - *snap_size = size; - *snap_features = features; - } - - return snap_name; -out_err: - return ERR_PTR(ret); -} - -static const char *rbd_dev_snap_info(struct rbd_device *rbd_dev, - u64 snap_id, u64 *snap_size, u64 *snap_features) -{ - if (rbd_dev->image_format == 1) - return rbd_dev_v1_snap_info(rbd_dev, snap_id, - snap_size, snap_features); - if (rbd_dev->image_format == 2) - return rbd_dev_v2_snap_info(rbd_dev, snap_id, - snap_size, snap_features); - return ERR_PTR(-EINVAL); -} - static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev) { int ret; @@ -4119,141 +4000,12 @@ static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev) dout("rbd_dev_v2_snap_context returned %d\n", ret); if (ret) goto out; - ret = rbd_dev_snaps_update(rbd_dev); - dout("rbd_dev_snaps_update returned %d\n", ret); - if (ret) - goto out; out: up_write(&rbd_dev->header_rwsem); return ret; } -/* - * Scan the rbd device's current snapshot list and compare it to the - * newly-received snapshot context. Remove any existing snapshots - * not present in the new snapshot context. Add a new snapshot for - * any snaphots in the snapshot context not in the current list. - * And verify there are no changes to snapshots we already know - * about. - * - * Assumes the snapshots in the snapshot context are sorted by - * snapshot id, highest id first. (Snapshots in the rbd_dev's list - * are also maintained in that order.) - * - * Note that any error occurs while updating the snapshot list - * aborts the update, and the entire list is cleared. The snapshot - * list becomes inconsistent at that point anyway, so it might as - * well be empty. - */ -static int rbd_dev_snaps_update(struct rbd_device *rbd_dev) -{ - struct ceph_snap_context *snapc = rbd_dev->header.snapc; - const u32 snap_count = snapc->num_snaps; - struct list_head *head = &rbd_dev->snaps; - struct list_head *links = head->next; - u32 index = 0; - int ret = 0; - - dout("%s: snap count is %u\n", __func__, (unsigned int)snap_count); - while (index < snap_count || links != head) { - u64 snap_id; - struct rbd_snap *snap; - const char *snap_name; - u64 snap_size = 0; - u64 snap_features = 0; - - snap_id = index < snap_count ? snapc->snaps[index] - : CEPH_NOSNAP; - snap = links != head ? list_entry(links, struct rbd_snap, node) - : NULL; - rbd_assert(!snap || snap->id != CEPH_NOSNAP); - - if (snap_id == CEPH_NOSNAP || (snap && snap->id > snap_id)) { - struct list_head *next = links->next; - - /* - * A previously-existing snapshot is not in - * the new snap context. - * - * If the now-missing snapshot is the one - * the image represents, clear its existence - * flag so we can avoid sending any more - * requests to it. - */ - if (rbd_dev->spec->snap_id == snap->id) - clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); - dout("removing %ssnap id %llu\n", - rbd_dev->spec->snap_id == snap->id ? - "mapped " : "", - (unsigned long long)snap->id); - - list_del(&snap->node); - rbd_snap_destroy(snap); - - /* Done with this list entry; advance */ - - links = next; - continue; - } - - snap_name = rbd_dev_snap_info(rbd_dev, snap_id, - &snap_size, &snap_features); - if (IS_ERR(snap_name)) { - ret = PTR_ERR(snap_name); - dout("failed to get snap info, error %d\n", ret); - goto out_err; - } - - dout("entry %u: snap_id = %llu\n", (unsigned int)snap_count, - (unsigned long long)snap_id); - if (!snap || (snap_id != CEPH_NOSNAP && snap->id < snap_id)) { - struct rbd_snap *new_snap; - - /* We haven't seen this snapshot before */ - - new_snap = rbd_snap_create(rbd_dev, snap_name, - snap_id, snap_size, snap_features); - if (IS_ERR(new_snap)) { - ret = PTR_ERR(new_snap); - dout(" failed to add dev, error %d\n", ret); - goto out_err; - } - - /* New goes before existing, or at end of list */ - - dout(" added dev%s\n", snap ? "" : " at end\n"); - if (snap) - list_add_tail(&new_snap->node, &snap->node); - else - list_add_tail(&new_snap->node, head); - } else { - /* Already have this one */ - - dout(" already present\n"); - - rbd_assert(snap->size == snap_size); - rbd_assert(!strcmp(snap->name, snap_name)); - rbd_assert(snap->features == snap_features); - - /* Done with this list entry; advance */ - - links = links->next; - } - - /* Advance to the next entry in the snapshot context */ - - index++; - } - dout("%s: done\n", __func__); - - return 0; -out_err: - rbd_remove_all_snaps(rbd_dev); - - return ret; -} - static int rbd_bus_add_dev(struct rbd_device *rbd_dev) { struct device *dev; @@ -4913,7 +4665,6 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev) { int ret; - rbd_remove_all_snaps(rbd_dev); rbd_dev_unprobe(rbd_dev); ret = rbd_dev_header_watch_sync(rbd_dev, 0); if (ret) @@ -4963,20 +4714,14 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev) if (ret) goto err_out_watch; - ret = rbd_dev_snaps_update(rbd_dev); - if (ret) - goto err_out_probe; - ret = rbd_dev_spec_update(rbd_dev); if (ret) - goto err_out_snaps; + goto err_out_probe; ret = rbd_dev_probe_parent(rbd_dev); if (!ret) return 0; -err_out_snaps: - rbd_remove_all_snaps(rbd_dev); err_out_probe: rbd_dev_unprobe(rbd_dev); err_out_watch: