Documentation: embargoed-hardware-issues.rst: Add myself for Power
[sfrench/cifs-2.6.git] / fs / bcachefs / chardev.c
1 // SPDX-License-Identifier: GPL-2.0
2 #ifndef NO_BCACHEFS_CHARDEV
3
4 #include "bcachefs.h"
5 #include "bcachefs_ioctl.h"
6 #include "buckets.h"
7 #include "chardev.h"
8 #include "journal.h"
9 #include "move.h"
10 #include "recovery.h"
11 #include "replicas.h"
12 #include "super.h"
13 #include "super-io.h"
14 #include "thread_with_file.h"
15
16 #include <linux/cdev.h>
17 #include <linux/device.h>
18 #include <linux/fs.h>
19 #include <linux/ioctl.h>
20 #include <linux/major.h>
21 #include <linux/sched/task.h>
22 #include <linux/slab.h>
23 #include <linux/uaccess.h>
24
25 /* returns with ref on ca->ref */
26 static struct bch_dev *bch2_device_lookup(struct bch_fs *c, u64 dev,
27                                           unsigned flags)
28 {
29         struct bch_dev *ca;
30
31         if (flags & BCH_BY_INDEX) {
32                 if (dev >= c->sb.nr_devices)
33                         return ERR_PTR(-EINVAL);
34
35                 rcu_read_lock();
36                 ca = rcu_dereference(c->devs[dev]);
37                 if (ca)
38                         percpu_ref_get(&ca->ref);
39                 rcu_read_unlock();
40
41                 if (!ca)
42                         return ERR_PTR(-EINVAL);
43         } else {
44                 char *path;
45
46                 path = strndup_user((const char __user *)
47                                     (unsigned long) dev, PATH_MAX);
48                 if (IS_ERR(path))
49                         return ERR_CAST(path);
50
51                 ca = bch2_dev_lookup(c, path);
52                 kfree(path);
53         }
54
55         return ca;
56 }
57
58 #if 0
59 static long bch2_ioctl_assemble(struct bch_ioctl_assemble __user *user_arg)
60 {
61         struct bch_ioctl_assemble arg;
62         struct bch_fs *c;
63         u64 *user_devs = NULL;
64         char **devs = NULL;
65         unsigned i;
66         int ret = -EFAULT;
67
68         if (copy_from_user(&arg, user_arg, sizeof(arg)))
69                 return -EFAULT;
70
71         if (arg.flags || arg.pad)
72                 return -EINVAL;
73
74         user_devs = kmalloc_array(arg.nr_devs, sizeof(u64), GFP_KERNEL);
75         if (!user_devs)
76                 return -ENOMEM;
77
78         devs = kcalloc(arg.nr_devs, sizeof(char *), GFP_KERNEL);
79
80         if (copy_from_user(user_devs, user_arg->devs,
81                            sizeof(u64) * arg.nr_devs))
82                 goto err;
83
84         for (i = 0; i < arg.nr_devs; i++) {
85                 devs[i] = strndup_user((const char __user *)(unsigned long)
86                                        user_devs[i],
87                                        PATH_MAX);
88                 ret= PTR_ERR_OR_ZERO(devs[i]);
89                 if (ret)
90                         goto err;
91         }
92
93         c = bch2_fs_open(devs, arg.nr_devs, bch2_opts_empty());
94         ret = PTR_ERR_OR_ZERO(c);
95         if (!ret)
96                 closure_put(&c->cl);
97 err:
98         if (devs)
99                 for (i = 0; i < arg.nr_devs; i++)
100                         kfree(devs[i]);
101         kfree(devs);
102         return ret;
103 }
104
105 static long bch2_ioctl_incremental(struct bch_ioctl_incremental __user *user_arg)
106 {
107         struct bch_ioctl_incremental arg;
108         const char *err;
109         char *path;
110
111         if (copy_from_user(&arg, user_arg, sizeof(arg)))
112                 return -EFAULT;
113
114         if (arg.flags || arg.pad)
115                 return -EINVAL;
116
117         path = strndup_user((const char __user *)(unsigned long) arg.dev, PATH_MAX);
118         ret = PTR_ERR_OR_ZERO(path);
119         if (ret)
120                 return ret;
121
122         err = bch2_fs_open_incremental(path);
123         kfree(path);
124
125         if (err) {
126                 pr_err("Could not register bcachefs devices: %s", err);
127                 return -EINVAL;
128         }
129
130         return 0;
131 }
132 #endif
133
134 struct fsck_thread {
135         struct thread_with_stdio thr;
136         struct bch_fs           *c;
137         char                    **devs;
138         size_t                  nr_devs;
139         struct bch_opts         opts;
140 };
141
142 static void bch2_fsck_thread_exit(struct thread_with_stdio *_thr)
143 {
144         struct fsck_thread *thr = container_of(_thr, struct fsck_thread, thr);
145         if (thr->devs)
146                 for (size_t i = 0; i < thr->nr_devs; i++)
147                         kfree(thr->devs[i]);
148         kfree(thr->devs);
149         kfree(thr);
150 }
151
152 static int bch2_fsck_offline_thread_fn(struct thread_with_stdio *stdio)
153 {
154         struct fsck_thread *thr = container_of(stdio, struct fsck_thread, thr);
155         struct bch_fs *c = bch2_fs_open(thr->devs, thr->nr_devs, thr->opts);
156
157         if (IS_ERR(c))
158                 return PTR_ERR(c);
159
160         int ret = 0;
161         if (test_bit(BCH_FS_errors_fixed, &c->flags))
162                 ret |= 1;
163         if (test_bit(BCH_FS_error, &c->flags))
164                 ret |= 4;
165
166         bch2_fs_stop(c);
167
168         if (ret & 1)
169                 bch2_stdio_redirect_printf(&stdio->stdio, false, "%s: errors fixed\n", c->name);
170         if (ret & 4)
171                 bch2_stdio_redirect_printf(&stdio->stdio, false, "%s: still has errors\n", c->name);
172
173         return ret;
174 }
175
176 static const struct thread_with_stdio_ops bch2_offline_fsck_ops = {
177         .exit           = bch2_fsck_thread_exit,
178         .fn             = bch2_fsck_offline_thread_fn,
179 };
180
181 static long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *user_arg)
182 {
183         struct bch_ioctl_fsck_offline arg;
184         struct fsck_thread *thr = NULL;
185         u64 *devs = NULL;
186         long ret = 0;
187
188         if (copy_from_user(&arg, user_arg, sizeof(arg)))
189                 return -EFAULT;
190
191         if (arg.flags)
192                 return -EINVAL;
193
194         if (!capable(CAP_SYS_ADMIN))
195                 return -EPERM;
196
197         if (!(devs = kcalloc(arg.nr_devs, sizeof(*devs), GFP_KERNEL)) ||
198             !(thr = kzalloc(sizeof(*thr), GFP_KERNEL)) ||
199             !(thr->devs = kcalloc(arg.nr_devs, sizeof(*thr->devs), GFP_KERNEL))) {
200                 ret = -ENOMEM;
201                 goto err;
202         }
203
204         thr->opts = bch2_opts_empty();
205         thr->nr_devs = arg.nr_devs;
206
207         if (copy_from_user(devs, &user_arg->devs[0],
208                            array_size(sizeof(user_arg->devs[0]), arg.nr_devs))) {
209                 ret = -EINVAL;
210                 goto err;
211         }
212
213         for (size_t i = 0; i < arg.nr_devs; i++) {
214                 thr->devs[i] = strndup_user((char __user *)(unsigned long) devs[i], PATH_MAX);
215                 ret = PTR_ERR_OR_ZERO(thr->devs[i]);
216                 if (ret)
217                         goto err;
218         }
219
220         if (arg.opts) {
221                 char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
222
223                 ret =   PTR_ERR_OR_ZERO(optstr) ?:
224                         bch2_parse_mount_opts(NULL, &thr->opts, optstr);
225                 kfree(optstr);
226
227                 if (ret)
228                         goto err;
229         }
230
231         opt_set(thr->opts, stdio, (u64)(unsigned long)&thr->thr.stdio);
232
233         ret = bch2_run_thread_with_stdio(&thr->thr, &bch2_offline_fsck_ops);
234 err:
235         if (ret < 0) {
236                 if (thr)
237                         bch2_fsck_thread_exit(&thr->thr);
238                 pr_err("ret %s", bch2_err_str(ret));
239         }
240         kfree(devs);
241         return ret;
242 }
243
244 static long bch2_global_ioctl(unsigned cmd, void __user *arg)
245 {
246         long ret;
247
248         switch (cmd) {
249 #if 0
250         case BCH_IOCTL_ASSEMBLE:
251                 return bch2_ioctl_assemble(arg);
252         case BCH_IOCTL_INCREMENTAL:
253                 return bch2_ioctl_incremental(arg);
254 #endif
255         case BCH_IOCTL_FSCK_OFFLINE: {
256                 ret = bch2_ioctl_fsck_offline(arg);
257                 break;
258         }
259         default:
260                 ret = -ENOTTY;
261                 break;
262         }
263
264         if (ret < 0)
265                 ret = bch2_err_class(ret);
266         return ret;
267 }
268
269 static long bch2_ioctl_query_uuid(struct bch_fs *c,
270                         struct bch_ioctl_query_uuid __user *user_arg)
271 {
272         return copy_to_user_errcode(&user_arg->uuid, &c->sb.user_uuid,
273                                     sizeof(c->sb.user_uuid));
274 }
275
276 #if 0
277 static long bch2_ioctl_start(struct bch_fs *c, struct bch_ioctl_start arg)
278 {
279         if (!capable(CAP_SYS_ADMIN))
280                 return -EPERM;
281
282         if (arg.flags || arg.pad)
283                 return -EINVAL;
284
285         return bch2_fs_start(c);
286 }
287
288 static long bch2_ioctl_stop(struct bch_fs *c)
289 {
290         if (!capable(CAP_SYS_ADMIN))
291                 return -EPERM;
292
293         bch2_fs_stop(c);
294         return 0;
295 }
296 #endif
297
298 static long bch2_ioctl_disk_add(struct bch_fs *c, struct bch_ioctl_disk arg)
299 {
300         char *path;
301         int ret;
302
303         if (!capable(CAP_SYS_ADMIN))
304                 return -EPERM;
305
306         if (arg.flags || arg.pad)
307                 return -EINVAL;
308
309         path = strndup_user((const char __user *)(unsigned long) arg.dev, PATH_MAX);
310         ret = PTR_ERR_OR_ZERO(path);
311         if (ret)
312                 return ret;
313
314         ret = bch2_dev_add(c, path);
315         kfree(path);
316
317         return ret;
318 }
319
320 static long bch2_ioctl_disk_remove(struct bch_fs *c, struct bch_ioctl_disk arg)
321 {
322         struct bch_dev *ca;
323
324         if (!capable(CAP_SYS_ADMIN))
325                 return -EPERM;
326
327         if ((arg.flags & ~(BCH_FORCE_IF_DATA_LOST|
328                            BCH_FORCE_IF_METADATA_LOST|
329                            BCH_FORCE_IF_DEGRADED|
330                            BCH_BY_INDEX)) ||
331             arg.pad)
332                 return -EINVAL;
333
334         ca = bch2_device_lookup(c, arg.dev, arg.flags);
335         if (IS_ERR(ca))
336                 return PTR_ERR(ca);
337
338         return bch2_dev_remove(c, ca, arg.flags);
339 }
340
341 static long bch2_ioctl_disk_online(struct bch_fs *c, struct bch_ioctl_disk arg)
342 {
343         char *path;
344         int ret;
345
346         if (!capable(CAP_SYS_ADMIN))
347                 return -EPERM;
348
349         if (arg.flags || arg.pad)
350                 return -EINVAL;
351
352         path = strndup_user((const char __user *)(unsigned long) arg.dev, PATH_MAX);
353         ret = PTR_ERR_OR_ZERO(path);
354         if (ret)
355                 return ret;
356
357         ret = bch2_dev_online(c, path);
358         kfree(path);
359         return ret;
360 }
361
362 static long bch2_ioctl_disk_offline(struct bch_fs *c, struct bch_ioctl_disk arg)
363 {
364         struct bch_dev *ca;
365         int ret;
366
367         if (!capable(CAP_SYS_ADMIN))
368                 return -EPERM;
369
370         if ((arg.flags & ~(BCH_FORCE_IF_DATA_LOST|
371                            BCH_FORCE_IF_METADATA_LOST|
372                            BCH_FORCE_IF_DEGRADED|
373                            BCH_BY_INDEX)) ||
374             arg.pad)
375                 return -EINVAL;
376
377         ca = bch2_device_lookup(c, arg.dev, arg.flags);
378         if (IS_ERR(ca))
379                 return PTR_ERR(ca);
380
381         ret = bch2_dev_offline(c, ca, arg.flags);
382         percpu_ref_put(&ca->ref);
383         return ret;
384 }
385
386 static long bch2_ioctl_disk_set_state(struct bch_fs *c,
387                         struct bch_ioctl_disk_set_state arg)
388 {
389         struct bch_dev *ca;
390         int ret;
391
392         if (!capable(CAP_SYS_ADMIN))
393                 return -EPERM;
394
395         if ((arg.flags & ~(BCH_FORCE_IF_DATA_LOST|
396                            BCH_FORCE_IF_METADATA_LOST|
397                            BCH_FORCE_IF_DEGRADED|
398                            BCH_BY_INDEX)) ||
399             arg.pad[0] || arg.pad[1] || arg.pad[2] ||
400             arg.new_state >= BCH_MEMBER_STATE_NR)
401                 return -EINVAL;
402
403         ca = bch2_device_lookup(c, arg.dev, arg.flags);
404         if (IS_ERR(ca))
405                 return PTR_ERR(ca);
406
407         ret = bch2_dev_set_state(c, ca, arg.new_state, arg.flags);
408         if (ret)
409                 bch_err(c, "Error setting device state: %s", bch2_err_str(ret));
410
411         percpu_ref_put(&ca->ref);
412         return ret;
413 }
414
415 struct bch_data_ctx {
416         struct thread_with_file         thr;
417
418         struct bch_fs                   *c;
419         struct bch_ioctl_data           arg;
420         struct bch_move_stats           stats;
421 };
422
423 static int bch2_data_thread(void *arg)
424 {
425         struct bch_data_ctx *ctx = container_of(arg, struct bch_data_ctx, thr);
426
427         ctx->thr.ret = bch2_data_job(ctx->c, &ctx->stats, ctx->arg);
428         ctx->stats.data_type = U8_MAX;
429         return 0;
430 }
431
432 static int bch2_data_job_release(struct inode *inode, struct file *file)
433 {
434         struct bch_data_ctx *ctx = container_of(file->private_data, struct bch_data_ctx, thr);
435
436         bch2_thread_with_file_exit(&ctx->thr);
437         kfree(ctx);
438         return 0;
439 }
440
441 static ssize_t bch2_data_job_read(struct file *file, char __user *buf,
442                                   size_t len, loff_t *ppos)
443 {
444         struct bch_data_ctx *ctx = container_of(file->private_data, struct bch_data_ctx, thr);
445         struct bch_fs *c = ctx->c;
446         struct bch_ioctl_data_event e = {
447                 .type                   = BCH_DATA_EVENT_PROGRESS,
448                 .p.data_type            = ctx->stats.data_type,
449                 .p.btree_id             = ctx->stats.pos.btree,
450                 .p.pos                  = ctx->stats.pos.pos,
451                 .p.sectors_done         = atomic64_read(&ctx->stats.sectors_seen),
452                 .p.sectors_total        = bch2_fs_usage_read_short(c).used,
453         };
454
455         if (len < sizeof(e))
456                 return -EINVAL;
457
458         return copy_to_user_errcode(buf, &e, sizeof(e)) ?: sizeof(e);
459 }
460
461 static const struct file_operations bcachefs_data_ops = {
462         .release        = bch2_data_job_release,
463         .read           = bch2_data_job_read,
464         .llseek         = no_llseek,
465 };
466
467 static long bch2_ioctl_data(struct bch_fs *c,
468                             struct bch_ioctl_data arg)
469 {
470         struct bch_data_ctx *ctx;
471         int ret;
472
473         if (!capable(CAP_SYS_ADMIN))
474                 return -EPERM;
475
476         if (arg.op >= BCH_DATA_OP_NR || arg.flags)
477                 return -EINVAL;
478
479         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
480         if (!ctx)
481                 return -ENOMEM;
482
483         ctx->c = c;
484         ctx->arg = arg;
485
486         ret = bch2_run_thread_with_file(&ctx->thr,
487                         &bcachefs_data_ops,
488                         bch2_data_thread);
489         if (ret < 0)
490                 kfree(ctx);
491         return ret;
492 }
493
494 static long bch2_ioctl_fs_usage(struct bch_fs *c,
495                                 struct bch_ioctl_fs_usage __user *user_arg)
496 {
497         struct bch_ioctl_fs_usage *arg = NULL;
498         struct bch_replicas_usage *dst_e, *dst_end;
499         struct bch_fs_usage_online *src;
500         u32 replica_entries_bytes;
501         unsigned i;
502         int ret = 0;
503
504         if (!test_bit(BCH_FS_started, &c->flags))
505                 return -EINVAL;
506
507         if (get_user(replica_entries_bytes, &user_arg->replica_entries_bytes))
508                 return -EFAULT;
509
510         arg = kzalloc(size_add(sizeof(*arg), replica_entries_bytes), GFP_KERNEL);
511         if (!arg)
512                 return -ENOMEM;
513
514         src = bch2_fs_usage_read(c);
515         if (!src) {
516                 ret = -ENOMEM;
517                 goto err;
518         }
519
520         arg->capacity           = c->capacity;
521         arg->used               = bch2_fs_sectors_used(c, src);
522         arg->online_reserved    = src->online_reserved;
523
524         for (i = 0; i < BCH_REPLICAS_MAX; i++)
525                 arg->persistent_reserved[i] = src->u.persistent_reserved[i];
526
527         dst_e   = arg->replicas;
528         dst_end = (void *) arg->replicas + replica_entries_bytes;
529
530         for (i = 0; i < c->replicas.nr; i++) {
531                 struct bch_replicas_entry_v1 *src_e =
532                         cpu_replicas_entry(&c->replicas, i);
533
534                 /* check that we have enough space for one replicas entry */
535                 if (dst_e + 1 > dst_end) {
536                         ret = -ERANGE;
537                         break;
538                 }
539
540                 dst_e->sectors          = src->u.replicas[i];
541                 dst_e->r                = *src_e;
542
543                 /* recheck after setting nr_devs: */
544                 if (replicas_usage_next(dst_e) > dst_end) {
545                         ret = -ERANGE;
546                         break;
547                 }
548
549                 memcpy(dst_e->r.devs, src_e->devs, src_e->nr_devs);
550
551                 dst_e = replicas_usage_next(dst_e);
552         }
553
554         arg->replica_entries_bytes = (void *) dst_e - (void *) arg->replicas;
555
556         percpu_up_read(&c->mark_lock);
557         kfree(src);
558
559         if (ret)
560                 goto err;
561
562         ret = copy_to_user_errcode(user_arg, arg,
563                         sizeof(*arg) + arg->replica_entries_bytes);
564 err:
565         kfree(arg);
566         return ret;
567 }
568
569 /* obsolete, didn't allow for new data types: */
570 static long bch2_ioctl_dev_usage(struct bch_fs *c,
571                                  struct bch_ioctl_dev_usage __user *user_arg)
572 {
573         struct bch_ioctl_dev_usage arg;
574         struct bch_dev_usage src;
575         struct bch_dev *ca;
576         unsigned i;
577
578         if (!test_bit(BCH_FS_started, &c->flags))
579                 return -EINVAL;
580
581         if (copy_from_user(&arg, user_arg, sizeof(arg)))
582                 return -EFAULT;
583
584         if ((arg.flags & ~BCH_BY_INDEX) ||
585             arg.pad[0] ||
586             arg.pad[1] ||
587             arg.pad[2])
588                 return -EINVAL;
589
590         ca = bch2_device_lookup(c, arg.dev, arg.flags);
591         if (IS_ERR(ca))
592                 return PTR_ERR(ca);
593
594         src = bch2_dev_usage_read(ca);
595
596         arg.state               = ca->mi.state;
597         arg.bucket_size         = ca->mi.bucket_size;
598         arg.nr_buckets          = ca->mi.nbuckets - ca->mi.first_bucket;
599
600         for (i = 0; i < BCH_DATA_NR; i++) {
601                 arg.d[i].buckets        = src.d[i].buckets;
602                 arg.d[i].sectors        = src.d[i].sectors;
603                 arg.d[i].fragmented     = src.d[i].fragmented;
604         }
605
606         percpu_ref_put(&ca->ref);
607
608         return copy_to_user_errcode(user_arg, &arg, sizeof(arg));
609 }
610
611 static long bch2_ioctl_dev_usage_v2(struct bch_fs *c,
612                                  struct bch_ioctl_dev_usage_v2 __user *user_arg)
613 {
614         struct bch_ioctl_dev_usage_v2 arg;
615         struct bch_dev_usage src;
616         struct bch_dev *ca;
617         int ret = 0;
618
619         if (!test_bit(BCH_FS_started, &c->flags))
620                 return -EINVAL;
621
622         if (copy_from_user(&arg, user_arg, sizeof(arg)))
623                 return -EFAULT;
624
625         if ((arg.flags & ~BCH_BY_INDEX) ||
626             arg.pad[0] ||
627             arg.pad[1] ||
628             arg.pad[2])
629                 return -EINVAL;
630
631         ca = bch2_device_lookup(c, arg.dev, arg.flags);
632         if (IS_ERR(ca))
633                 return PTR_ERR(ca);
634
635         src = bch2_dev_usage_read(ca);
636
637         arg.state               = ca->mi.state;
638         arg.bucket_size         = ca->mi.bucket_size;
639         arg.nr_data_types       = min(arg.nr_data_types, BCH_DATA_NR);
640         arg.nr_buckets          = ca->mi.nbuckets - ca->mi.first_bucket;
641
642         ret = copy_to_user_errcode(user_arg, &arg, sizeof(arg));
643         if (ret)
644                 goto err;
645
646         for (unsigned i = 0; i < arg.nr_data_types; i++) {
647                 struct bch_ioctl_dev_usage_type t = {
648                         .buckets        = src.d[i].buckets,
649                         .sectors        = src.d[i].sectors,
650                         .fragmented     = src.d[i].fragmented,
651                 };
652
653                 ret = copy_to_user_errcode(&user_arg->d[i], &t, sizeof(t));
654                 if (ret)
655                         goto err;
656         }
657 err:
658         percpu_ref_put(&ca->ref);
659         return ret;
660 }
661
662 static long bch2_ioctl_read_super(struct bch_fs *c,
663                                   struct bch_ioctl_read_super arg)
664 {
665         struct bch_dev *ca = NULL;
666         struct bch_sb *sb;
667         int ret = 0;
668
669         if (!capable(CAP_SYS_ADMIN))
670                 return -EPERM;
671
672         if ((arg.flags & ~(BCH_BY_INDEX|BCH_READ_DEV)) ||
673             arg.pad)
674                 return -EINVAL;
675
676         mutex_lock(&c->sb_lock);
677
678         if (arg.flags & BCH_READ_DEV) {
679                 ca = bch2_device_lookup(c, arg.dev, arg.flags);
680
681                 if (IS_ERR(ca)) {
682                         ret = PTR_ERR(ca);
683                         goto err;
684                 }
685
686                 sb = ca->disk_sb.sb;
687         } else {
688                 sb = c->disk_sb.sb;
689         }
690
691         if (vstruct_bytes(sb) > arg.size) {
692                 ret = -ERANGE;
693                 goto err;
694         }
695
696         ret = copy_to_user_errcode((void __user *)(unsigned long)arg.sb, sb,
697                                    vstruct_bytes(sb));
698 err:
699         if (!IS_ERR_OR_NULL(ca))
700                 percpu_ref_put(&ca->ref);
701         mutex_unlock(&c->sb_lock);
702         return ret;
703 }
704
705 static long bch2_ioctl_disk_get_idx(struct bch_fs *c,
706                                     struct bch_ioctl_disk_get_idx arg)
707 {
708         dev_t dev = huge_decode_dev(arg.dev);
709
710         if (!capable(CAP_SYS_ADMIN))
711                 return -EPERM;
712
713         if (!dev)
714                 return -EINVAL;
715
716         for_each_online_member(c, ca)
717                 if (ca->dev == dev) {
718                         percpu_ref_put(&ca->io_ref);
719                         return ca->dev_idx;
720                 }
721
722         return -BCH_ERR_ENOENT_dev_idx_not_found;
723 }
724
725 static long bch2_ioctl_disk_resize(struct bch_fs *c,
726                                    struct bch_ioctl_disk_resize arg)
727 {
728         struct bch_dev *ca;
729         int ret;
730
731         if (!capable(CAP_SYS_ADMIN))
732                 return -EPERM;
733
734         if ((arg.flags & ~BCH_BY_INDEX) ||
735             arg.pad)
736                 return -EINVAL;
737
738         ca = bch2_device_lookup(c, arg.dev, arg.flags);
739         if (IS_ERR(ca))
740                 return PTR_ERR(ca);
741
742         ret = bch2_dev_resize(c, ca, arg.nbuckets);
743
744         percpu_ref_put(&ca->ref);
745         return ret;
746 }
747
748 static long bch2_ioctl_disk_resize_journal(struct bch_fs *c,
749                                    struct bch_ioctl_disk_resize_journal arg)
750 {
751         struct bch_dev *ca;
752         int ret;
753
754         if (!capable(CAP_SYS_ADMIN))
755                 return -EPERM;
756
757         if ((arg.flags & ~BCH_BY_INDEX) ||
758             arg.pad)
759                 return -EINVAL;
760
761         if (arg.nbuckets > U32_MAX)
762                 return -EINVAL;
763
764         ca = bch2_device_lookup(c, arg.dev, arg.flags);
765         if (IS_ERR(ca))
766                 return PTR_ERR(ca);
767
768         ret = bch2_set_nr_journal_buckets(c, ca, arg.nbuckets);
769
770         percpu_ref_put(&ca->ref);
771         return ret;
772 }
773
774 static int bch2_fsck_online_thread_fn(struct thread_with_stdio *stdio)
775 {
776         struct fsck_thread *thr = container_of(stdio, struct fsck_thread, thr);
777         struct bch_fs *c = thr->c;
778
779         c->stdio_filter = current;
780         c->stdio = &thr->thr.stdio;
781
782         /*
783          * XXX: can we figure out a way to do this without mucking with c->opts?
784          */
785         unsigned old_fix_errors = c->opts.fix_errors;
786         if (opt_defined(thr->opts, fix_errors))
787                 c->opts.fix_errors = thr->opts.fix_errors;
788         else
789                 c->opts.fix_errors = FSCK_FIX_ask;
790
791         c->opts.fsck = true;
792         set_bit(BCH_FS_fsck_running, &c->flags);
793
794         c->curr_recovery_pass = BCH_RECOVERY_PASS_check_alloc_info;
795         int ret = bch2_run_online_recovery_passes(c);
796
797         clear_bit(BCH_FS_fsck_running, &c->flags);
798         bch_err_fn(c, ret);
799
800         c->stdio = NULL;
801         c->stdio_filter = NULL;
802         c->opts.fix_errors = old_fix_errors;
803
804         up(&c->online_fsck_mutex);
805         bch2_ro_ref_put(c);
806         return ret;
807 }
808
809 static const struct thread_with_stdio_ops bch2_online_fsck_ops = {
810         .exit           = bch2_fsck_thread_exit,
811         .fn             = bch2_fsck_online_thread_fn,
812 };
813
814 static long bch2_ioctl_fsck_online(struct bch_fs *c,
815                                    struct bch_ioctl_fsck_online arg)
816 {
817         struct fsck_thread *thr = NULL;
818         long ret = 0;
819
820         if (arg.flags)
821                 return -EINVAL;
822
823         if (!capable(CAP_SYS_ADMIN))
824                 return -EPERM;
825
826         if (!bch2_ro_ref_tryget(c))
827                 return -EROFS;
828
829         if (down_trylock(&c->online_fsck_mutex)) {
830                 bch2_ro_ref_put(c);
831                 return -EAGAIN;
832         }
833
834         thr = kzalloc(sizeof(*thr), GFP_KERNEL);
835         if (!thr) {
836                 ret = -ENOMEM;
837                 goto err;
838         }
839
840         thr->c = c;
841         thr->opts = bch2_opts_empty();
842
843         if (arg.opts) {
844                 char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
845
846                 ret =   PTR_ERR_OR_ZERO(optstr) ?:
847                         bch2_parse_mount_opts(c, &thr->opts, optstr);
848                 kfree(optstr);
849
850                 if (ret)
851                         goto err;
852         }
853
854         ret = bch2_run_thread_with_stdio(&thr->thr, &bch2_online_fsck_ops);
855 err:
856         if (ret < 0) {
857                 bch_err_fn(c, ret);
858                 if (thr)
859                         bch2_fsck_thread_exit(&thr->thr);
860                 up(&c->online_fsck_mutex);
861                 bch2_ro_ref_put(c);
862         }
863         return ret;
864 }
865
866 #define BCH_IOCTL(_name, _argtype)                                      \
867 do {                                                                    \
868         _argtype i;                                                     \
869                                                                         \
870         if (copy_from_user(&i, arg, sizeof(i)))                         \
871                 return -EFAULT;                                         \
872         ret = bch2_ioctl_##_name(c, i);                                 \
873         goto out;                                                       \
874 } while (0)
875
876 long bch2_fs_ioctl(struct bch_fs *c, unsigned cmd, void __user *arg)
877 {
878         long ret;
879
880         switch (cmd) {
881         case BCH_IOCTL_QUERY_UUID:
882                 return bch2_ioctl_query_uuid(c, arg);
883         case BCH_IOCTL_FS_USAGE:
884                 return bch2_ioctl_fs_usage(c, arg);
885         case BCH_IOCTL_DEV_USAGE:
886                 return bch2_ioctl_dev_usage(c, arg);
887         case BCH_IOCTL_DEV_USAGE_V2:
888                 return bch2_ioctl_dev_usage_v2(c, arg);
889 #if 0
890         case BCH_IOCTL_START:
891                 BCH_IOCTL(start, struct bch_ioctl_start);
892         case BCH_IOCTL_STOP:
893                 return bch2_ioctl_stop(c);
894 #endif
895         case BCH_IOCTL_READ_SUPER:
896                 BCH_IOCTL(read_super, struct bch_ioctl_read_super);
897         case BCH_IOCTL_DISK_GET_IDX:
898                 BCH_IOCTL(disk_get_idx, struct bch_ioctl_disk_get_idx);
899         }
900
901         if (!test_bit(BCH_FS_started, &c->flags))
902                 return -EINVAL;
903
904         switch (cmd) {
905         case BCH_IOCTL_DISK_ADD:
906                 BCH_IOCTL(disk_add, struct bch_ioctl_disk);
907         case BCH_IOCTL_DISK_REMOVE:
908                 BCH_IOCTL(disk_remove, struct bch_ioctl_disk);
909         case BCH_IOCTL_DISK_ONLINE:
910                 BCH_IOCTL(disk_online, struct bch_ioctl_disk);
911         case BCH_IOCTL_DISK_OFFLINE:
912                 BCH_IOCTL(disk_offline, struct bch_ioctl_disk);
913         case BCH_IOCTL_DISK_SET_STATE:
914                 BCH_IOCTL(disk_set_state, struct bch_ioctl_disk_set_state);
915         case BCH_IOCTL_DATA:
916                 BCH_IOCTL(data, struct bch_ioctl_data);
917         case BCH_IOCTL_DISK_RESIZE:
918                 BCH_IOCTL(disk_resize, struct bch_ioctl_disk_resize);
919         case BCH_IOCTL_DISK_RESIZE_JOURNAL:
920                 BCH_IOCTL(disk_resize_journal, struct bch_ioctl_disk_resize_journal);
921         case BCH_IOCTL_FSCK_ONLINE:
922                 BCH_IOCTL(fsck_online, struct bch_ioctl_fsck_online);
923         default:
924                 return -ENOTTY;
925         }
926 out:
927         if (ret < 0)
928                 ret = bch2_err_class(ret);
929         return ret;
930 }
931
932 static DEFINE_IDR(bch_chardev_minor);
933
934 static long bch2_chardev_ioctl(struct file *filp, unsigned cmd, unsigned long v)
935 {
936         unsigned minor = iminor(file_inode(filp));
937         struct bch_fs *c = minor < U8_MAX ? idr_find(&bch_chardev_minor, minor) : NULL;
938         void __user *arg = (void __user *) v;
939
940         return c
941                 ? bch2_fs_ioctl(c, cmd, arg)
942                 : bch2_global_ioctl(cmd, arg);
943 }
944
945 static const struct file_operations bch_chardev_fops = {
946         .owner          = THIS_MODULE,
947         .unlocked_ioctl = bch2_chardev_ioctl,
948         .open           = nonseekable_open,
949 };
950
951 static int bch_chardev_major;
952 static struct class *bch_chardev_class;
953 static struct device *bch_chardev;
954
955 void bch2_fs_chardev_exit(struct bch_fs *c)
956 {
957         if (!IS_ERR_OR_NULL(c->chardev))
958                 device_unregister(c->chardev);
959         if (c->minor >= 0)
960                 idr_remove(&bch_chardev_minor, c->minor);
961 }
962
963 int bch2_fs_chardev_init(struct bch_fs *c)
964 {
965         c->minor = idr_alloc(&bch_chardev_minor, c, 0, 0, GFP_KERNEL);
966         if (c->minor < 0)
967                 return c->minor;
968
969         c->chardev = device_create(bch_chardev_class, NULL,
970                                    MKDEV(bch_chardev_major, c->minor), c,
971                                    "bcachefs%u-ctl", c->minor);
972         if (IS_ERR(c->chardev))
973                 return PTR_ERR(c->chardev);
974
975         return 0;
976 }
977
978 void bch2_chardev_exit(void)
979 {
980         if (!IS_ERR_OR_NULL(bch_chardev_class))
981                 device_destroy(bch_chardev_class,
982                                MKDEV(bch_chardev_major, U8_MAX));
983         if (!IS_ERR_OR_NULL(bch_chardev_class))
984                 class_destroy(bch_chardev_class);
985         if (bch_chardev_major > 0)
986                 unregister_chrdev(bch_chardev_major, "bcachefs");
987 }
988
989 int __init bch2_chardev_init(void)
990 {
991         bch_chardev_major = register_chrdev(0, "bcachefs-ctl", &bch_chardev_fops);
992         if (bch_chardev_major < 0)
993                 return bch_chardev_major;
994
995         bch_chardev_class = class_create("bcachefs");
996         if (IS_ERR(bch_chardev_class))
997                 return PTR_ERR(bch_chardev_class);
998
999         bch_chardev = device_create(bch_chardev_class, NULL,
1000                                     MKDEV(bch_chardev_major, U8_MAX),
1001                                     NULL, "bcachefs-ctl");
1002         if (IS_ERR(bch_chardev))
1003                 return PTR_ERR(bch_chardev);
1004
1005         return 0;
1006 }
1007
1008 #endif /* NO_BCACHEFS_CHARDEV */