|
@@ -3685,46 +3685,36 @@ static ssize_t rbd_snap_show(struct device *dev,
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * For an rbd v2 image, shows the pool id, image id, and snapshot id
|
|
|
- * for the parent image. If there is no parent, simply shows
|
|
|
- * "(no parent image)".
|
|
|
+ * For a v2 image, shows the chain of parent images, separated by empty
|
|
|
+ * lines. For v1 images or if there is no parent, shows "(no parent
|
|
|
+ * image)".
|
|
|
*/
|
|
|
static ssize_t rbd_parent_show(struct device *dev,
|
|
|
- struct device_attribute *attr,
|
|
|
- char *buf)
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
{
|
|
|
struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
|
|
|
- struct rbd_spec *spec = rbd_dev->parent_spec;
|
|
|
- int count;
|
|
|
- char *bufp = buf;
|
|
|
+ ssize_t count = 0;
|
|
|
|
|
|
- if (!spec)
|
|
|
+ if (!rbd_dev->parent)
|
|
|
return sprintf(buf, "(no parent image)\n");
|
|
|
|
|
|
- count = sprintf(bufp, "pool_id %llu\npool_name %s\n",
|
|
|
- (unsigned long long) spec->pool_id, spec->pool_name);
|
|
|
- if (count < 0)
|
|
|
- return count;
|
|
|
- bufp += count;
|
|
|
-
|
|
|
- count = sprintf(bufp, "image_id %s\nimage_name %s\n", spec->image_id,
|
|
|
- spec->image_name ? spec->image_name : "(unknown)");
|
|
|
- if (count < 0)
|
|
|
- return count;
|
|
|
- bufp += count;
|
|
|
-
|
|
|
- count = sprintf(bufp, "snap_id %llu\nsnap_name %s\n",
|
|
|
- (unsigned long long) spec->snap_id, spec->snap_name);
|
|
|
- if (count < 0)
|
|
|
- return count;
|
|
|
- bufp += count;
|
|
|
-
|
|
|
- count = sprintf(bufp, "overlap %llu\n", rbd_dev->parent_overlap);
|
|
|
- if (count < 0)
|
|
|
- return count;
|
|
|
- bufp += count;
|
|
|
-
|
|
|
- return (ssize_t) (bufp - buf);
|
|
|
+ for ( ; rbd_dev->parent; rbd_dev = rbd_dev->parent) {
|
|
|
+ struct rbd_spec *spec = rbd_dev->parent_spec;
|
|
|
+
|
|
|
+ count += sprintf(&buf[count], "%s"
|
|
|
+ "pool_id %llu\npool_name %s\n"
|
|
|
+ "image_id %s\nimage_name %s\n"
|
|
|
+ "snap_id %llu\nsnap_name %s\n"
|
|
|
+ "overlap %llu\n",
|
|
|
+ !count ? "" : "\n", /* first? */
|
|
|
+ spec->pool_id, spec->pool_name,
|
|
|
+ spec->image_id, spec->image_name ?: "(unknown)",
|
|
|
+ spec->snap_id, spec->snap_name,
|
|
|
+ rbd_dev->parent_overlap);
|
|
|
+ }
|
|
|
+
|
|
|
+ return count;
|
|
|
}
|
|
|
|
|
|
static ssize_t rbd_image_refresh(struct device *dev,
|