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