]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: Convert bch2_ioctl_fs_usage() to new accounting
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 7 Jan 2024 01:29:25 +0000 (20:29 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 14 Jul 2024 23:00:13 +0000 (19:00 -0400)
This converts bch2_ioctl_fs_usage() to read from the new disk
accounting, via bch2_fs_replicas_usage_read().

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/chardev.c

index 77d7186b4ba3bedb32d53ef276b9e31d330a225c..57bb02996f8ee7f197e0c8908898c6e69fc305a9 100644 (file)
@@ -5,6 +5,7 @@
 #include "bcachefs_ioctl.h"
 #include "buckets.h"
 #include "chardev.h"
+#include "disk_accounting.h"
 #include "journal.h"
 #include "move.h"
 #include "recovery_passes.h"
@@ -516,11 +517,11 @@ static long bch2_ioctl_data(struct bch_fs *c,
 static long bch2_ioctl_fs_usage(struct bch_fs *c,
                                struct bch_ioctl_fs_usage __user *user_arg)
 {
-       struct bch_ioctl_fs_usage *arg = NULL;
-       struct bch_replicas_usage *dst_e, *dst_end;
-       struct bch_fs_usage_online *src;
-       u32 replica_entries_bytes;
+       struct bch_ioctl_fs_usage arg;
+       struct bch_fs_usage_online *src = NULL;
+       darray_char replicas = {};
        unsigned i;
+       u32 replica_entries_bytes;
        int ret = 0;
 
        if (!test_bit(BCH_FS_started, &c->flags))
@@ -529,9 +530,16 @@ static long bch2_ioctl_fs_usage(struct bch_fs *c,
        if (get_user(replica_entries_bytes, &user_arg->replica_entries_bytes))
                return -EFAULT;
 
-       arg = kzalloc(size_add(sizeof(*arg), replica_entries_bytes), GFP_KERNEL);
-       if (!arg)
-               return -ENOMEM;
+       ret   = bch2_fs_replicas_usage_read(c, &replicas) ?:
+               (replica_entries_bytes < replicas.nr ? -ERANGE : 0) ?:
+               copy_to_user_errcode(&user_arg->replicas, replicas.data, replicas.nr);
+       if (ret)
+               goto err;
+
+       arg.capacity            = c->capacity;
+       arg.used                = bch2_fs_sectors_used(c, src);
+       arg.online_reserved     = src->online_reserved;
+       arg.replica_entries_bytes = replicas.nr;
 
        src = bch2_fs_usage_read(c);
        if (!src) {
@@ -539,52 +547,14 @@ static long bch2_ioctl_fs_usage(struct bch_fs *c,
                goto err;
        }
 
-       arg->capacity           = c->capacity;
-       arg->used               = bch2_fs_sectors_used(c, src);
-       arg->online_reserved    = src->online_reserved;
-
        for (i = 0; i < BCH_REPLICAS_MAX; i++)
-               arg->persistent_reserved[i] = src->u.persistent_reserved[i];
-
-       dst_e   = arg->replicas;
-       dst_end = (void *) arg->replicas + replica_entries_bytes;
-
-       for (i = 0; i < c->replicas.nr; i++) {
-               struct bch_replicas_entry_v1 *src_e =
-                       cpu_replicas_entry(&c->replicas, i);
-
-               /* check that we have enough space for one replicas entry */
-               if (dst_e + 1 > dst_end) {
-                       ret = -ERANGE;
-                       break;
-               }
-
-               dst_e->sectors          = src->u.replicas[i];
-               dst_e->r                = *src_e;
-
-               /* recheck after setting nr_devs: */
-               if (replicas_usage_next(dst_e) > dst_end) {
-                       ret = -ERANGE;
-                       break;
-               }
-
-               memcpy(dst_e->r.devs, src_e->devs, src_e->nr_devs);
-
-               dst_e = replicas_usage_next(dst_e);
-       }
-
-       arg->replica_entries_bytes = (void *) dst_e - (void *) arg->replicas;
-
+               arg.persistent_reserved[i] = src->u.persistent_reserved[i];
        percpu_up_read(&c->mark_lock);
-       kfree(src);
-
-       if (ret)
-               goto err;
 
-       ret = copy_to_user_errcode(user_arg, arg,
-                       sizeof(*arg) + arg->replica_entries_bytes);
+       ret = copy_to_user_errcode(user_arg, &arg, sizeof(arg));
 err:
-       kfree(arg);
+       darray_exit(&replicas);
+       kfree(src);
        return ret;
 }