1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/fs.h>
24#include <linux/wait.h>
25#include <linux/slab.h>
26#include <linux/capability.h>
27#include <linux/uaccess.h>
28#include <linux/vmalloc.h>
29#include <linux/compat.h>
30#include <linux/mount.h>
31#include <linux/buffer_head.h>
32#include <linux/nilfs2_fs.h>
33#include "nilfs.h"
34#include "segment.h"
35#include "bmap.h"
36#include "cpfile.h"
37#include "sufile.h"
38#include "dat.h"
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
61 struct nilfs_argv *argv, int dir,
62 ssize_t (*dofunc)(struct the_nilfs *,
63 __u64 *, int,
64 void *, size_t, size_t))
65{
66 void *buf;
67 void __user *base = (void __user *)(unsigned long)argv->v_base;
68 size_t maxmembs, total, n;
69 ssize_t nr;
70 int ret, i;
71 __u64 pos, ppos;
72
73 if (argv->v_nmembs == 0)
74 return 0;
75
76 if (argv->v_size > PAGE_SIZE)
77 return -EINVAL;
78
79
80
81
82
83
84 if (argv->v_index > ~(__u64)0 - argv->v_nmembs)
85 return -EINVAL;
86
87 buf = (void *)__get_free_pages(GFP_NOFS, 0);
88 if (unlikely(!buf))
89 return -ENOMEM;
90 maxmembs = PAGE_SIZE / argv->v_size;
91
92 ret = 0;
93 total = 0;
94 pos = argv->v_index;
95 for (i = 0; i < argv->v_nmembs; i += n) {
96 n = (argv->v_nmembs - i < maxmembs) ?
97 argv->v_nmembs - i : maxmembs;
98 if ((dir & _IOC_WRITE) &&
99 copy_from_user(buf, base + argv->v_size * i,
100 argv->v_size * n)) {
101 ret = -EFAULT;
102 break;
103 }
104 ppos = pos;
105 nr = dofunc(nilfs, &pos, argv->v_flags, buf, argv->v_size,
106 n);
107 if (nr < 0) {
108 ret = nr;
109 break;
110 }
111 if ((dir & _IOC_READ) &&
112 copy_to_user(base + argv->v_size * i, buf,
113 argv->v_size * nr)) {
114 ret = -EFAULT;
115 break;
116 }
117 total += nr;
118 if ((size_t)nr < n)
119 break;
120 if (pos == ppos)
121 pos += n;
122 }
123 argv->v_nmembs = total;
124
125 free_pages((unsigned long)buf, 0);
126 return ret;
127}
128
129
130
131
132static int nilfs_ioctl_getflags(struct inode *inode, void __user *argp)
133{
134 unsigned int flags = NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE;
135
136 return put_user(flags, (int __user *)argp);
137}
138
139
140
141
142static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp,
143 void __user *argp)
144{
145 struct nilfs_transaction_info ti;
146 unsigned int flags, oldflags;
147 int ret;
148
149 if (!inode_owner_or_capable(inode))
150 return -EACCES;
151
152 if (get_user(flags, (int __user *)argp))
153 return -EFAULT;
154
155 ret = mnt_want_write_file(filp);
156 if (ret)
157 return ret;
158
159 flags = nilfs_mask_flags(inode->i_mode, flags);
160
161 mutex_lock(&inode->i_mutex);
162
163 oldflags = NILFS_I(inode)->i_flags;
164
165
166
167
168
169 ret = -EPERM;
170 if (((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) &&
171 !capable(CAP_LINUX_IMMUTABLE))
172 goto out;
173
174 ret = nilfs_transaction_begin(inode->i_sb, &ti, 0);
175 if (ret)
176 goto out;
177
178 NILFS_I(inode)->i_flags = (oldflags & ~FS_FL_USER_MODIFIABLE) |
179 (flags & FS_FL_USER_MODIFIABLE);
180
181 nilfs_set_inode_flags(inode);
182 inode->i_ctime = CURRENT_TIME;
183 if (IS_SYNC(inode))
184 nilfs_set_transaction_flag(NILFS_TI_SYNC);
185
186 nilfs_mark_inode_dirty(inode);
187 ret = nilfs_transaction_commit(inode->i_sb);
188out:
189 mutex_unlock(&inode->i_mutex);
190 mnt_drop_write_file(filp);
191 return ret;
192}
193
194
195
196
197static int nilfs_ioctl_getversion(struct inode *inode, void __user *argp)
198{
199 return put_user(inode->i_generation, (int __user *)argp);
200}
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
222 unsigned int cmd, void __user *argp)
223{
224 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
225 struct nilfs_transaction_info ti;
226 struct nilfs_cpmode cpmode;
227 int ret;
228
229 if (!capable(CAP_SYS_ADMIN))
230 return -EPERM;
231
232 ret = mnt_want_write_file(filp);
233 if (ret)
234 return ret;
235
236 ret = -EFAULT;
237 if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
238 goto out;
239
240 mutex_lock(&nilfs->ns_snapshot_mount_mutex);
241
242 nilfs_transaction_begin(inode->i_sb, &ti, 0);
243 ret = nilfs_cpfile_change_cpmode(
244 nilfs->ns_cpfile, cpmode.cm_cno, cpmode.cm_mode);
245 if (unlikely(ret < 0))
246 nilfs_transaction_abort(inode->i_sb);
247 else
248 nilfs_transaction_commit(inode->i_sb);
249
250 mutex_unlock(&nilfs->ns_snapshot_mount_mutex);
251out:
252 mnt_drop_write_file(filp);
253 return ret;
254}
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275static int
276nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
277 unsigned int cmd, void __user *argp)
278{
279 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
280 struct nilfs_transaction_info ti;
281 __u64 cno;
282 int ret;
283
284 if (!capable(CAP_SYS_ADMIN))
285 return -EPERM;
286
287 ret = mnt_want_write_file(filp);
288 if (ret)
289 return ret;
290
291 ret = -EFAULT;
292 if (copy_from_user(&cno, argp, sizeof(cno)))
293 goto out;
294
295 nilfs_transaction_begin(inode->i_sb, &ti, 0);
296 ret = nilfs_cpfile_delete_checkpoint(nilfs->ns_cpfile, cno);
297 if (unlikely(ret < 0))
298 nilfs_transaction_abort(inode->i_sb);
299 else
300 nilfs_transaction_commit(inode->i_sb);
301out:
302 mnt_drop_write_file(filp);
303 return ret;
304}
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321static ssize_t
322nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
323 void *buf, size_t size, size_t nmembs)
324{
325 int ret;
326
327 down_read(&nilfs->ns_segctor_sem);
328 ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
329 size, nmembs);
330 up_read(&nilfs->ns_segctor_sem);
331 return ret;
332}
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
356 unsigned int cmd, void __user *argp)
357{
358 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
359 struct nilfs_cpstat cpstat;
360 int ret;
361
362 down_read(&nilfs->ns_segctor_sem);
363 ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
364 up_read(&nilfs->ns_segctor_sem);
365 if (ret < 0)
366 return ret;
367
368 if (copy_to_user(argp, &cpstat, sizeof(cpstat)))
369 ret = -EFAULT;
370 return ret;
371}
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388static ssize_t
389nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
390 void *buf, size_t size, size_t nmembs)
391{
392 int ret;
393
394 down_read(&nilfs->ns_segctor_sem);
395 ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size,
396 nmembs);
397 up_read(&nilfs->ns_segctor_sem);
398 return ret;
399}
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
423 unsigned int cmd, void __user *argp)
424{
425 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
426 struct nilfs_sustat sustat;
427 int ret;
428
429 down_read(&nilfs->ns_segctor_sem);
430 ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
431 up_read(&nilfs->ns_segctor_sem);
432 if (ret < 0)
433 return ret;
434
435 if (copy_to_user(argp, &sustat, sizeof(sustat)))
436 ret = -EFAULT;
437 return ret;
438}
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455static ssize_t
456nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
457 void *buf, size_t size, size_t nmembs)
458{
459 int ret;
460
461 down_read(&nilfs->ns_segctor_sem);
462 ret = nilfs_dat_get_vinfo(nilfs->ns_dat, buf, size, nmembs);
463 up_read(&nilfs->ns_segctor_sem);
464 return ret;
465}
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482static ssize_t
483nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
484 void *buf, size_t size, size_t nmembs)
485{
486 struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
487 struct nilfs_bdesc *bdescs = buf;
488 int ret, i;
489
490 down_read(&nilfs->ns_segctor_sem);
491 for (i = 0; i < nmembs; i++) {
492 ret = nilfs_bmap_lookup_at_level(bmap,
493 bdescs[i].bd_offset,
494 bdescs[i].bd_level + 1,
495 &bdescs[i].bd_blocknr);
496 if (ret < 0) {
497 if (ret != -ENOENT) {
498 up_read(&nilfs->ns_segctor_sem);
499 return ret;
500 }
501 bdescs[i].bd_blocknr = 0;
502 }
503 }
504 up_read(&nilfs->ns_segctor_sem);
505 return nmembs;
506}
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
532 unsigned int cmd, void __user *argp)
533{
534 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
535 struct nilfs_argv argv;
536 int ret;
537
538 if (copy_from_user(&argv, argp, sizeof(argv)))
539 return -EFAULT;
540
541 if (argv.v_size != sizeof(struct nilfs_bdesc))
542 return -EINVAL;
543
544 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
545 nilfs_ioctl_do_get_bdescs);
546 if (ret < 0)
547 return ret;
548
549 if (copy_to_user(argp, &argv, sizeof(argv)))
550 ret = -EFAULT;
551 return ret;
552}
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574static int nilfs_ioctl_move_inode_block(struct inode *inode,
575 struct nilfs_vdesc *vdesc,
576 struct list_head *buffers)
577{
578 struct buffer_head *bh;
579 int ret;
580
581 if (vdesc->vd_flags == 0)
582 ret = nilfs_gccache_submit_read_data(
583 inode, vdesc->vd_offset, vdesc->vd_blocknr,
584 vdesc->vd_vblocknr, &bh);
585 else
586 ret = nilfs_gccache_submit_read_node(
587 inode, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh);
588
589 if (unlikely(ret < 0)) {
590 if (ret == -ENOENT)
591 printk(KERN_CRIT
592 "%s: invalid virtual block address (%s): "
593 "ino=%llu, cno=%llu, offset=%llu, "
594 "blocknr=%llu, vblocknr=%llu\n",
595 __func__, vdesc->vd_flags ? "node" : "data",
596 (unsigned long long)vdesc->vd_ino,
597 (unsigned long long)vdesc->vd_cno,
598 (unsigned long long)vdesc->vd_offset,
599 (unsigned long long)vdesc->vd_blocknr,
600 (unsigned long long)vdesc->vd_vblocknr);
601 return ret;
602 }
603 if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
604 printk(KERN_CRIT "%s: conflicting %s buffer: ino=%llu, "
605 "cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu\n",
606 __func__, vdesc->vd_flags ? "node" : "data",
607 (unsigned long long)vdesc->vd_ino,
608 (unsigned long long)vdesc->vd_cno,
609 (unsigned long long)vdesc->vd_offset,
610 (unsigned long long)vdesc->vd_blocknr,
611 (unsigned long long)vdesc->vd_vblocknr);
612 brelse(bh);
613 return -EEXIST;
614 }
615 list_add_tail(&bh->b_assoc_buffers, buffers);
616 return 0;
617}
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632static int nilfs_ioctl_move_blocks(struct super_block *sb,
633 struct nilfs_argv *argv, void *buf)
634{
635 size_t nmembs = argv->v_nmembs;
636 struct the_nilfs *nilfs = sb->s_fs_info;
637 struct inode *inode;
638 struct nilfs_vdesc *vdesc;
639 struct buffer_head *bh, *n;
640 LIST_HEAD(buffers);
641 ino_t ino;
642 __u64 cno;
643 int i, ret;
644
645 for (i = 0, vdesc = buf; i < nmembs; ) {
646 ino = vdesc->vd_ino;
647 cno = vdesc->vd_cno;
648 inode = nilfs_iget_for_gc(sb, ino, cno);
649 if (IS_ERR(inode)) {
650 ret = PTR_ERR(inode);
651 goto failed;
652 }
653 if (list_empty(&NILFS_I(inode)->i_dirty)) {
654
655
656
657
658
659 igrab(inode);
660 list_add(&NILFS_I(inode)->i_dirty,
661 &nilfs->ns_gc_inodes);
662 }
663
664 do {
665 ret = nilfs_ioctl_move_inode_block(inode, vdesc,
666 &buffers);
667 if (unlikely(ret < 0)) {
668 iput(inode);
669 goto failed;
670 }
671 vdesc++;
672 } while (++i < nmembs &&
673 vdesc->vd_ino == ino && vdesc->vd_cno == cno);
674
675 iput(inode);
676 }
677
678 list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
679 ret = nilfs_gccache_wait_and_mark_dirty(bh);
680 if (unlikely(ret < 0)) {
681 WARN_ON(ret == -EEXIST);
682 goto failed;
683 }
684 list_del_init(&bh->b_assoc_buffers);
685 brelse(bh);
686 }
687 return nmembs;
688
689 failed:
690 list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
691 list_del_init(&bh->b_assoc_buffers);
692 brelse(bh);
693 }
694 return ret;
695}
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
717 struct nilfs_argv *argv, void *buf)
718{
719 size_t nmembs = argv->v_nmembs;
720 struct inode *cpfile = nilfs->ns_cpfile;
721 struct nilfs_period *periods = buf;
722 int ret, i;
723
724 for (i = 0; i < nmembs; i++) {
725 ret = nilfs_cpfile_delete_checkpoints(
726 cpfile, periods[i].p_start, periods[i].p_end);
727 if (ret < 0)
728 return ret;
729 }
730 return nmembs;
731}
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
752 struct nilfs_argv *argv, void *buf)
753{
754 size_t nmembs = argv->v_nmembs;
755 int ret;
756
757 ret = nilfs_dat_freev(nilfs->ns_dat, buf, nmembs);
758
759 return (ret < 0) ? ret : nmembs;
760}
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
781 struct nilfs_argv *argv, void *buf)
782{
783 size_t nmembs = argv->v_nmembs;
784 struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
785 struct nilfs_bdesc *bdescs = buf;
786 int ret, i;
787
788 for (i = 0; i < nmembs; i++) {
789
790 ret = nilfs_bmap_lookup_at_level(bmap,
791 bdescs[i].bd_offset,
792 bdescs[i].bd_level + 1,
793 &bdescs[i].bd_blocknr);
794 if (ret < 0) {
795 if (ret != -ENOENT)
796 return ret;
797 bdescs[i].bd_blocknr = 0;
798 }
799 if (bdescs[i].bd_blocknr != bdescs[i].bd_oblocknr)
800
801 continue;
802 if (bdescs[i].bd_level == 0) {
803 ret = nilfs_mdt_mark_block_dirty(nilfs->ns_dat,
804 bdescs[i].bd_offset);
805 if (ret < 0) {
806 WARN_ON(ret == -ENOENT);
807 return ret;
808 }
809 } else {
810 ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset,
811 bdescs[i].bd_level);
812 if (ret < 0) {
813 WARN_ON(ret == -ENOENT);
814 return ret;
815 }
816 }
817 }
818 return nmembs;
819}
820
821int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
822 struct nilfs_argv *argv, void **kbufs)
823{
824 const char *msg;
825 int ret;
826
827 ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
828 if (ret < 0) {
829
830
831
832
833 msg = "cannot delete checkpoints";
834 goto failed;
835 }
836 ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]);
837 if (ret < 0) {
838
839
840
841
842 msg = "cannot delete virtual blocks from DAT file";
843 goto failed;
844 }
845 ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]);
846 if (ret < 0) {
847
848
849
850 msg = "cannot mark copying blocks dirty";
851 goto failed;
852 }
853 return 0;
854
855 failed:
856 printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
857 msg, ret);
858 return ret;
859}
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
876 unsigned int cmd, void __user *argp)
877{
878 struct nilfs_argv argv[5];
879 static const size_t argsz[5] = {
880 sizeof(struct nilfs_vdesc),
881 sizeof(struct nilfs_period),
882 sizeof(__u64),
883 sizeof(struct nilfs_bdesc),
884 sizeof(__u64),
885 };
886 void __user *base;
887 void *kbufs[5];
888 struct the_nilfs *nilfs;
889 size_t len, nsegs;
890 int n, ret;
891
892 if (!capable(CAP_SYS_ADMIN))
893 return -EPERM;
894
895 ret = mnt_want_write_file(filp);
896 if (ret)
897 return ret;
898
899 ret = -EFAULT;
900 if (copy_from_user(argv, argp, sizeof(argv)))
901 goto out;
902
903 ret = -EINVAL;
904 nsegs = argv[4].v_nmembs;
905 if (argv[4].v_size != argsz[4])
906 goto out;
907 if (nsegs > UINT_MAX / sizeof(__u64))
908 goto out;
909
910
911
912
913
914
915 kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
916 nsegs * sizeof(__u64));
917 if (IS_ERR(kbufs[4])) {
918 ret = PTR_ERR(kbufs[4]);
919 goto out;
920 }
921 nilfs = inode->i_sb->s_fs_info;
922
923 for (n = 0; n < 4; n++) {
924 ret = -EINVAL;
925 if (argv[n].v_size != argsz[n])
926 goto out_free;
927
928 if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment)
929 goto out_free;
930
931 if (argv[n].v_nmembs >= UINT_MAX / argv[n].v_size)
932 goto out_free;
933
934 len = argv[n].v_size * argv[n].v_nmembs;
935 base = (void __user *)(unsigned long)argv[n].v_base;
936 if (len == 0) {
937 kbufs[n] = NULL;
938 continue;
939 }
940
941 kbufs[n] = vmalloc(len);
942 if (!kbufs[n]) {
943 ret = -ENOMEM;
944 goto out_free;
945 }
946 if (copy_from_user(kbufs[n], base, len)) {
947 ret = -EFAULT;
948 vfree(kbufs[n]);
949 goto out_free;
950 }
951 }
952
953
954
955
956
957
958
959 if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) {
960 ret = -EBUSY;
961 goto out_free;
962 }
963
964 ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]);
965 if (ret < 0)
966 printk(KERN_ERR "NILFS: GC failed during preparation: "
967 "cannot read source blocks: err=%d\n", ret);
968 else {
969 if (nilfs_sb_need_update(nilfs))
970 set_nilfs_discontinued(nilfs);
971 ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
972 }
973
974 nilfs_remove_all_gcinodes(nilfs);
975 clear_nilfs_gc_running(nilfs);
976
977out_free:
978 while (--n >= 0)
979 vfree(kbufs[n]);
980 kfree(kbufs[4]);
981out:
982 mnt_drop_write_file(filp);
983 return ret;
984}
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
1014 unsigned int cmd, void __user *argp)
1015{
1016 __u64 cno;
1017 int ret;
1018 struct the_nilfs *nilfs;
1019
1020 ret = nilfs_construct_segment(inode->i_sb);
1021 if (ret < 0)
1022 return ret;
1023
1024 nilfs = inode->i_sb->s_fs_info;
1025 ret = nilfs_flush_device(nilfs);
1026 if (ret < 0)
1027 return ret;
1028
1029 if (argp != NULL) {
1030 down_read(&nilfs->ns_segctor_sem);
1031 cno = nilfs->ns_cno - 1;
1032 up_read(&nilfs->ns_segctor_sem);
1033 if (copy_to_user(argp, &cno, sizeof(cno)))
1034 return -EFAULT;
1035 }
1036 return 0;
1037}
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047static int nilfs_ioctl_resize(struct inode *inode, struct file *filp,
1048 void __user *argp)
1049{
1050 __u64 newsize;
1051 int ret = -EPERM;
1052
1053 if (!capable(CAP_SYS_ADMIN))
1054 goto out;
1055
1056 ret = mnt_want_write_file(filp);
1057 if (ret)
1058 goto out;
1059
1060 ret = -EFAULT;
1061 if (copy_from_user(&newsize, argp, sizeof(newsize)))
1062 goto out_drop_write;
1063
1064 ret = nilfs_resize_fs(inode->i_sb, newsize);
1065
1066out_drop_write:
1067 mnt_drop_write_file(filp);
1068out:
1069 return ret;
1070}
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083static int nilfs_ioctl_trim_fs(struct inode *inode, void __user *argp)
1084{
1085 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1086 struct request_queue *q = bdev_get_queue(nilfs->ns_bdev);
1087 struct fstrim_range range;
1088 int ret;
1089
1090 if (!capable(CAP_SYS_ADMIN))
1091 return -EPERM;
1092
1093 if (!blk_queue_discard(q))
1094 return -EOPNOTSUPP;
1095
1096 if (copy_from_user(&range, argp, sizeof(range)))
1097 return -EFAULT;
1098
1099 range.minlen = max_t(u64, range.minlen, q->limits.discard_granularity);
1100
1101 down_read(&nilfs->ns_segctor_sem);
1102 ret = nilfs_sufile_trim_fs(nilfs->ns_sufile, &range);
1103 up_read(&nilfs->ns_segctor_sem);
1104
1105 if (ret < 0)
1106 return ret;
1107
1108 if (copy_to_user(argp, &range, sizeof(range)))
1109 return -EFAULT;
1110
1111 return 0;
1112}
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp)
1126{
1127 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1128 __u64 range[2];
1129 __u64 minseg, maxseg;
1130 unsigned long segbytes;
1131 int ret = -EPERM;
1132
1133 if (!capable(CAP_SYS_ADMIN))
1134 goto out;
1135
1136 ret = -EFAULT;
1137 if (copy_from_user(range, argp, sizeof(__u64[2])))
1138 goto out;
1139
1140 ret = -ERANGE;
1141 if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode))
1142 goto out;
1143
1144 segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize;
1145
1146 minseg = range[0] + segbytes - 1;
1147 do_div(minseg, segbytes);
1148 maxseg = NILFS_SB2_OFFSET_BYTES(range[1]);
1149 do_div(maxseg, segbytes);
1150 maxseg--;
1151
1152 ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg);
1153out:
1154 return ret;
1155}
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
1180 unsigned int cmd, void __user *argp,
1181 size_t membsz,
1182 ssize_t (*dofunc)(struct the_nilfs *,
1183 __u64 *, int,
1184 void *, size_t, size_t))
1185
1186{
1187 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1188 struct nilfs_argv argv;
1189 int ret;
1190
1191 if (copy_from_user(&argv, argp, sizeof(argv)))
1192 return -EFAULT;
1193
1194 if (argv.v_size < membsz)
1195 return -EINVAL;
1196
1197 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
1198 if (ret < 0)
1199 return ret;
1200
1201 if (copy_to_user(argp, &argv, sizeof(argv)))
1202 ret = -EFAULT;
1203 return ret;
1204}
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230static int nilfs_ioctl_set_suinfo(struct inode *inode, struct file *filp,
1231 unsigned int cmd, void __user *argp)
1232{
1233 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1234 struct nilfs_transaction_info ti;
1235 struct nilfs_argv argv;
1236 size_t len;
1237 void __user *base;
1238 void *kbuf;
1239 int ret;
1240
1241 if (!capable(CAP_SYS_ADMIN))
1242 return -EPERM;
1243
1244 ret = mnt_want_write_file(filp);
1245 if (ret)
1246 return ret;
1247
1248 ret = -EFAULT;
1249 if (copy_from_user(&argv, argp, sizeof(argv)))
1250 goto out;
1251
1252 ret = -EINVAL;
1253 if (argv.v_size < sizeof(struct nilfs_suinfo_update))
1254 goto out;
1255
1256 if (argv.v_nmembs > nilfs->ns_nsegments)
1257 goto out;
1258
1259 if (argv.v_nmembs >= UINT_MAX / argv.v_size)
1260 goto out;
1261
1262 len = argv.v_size * argv.v_nmembs;
1263 if (!len) {
1264 ret = 0;
1265 goto out;
1266 }
1267
1268 base = (void __user *)(unsigned long)argv.v_base;
1269 kbuf = vmalloc(len);
1270 if (!kbuf) {
1271 ret = -ENOMEM;
1272 goto out;
1273 }
1274
1275 if (copy_from_user(kbuf, base, len)) {
1276 ret = -EFAULT;
1277 goto out_free;
1278 }
1279
1280 nilfs_transaction_begin(inode->i_sb, &ti, 0);
1281 ret = nilfs_sufile_set_suinfo(nilfs->ns_sufile, kbuf, argv.v_size,
1282 argv.v_nmembs);
1283 if (unlikely(ret < 0))
1284 nilfs_transaction_abort(inode->i_sb);
1285 else
1286 nilfs_transaction_commit(inode->i_sb);
1287
1288out_free:
1289 vfree(kbuf);
1290out:
1291 mnt_drop_write_file(filp);
1292 return ret;
1293}
1294
1295long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1296{
1297 struct inode *inode = file_inode(filp);
1298 void __user *argp = (void __user *)arg;
1299
1300 switch (cmd) {
1301 case FS_IOC_GETFLAGS:
1302 return nilfs_ioctl_getflags(inode, argp);
1303 case FS_IOC_SETFLAGS:
1304 return nilfs_ioctl_setflags(inode, filp, argp);
1305 case FS_IOC_GETVERSION:
1306 return nilfs_ioctl_getversion(inode, argp);
1307 case NILFS_IOCTL_CHANGE_CPMODE:
1308 return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp);
1309 case NILFS_IOCTL_DELETE_CHECKPOINT:
1310 return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
1311 case NILFS_IOCTL_GET_CPINFO:
1312 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1313 sizeof(struct nilfs_cpinfo),
1314 nilfs_ioctl_do_get_cpinfo);
1315 case NILFS_IOCTL_GET_CPSTAT:
1316 return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
1317 case NILFS_IOCTL_GET_SUINFO:
1318 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1319 sizeof(struct nilfs_suinfo),
1320 nilfs_ioctl_do_get_suinfo);
1321 case NILFS_IOCTL_SET_SUINFO:
1322 return nilfs_ioctl_set_suinfo(inode, filp, cmd, argp);
1323 case NILFS_IOCTL_GET_SUSTAT:
1324 return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
1325 case NILFS_IOCTL_GET_VINFO:
1326 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1327 sizeof(struct nilfs_vinfo),
1328 nilfs_ioctl_do_get_vinfo);
1329 case NILFS_IOCTL_GET_BDESCS:
1330 return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
1331 case NILFS_IOCTL_CLEAN_SEGMENTS:
1332 return nilfs_ioctl_clean_segments(inode, filp, cmd, argp);
1333 case NILFS_IOCTL_SYNC:
1334 return nilfs_ioctl_sync(inode, filp, cmd, argp);
1335 case NILFS_IOCTL_RESIZE:
1336 return nilfs_ioctl_resize(inode, filp, argp);
1337 case NILFS_IOCTL_SET_ALLOC_RANGE:
1338 return nilfs_ioctl_set_alloc_range(inode, argp);
1339 case FITRIM:
1340 return nilfs_ioctl_trim_fs(inode, argp);
1341 default:
1342 return -ENOTTY;
1343 }
1344}
1345
1346#ifdef CONFIG_COMPAT
1347long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1348{
1349 switch (cmd) {
1350 case FS_IOC32_GETFLAGS:
1351 cmd = FS_IOC_GETFLAGS;
1352 break;
1353 case FS_IOC32_SETFLAGS:
1354 cmd = FS_IOC_SETFLAGS;
1355 break;
1356 case FS_IOC32_GETVERSION:
1357 cmd = FS_IOC_GETVERSION;
1358 break;
1359 case NILFS_IOCTL_CHANGE_CPMODE:
1360 case NILFS_IOCTL_DELETE_CHECKPOINT:
1361 case NILFS_IOCTL_GET_CPINFO:
1362 case NILFS_IOCTL_GET_CPSTAT:
1363 case NILFS_IOCTL_GET_SUINFO:
1364 case NILFS_IOCTL_SET_SUINFO:
1365 case NILFS_IOCTL_GET_SUSTAT:
1366 case NILFS_IOCTL_GET_VINFO:
1367 case NILFS_IOCTL_GET_BDESCS:
1368 case NILFS_IOCTL_CLEAN_SEGMENTS:
1369 case NILFS_IOCTL_SYNC:
1370 case NILFS_IOCTL_RESIZE:
1371 case NILFS_IOCTL_SET_ALLOC_RANGE:
1372 break;
1373 default:
1374 return -ENOIOCTLCMD;
1375 }
1376 return nilfs_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
1377}
1378#endif
1379