static int rbd_dev_refresh(struct rbd_device *rbd_dev);
 static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev);
+static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
+                                       u64 snap_id);
 
 static int rbd_open(struct block_device *bdev, fmode_t mode)
 {
        return BAD_SNAP_INDEX;
 }
 
-static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id)
+static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u64 snap_id)
 {
-       struct rbd_snap *snap;
+       u32 which;
 
+       which = rbd_dev_snap_index(rbd_dev, snap_id);
+       if (which == BAD_SNAP_INDEX)
+               return NULL;
+
+       return _rbd_dev_v1_snap_name(rbd_dev, which);
+}
+
+static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id)
+{
        if (snap_id == CEPH_NOSNAP)
                return RBD_SNAP_HEAD_NAME;
 
-       list_for_each_entry(snap, &rbd_dev->snaps, node)
-               if (snap_id == snap->id)
-                       return snap->name;
+       rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+       if (rbd_dev->image_format == 1)
+               return rbd_dev_v1_snap_name(rbd_dev, snap_id);
 
-       return NULL;
+       return rbd_dev_v2_snap_name(rbd_dev, snap_id);
 }
 
 static struct rbd_snap *snap_by_name(struct rbd_device *rbd_dev,
  * 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, u32 which,
-               u64 *snap_size, u64 *snap_features)
+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);
        /* Look up the snapshot name, and make a copy */
 
        snap_name = rbd_snap_name(rbd_dev, spec->snap_id);
-       if (!snap_name) {
-               rbd_warn(rbd_dev, "no snapshot with id %llu", spec->snap_id);
-               ret = -EIO;
-               goto out_err;
-       }
-       snap_name = kstrdup(snap_name, GFP_KERNEL);
        if (!snap_name) {
                ret = -ENOMEM;
                goto out_err;
        return ret;
 }
 
-static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u32 which)
+static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
+                                       u64 snap_id)
 {
        size_t size;
        void *reply_buf;
-       __le64 snap_id;
+       __le64 snapid;
        int ret;
        void *p;
        void *end;
        if (!reply_buf)
                return ERR_PTR(-ENOMEM);
 
-       rbd_assert(which < rbd_dev->header.snapc->num_snaps);
-       snap_id = cpu_to_le64(rbd_dev->header.snapc->snaps[which]);
+       snapid = cpu_to_le64(snap_id);
        ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name,
                                "rbd", "get_snapshot_name",
-                               &snap_id, sizeof (snap_id),
+                               &snapid, sizeof (snapid),
                                reply_buf, size);
        dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
        if (ret < 0) {
                goto out;
 
        dout("  snap_id 0x%016llx snap_name = %s\n",
-               (unsigned long long)le64_to_cpu(snap_id), snap_name);
+               (unsigned long long)snap_id, snap_name);
 out:
        kfree(reply_buf);
 
        return snap_name;
 }
 
-static const char *rbd_dev_v2_snap_info(struct rbd_device *rbd_dev, u32 which,
-               u64 *snap_size, u64 *snap_features)
+static const char *rbd_dev_v2_snap_info(struct rbd_device *rbd_dev,
+                       u64 snap_id, u64 *snap_size, u64 *snap_features)
 {
-       u64 snap_id;
        u64 size;
        u64 features;
        const char *snap_name;
        int ret;
 
-       rbd_assert(which < rbd_dev->header.snapc->num_snaps);
-       snap_id = rbd_dev->header.snapc->snaps[which];
        ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, NULL, &size);
        if (ret)
                goto out_err;
        if (ret)
                goto out_err;
 
-       snap_name = rbd_dev_v2_snap_name(rbd_dev, which);
+       snap_name = rbd_dev_v2_snap_name(rbd_dev, snap_id);
        if (!IS_ERR(snap_name)) {
                *snap_size = size;
                *snap_features = features;
        return ERR_PTR(ret);
 }
 
-static const char *rbd_dev_snap_info(struct rbd_device *rbd_dev, u32 which,
-               u64 *snap_size, u64 *snap_features)
+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, which,
+               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, which,
+               return rbd_dev_v2_snap_info(rbd_dev, snap_id,
                                        snap_size, snap_features);
        return ERR_PTR(-EINVAL);
 }
                        continue;
                }
 
-               snap_name = rbd_dev_snap_info(rbd_dev, index,
+               snap_name = rbd_dev_snap_info(rbd_dev, snap_id,
                                        &snap_size, &snap_features);
                if (IS_ERR(snap_name)) {
                        ret = PTR_ERR(snap_name);