From: Yu Kuai <yuku...@huawei.com>

There are 3 APIs for now:
 - bits: readonly, show status of bitmap bits, the number of each value;
 - metadata: readonly show bitmap metadata, include chunksize, chunkshift,
 chunks, offset and daemon_sleep;
 - daemon_sleep: read-write, default value is 30;

Signed-off-by: Yu Kuai <yuku...@huawei.com>
---
 drivers/md/md-llbitmap.c | 106 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
index a16bc84d9fa2..88ba29111e13 100644
--- a/drivers/md/md-llbitmap.c
+++ b/drivers/md/md-llbitmap.c
@@ -1234,6 +1234,110 @@ static void llbitmap_free(void *data)
 {
 }
 
+static ssize_t bits_show(struct mddev *mddev, char *page)
+{
+       struct llbitmap *llbitmap;
+       int bits[nr_llbitmap_state] = {0};
+       loff_t start = 0;
+
+       mutex_lock(&mddev->bitmap_info.mutex);
+       llbitmap = mddev->bitmap;
+       if (!llbitmap) {
+               mutex_unlock(&mddev->bitmap_info.mutex);
+               return sprintf(page, "no bitmap\n");
+       }
+
+       if (test_bit(BITMAP_WRITE_ERROR, &llbitmap->flags)) {
+               mutex_unlock(&mddev->bitmap_info.mutex);
+               return sprintf(page, "bitmap io error\n");
+       }
+
+       while (start < llbitmap->chunks) {
+               ssize_t ret;
+               enum llbitmap_state c;
+
+               ret = llbitmap_read(llbitmap, &c, start);
+               if (ret < 0) {
+                       set_bit(BITMAP_WRITE_ERROR, &llbitmap->flags);
+                       mutex_unlock(&mddev->bitmap_info.mutex);
+                       return sprintf(page, "bitmap io error\n");
+               }
+
+               if (c < 0 || c >= nr_llbitmap_state)
+                       pr_err("%s: invalid bit %llu state %d\n",
+                              __func__, start, c);
+               else
+                       bits[c]++;
+               start++;
+       }
+
+       mutex_unlock(&mddev->bitmap_info.mutex);
+       return sprintf(page, "unwritten %d\nclean %d\ndirty %d\nneed sync 
%d\nsyncing %d\n",
+                      bits[BitUnwritten], bits[BitClean], bits[BitDirty],
+                      bits[BitNeedSync], bits[BitSyncing]);
+}
+
+static struct md_sysfs_entry llbitmap_bits =
+__ATTR_RO(bits);
+
+static ssize_t metadata_show(struct mddev *mddev, char *page)
+{
+       struct llbitmap *llbitmap;
+       ssize_t ret;
+
+       mutex_lock(&mddev->bitmap_info.mutex);
+       llbitmap = mddev->bitmap;
+       if (!llbitmap) {
+               mutex_unlock(&mddev->bitmap_info.mutex);
+               return sprintf(page, "no bitmap\n");
+       }
+
+       ret =  sprintf(page, "chunksize %lu\nchunkshift %lu\nchunks %lu\noffset 
%llu\ndaemon_sleep %lu\n",
+                      llbitmap->chunksize, llbitmap->chunkshift,
+                      llbitmap->chunks, mddev->bitmap_info.offset,
+                      llbitmap->mddev->bitmap_info.daemon_sleep);
+       mutex_unlock(&mddev->bitmap_info.mutex);
+
+       return ret;
+}
+
+static struct md_sysfs_entry llbitmap_metadata =
+__ATTR_RO(metadata);
+
+static ssize_t
+daemon_sleep_show(struct mddev *mddev, char *page)
+{
+       return sprintf(page, "%lu\n", mddev->bitmap_info.daemon_sleep);
+}
+
+static ssize_t
+daemon_sleep_store(struct mddev *mddev, const char *buf, size_t len)
+{
+       unsigned long timeout;
+       int rv = kstrtoul(buf, 10, &timeout);
+
+       if (rv)
+               return rv;
+
+       mddev->bitmap_info.daemon_sleep = timeout;
+       return len;
+}
+
+static struct md_sysfs_entry llbitmap_daemon_sleep =
+__ATTR_RW(daemon_sleep);
+
+static struct attribute *md_llbitmap_attrs[] = {
+       &llbitmap_bits.attr,
+       &llbitmap_metadata.attr,
+       &llbitmap_daemon_sleep.attr,
+       NULL
+};
+
+static struct attribute_group md_llbitmap_group = {
+       .name = "llbitmap",
+       .attrs = md_llbitmap_attrs,
+};
+
 static struct bitmap_operations llbitmap_ops = {
        .head = {
                .type   = MD_BITMAP,
@@ -1274,4 +1378,6 @@ static struct bitmap_operations llbitmap_ops = {
        .copy_from_slot         = llbitmap_copy_from_slot,
        .set_pages              = llbitmap_set_pages,
        .free                   = llbitmap_free,
+
+       .group                  = &md_llbitmap_group,
 };
-- 
2.39.2


Reply via email to