]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
rbd: show the entire chain of parent images
authorIlya Dryomov <ilya.dryomov@inktank.com>
Tue, 22 Jul 2014 17:53:07 +0000 (21:53 +0400)
committerIlya Dryomov <ilya.dryomov@inktank.com>
Fri, 25 Jul 2014 09:14:27 +0000 (13:14 +0400)
Make /sys/bus/rbd/devices/<id>/parent show the entire chain of parent
images.  While at it, kernel sprintf() doesn't return negative values,
casting to unsigned long long is no longer necessary and there is no
good reason to split into multiple sprintf() calls.

Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
Reviewed-by: Alex Elder <elder@linaro.org>
Documentation/ABI/testing/sysfs-bus-rbd
drivers/block/rbd.c

index 501adc2a9ec723841c5246b19875a9bc14471ada..2ddd680929d8f83dc2147592978b37a6e33dc9a5 100644 (file)
@@ -94,5 +94,5 @@ current_snap
 
 parent
 
-       Information identifying the pool, image, and snapshot id for
-       the parent image in a layered rbd image (format 2 only).
+       Information identifying the chain of parent images in a layered rbd
+       image.  Entries are separated by empty lines.
index 703b728e05fa4fbce2442b44031798893501cb19..7847fbb949ff4920f55fe356838e602800fc6ad1 100644 (file)
@@ -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,