#define RBD_SNAP_HEAD_NAME     "-"
 
+/* This allows a single page to hold an image name sent by OSD */
+#define RBD_IMAGE_NAME_LEN_MAX (PAGE_SIZE - sizeof (__le32) - 1)
 #define RBD_IMAGE_ID_LEN_MAX   64
+
 #define RBD_OBJ_PREFIX_LEN_MAX 64
 
 /* Feature bits */
        return -ENOMEM;
 }
 
+static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id)
+{
+       struct rbd_snap *snap;
+
+       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;
+
+       return NULL;
+}
+
 static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name)
 {
 
                goto out_err;
        }
        parent_spec->image_id = image_id;
+       parent_spec->image_id_len = len;
        ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err);
        ceph_decode_64_safe(&p, end, overlap, out_err);
 
        return ret;
 }
 
+static char *rbd_dev_image_name(struct rbd_device *rbd_dev)
+{
+       size_t image_id_size;
+       char *image_id;
+       void *p;
+       void *end;
+       size_t size;
+       void *reply_buf = NULL;
+       size_t len = 0;
+       char *image_name = NULL;
+       int ret;
+
+       rbd_assert(!rbd_dev->spec->image_name);
+
+       image_id_size = sizeof (__le32) + rbd_dev->spec->image_id_len;
+       image_id = kmalloc(image_id_size, GFP_KERNEL);
+       if (!image_id)
+               return NULL;
+
+       p = image_id;
+       end = (char *) image_id + image_id_size;
+       ceph_encode_string(&p, end, rbd_dev->spec->image_id,
+                               (u32) rbd_dev->spec->image_id_len);
+
+       size = sizeof (__le32) + RBD_IMAGE_NAME_LEN_MAX;
+       reply_buf = kmalloc(size, GFP_KERNEL);
+       if (!reply_buf)
+               goto out;
+
+       ret = rbd_req_sync_exec(rbd_dev, RBD_DIRECTORY,
+                               "rbd", "dir_get_name",
+                               image_id, image_id_size,
+                               (char *) reply_buf, size,
+                               CEPH_OSD_FLAG_READ, NULL);
+       if (ret < 0)
+               goto out;
+       p = reply_buf;
+       end = (char *) reply_buf + size;
+       image_name = ceph_extract_encoded_string(&p, end, &len, GFP_KERNEL);
+       if (IS_ERR(image_name))
+               image_name = NULL;
+       else
+               dout("%s: name is %s len is %zd\n", __func__, image_name, len);
+out:
+       kfree(reply_buf);
+       kfree(image_id);
+
+       return image_name;
+}
+
+/*
+ * When a parent image gets probed, we only have the pool, image,
+ * and snapshot ids but not the names of any of them.  This call
+ * is made later to fill in those names.  It has to be done after
+ * rbd_dev_snaps_update() has completed because some of the
+ * information (in particular, snapshot name) is not available
+ * until then.
+ */
+static int rbd_dev_probe_update_spec(struct rbd_device *rbd_dev)
+{
+       struct ceph_osd_client *osdc;
+       const char *name;
+       void *reply_buf = NULL;
+       int ret;
+
+       if (rbd_dev->spec->pool_name)
+               return 0;       /* Already have the names */
+
+       /* Look up the pool name */
+
+       osdc = &rbd_dev->rbd_client->client->osdc;
+       name = ceph_pg_pool_name_by_id(osdc->osdmap, rbd_dev->spec->pool_id);
+       if (!name)
+               return -EIO;    /* pool id too large (>= 2^31) */
+
+       rbd_dev->spec->pool_name = kstrdup(name, GFP_KERNEL);
+       if (!rbd_dev->spec->pool_name)
+               return -ENOMEM;
+
+       /* Fetch the image name; tolerate failure here */
+
+       name = rbd_dev_image_name(rbd_dev);
+       if (name) {
+               rbd_dev->spec->image_name_len = strlen(name);
+               rbd_dev->spec->image_name = (char *) name;
+       } else {
+               pr_warning(RBD_DRV_NAME "%d "
+                       "unable to get image name for image id %s\n",
+                       rbd_dev->major, rbd_dev->spec->image_id);
+       }
+
+       /* Look up the snapshot name. */
+
+       name = rbd_snap_name(rbd_dev, rbd_dev->spec->snap_id);
+       if (!name) {
+               ret = -EIO;
+               goto out_err;
+       }
+       rbd_dev->spec->snap_name = kstrdup(name, GFP_KERNEL);
+       if(!rbd_dev->spec->snap_name)
+               goto out_err;
+
+       return 0;
+out_err:
+       kfree(reply_buf);
+       kfree(rbd_dev->spec->pool_name);
+       rbd_dev->spec->pool_name = NULL;
+
+       return ret;
+}
+
 static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver)
 {
        size_t size;
        if (ret)
                return ret;
 
+       ret = rbd_dev_probe_update_spec(rbd_dev);
+       if (ret)
+               goto err_out_snaps;
+
        ret = rbd_dev_set_mapping(rbd_dev);
        if (ret)
                goto err_out_snaps;