0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/fs.h>
0011 #include <linux/wait.h>
0012 #include <linux/slab.h>
0013 #include <linux/capability.h> /* capable() */
0014 #include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
0015 #include <linux/vmalloc.h>
0016 #include <linux/compat.h> /* compat_ptr() */
0017 #include <linux/mount.h> /* mnt_want_write_file(), mnt_drop_write_file() */
0018 #include <linux/buffer_head.h>
0019 #include <linux/fileattr.h>
0020 #include "nilfs.h"
0021 #include "segment.h"
0022 #include "bmap.h"
0023 #include "cpfile.h"
0024 #include "sufile.h"
0025 #include "dat.h"
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
0048 struct nilfs_argv *argv, int dir,
0049 ssize_t (*dofunc)(struct the_nilfs *,
0050 __u64 *, int,
0051 void *, size_t, size_t))
0052 {
0053 void *buf;
0054 void __user *base = (void __user *)(unsigned long)argv->v_base;
0055 size_t maxmembs, total, n;
0056 ssize_t nr;
0057 int ret, i;
0058 __u64 pos, ppos;
0059
0060 if (argv->v_nmembs == 0)
0061 return 0;
0062
0063 if (argv->v_size > PAGE_SIZE)
0064 return -EINVAL;
0065
0066
0067
0068
0069
0070
0071 if (argv->v_index > ~(__u64)0 - argv->v_nmembs)
0072 return -EINVAL;
0073
0074 buf = (void *)__get_free_pages(GFP_NOFS, 0);
0075 if (unlikely(!buf))
0076 return -ENOMEM;
0077 maxmembs = PAGE_SIZE / argv->v_size;
0078
0079 ret = 0;
0080 total = 0;
0081 pos = argv->v_index;
0082 for (i = 0; i < argv->v_nmembs; i += n) {
0083 n = (argv->v_nmembs - i < maxmembs) ?
0084 argv->v_nmembs - i : maxmembs;
0085 if ((dir & _IOC_WRITE) &&
0086 copy_from_user(buf, base + argv->v_size * i,
0087 argv->v_size * n)) {
0088 ret = -EFAULT;
0089 break;
0090 }
0091 ppos = pos;
0092 nr = dofunc(nilfs, &pos, argv->v_flags, buf, argv->v_size,
0093 n);
0094 if (nr < 0) {
0095 ret = nr;
0096 break;
0097 }
0098 if ((dir & _IOC_READ) &&
0099 copy_to_user(base + argv->v_size * i, buf,
0100 argv->v_size * nr)) {
0101 ret = -EFAULT;
0102 break;
0103 }
0104 total += nr;
0105 if ((size_t)nr < n)
0106 break;
0107 if (pos == ppos)
0108 pos += n;
0109 }
0110 argv->v_nmembs = total;
0111
0112 free_pages((unsigned long)buf, 0);
0113 return ret;
0114 }
0115
0116
0117
0118
0119 int nilfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
0120 {
0121 struct inode *inode = d_inode(dentry);
0122
0123 fileattr_fill_flags(fa, NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE);
0124
0125 return 0;
0126 }
0127
0128
0129
0130
0131 int nilfs_fileattr_set(struct user_namespace *mnt_userns,
0132 struct dentry *dentry, struct fileattr *fa)
0133 {
0134 struct inode *inode = d_inode(dentry);
0135 struct nilfs_transaction_info ti;
0136 unsigned int flags, oldflags;
0137 int ret;
0138
0139 if (fileattr_has_fsx(fa))
0140 return -EOPNOTSUPP;
0141
0142 flags = nilfs_mask_flags(inode->i_mode, fa->flags);
0143
0144 ret = nilfs_transaction_begin(inode->i_sb, &ti, 0);
0145 if (ret)
0146 return ret;
0147
0148 oldflags = NILFS_I(inode)->i_flags & ~FS_FL_USER_MODIFIABLE;
0149 NILFS_I(inode)->i_flags = oldflags | (flags & FS_FL_USER_MODIFIABLE);
0150
0151 nilfs_set_inode_flags(inode);
0152 inode->i_ctime = current_time(inode);
0153 if (IS_SYNC(inode))
0154 nilfs_set_transaction_flag(NILFS_TI_SYNC);
0155
0156 nilfs_mark_inode_dirty(inode);
0157 return nilfs_transaction_commit(inode->i_sb);
0158 }
0159
0160
0161
0162
0163 static int nilfs_ioctl_getversion(struct inode *inode, void __user *argp)
0164 {
0165 return put_user(inode->i_generation, (int __user *)argp);
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
0188 unsigned int cmd, void __user *argp)
0189 {
0190 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
0191 struct nilfs_transaction_info ti;
0192 struct nilfs_cpmode cpmode;
0193 int ret;
0194
0195 if (!capable(CAP_SYS_ADMIN))
0196 return -EPERM;
0197
0198 ret = mnt_want_write_file(filp);
0199 if (ret)
0200 return ret;
0201
0202 ret = -EFAULT;
0203 if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
0204 goto out;
0205
0206 mutex_lock(&nilfs->ns_snapshot_mount_mutex);
0207
0208 nilfs_transaction_begin(inode->i_sb, &ti, 0);
0209 ret = nilfs_cpfile_change_cpmode(
0210 nilfs->ns_cpfile, cpmode.cm_cno, cpmode.cm_mode);
0211 if (unlikely(ret < 0))
0212 nilfs_transaction_abort(inode->i_sb);
0213 else
0214 nilfs_transaction_commit(inode->i_sb);
0215
0216 mutex_unlock(&nilfs->ns_snapshot_mount_mutex);
0217 out:
0218 mnt_drop_write_file(filp);
0219 return ret;
0220 }
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241 static int
0242 nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
0243 unsigned int cmd, void __user *argp)
0244 {
0245 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
0246 struct nilfs_transaction_info ti;
0247 __u64 cno;
0248 int ret;
0249
0250 if (!capable(CAP_SYS_ADMIN))
0251 return -EPERM;
0252
0253 ret = mnt_want_write_file(filp);
0254 if (ret)
0255 return ret;
0256
0257 ret = -EFAULT;
0258 if (copy_from_user(&cno, argp, sizeof(cno)))
0259 goto out;
0260
0261 nilfs_transaction_begin(inode->i_sb, &ti, 0);
0262 ret = nilfs_cpfile_delete_checkpoint(nilfs->ns_cpfile, cno);
0263 if (unlikely(ret < 0))
0264 nilfs_transaction_abort(inode->i_sb);
0265 else
0266 nilfs_transaction_commit(inode->i_sb);
0267 out:
0268 mnt_drop_write_file(filp);
0269 return ret;
0270 }
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 static ssize_t
0288 nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
0289 void *buf, size_t size, size_t nmembs)
0290 {
0291 int ret;
0292
0293 down_read(&nilfs->ns_segctor_sem);
0294 ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
0295 size, nmembs);
0296 up_read(&nilfs->ns_segctor_sem);
0297 return ret;
0298 }
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321 static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
0322 unsigned int cmd, void __user *argp)
0323 {
0324 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
0325 struct nilfs_cpstat cpstat;
0326 int ret;
0327
0328 down_read(&nilfs->ns_segctor_sem);
0329 ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
0330 up_read(&nilfs->ns_segctor_sem);
0331 if (ret < 0)
0332 return ret;
0333
0334 if (copy_to_user(argp, &cpstat, sizeof(cpstat)))
0335 ret = -EFAULT;
0336 return ret;
0337 }
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 static ssize_t
0355 nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
0356 void *buf, size_t size, size_t nmembs)
0357 {
0358 int ret;
0359
0360 down_read(&nilfs->ns_segctor_sem);
0361 ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size,
0362 nmembs);
0363 up_read(&nilfs->ns_segctor_sem);
0364 return ret;
0365 }
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388 static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
0389 unsigned int cmd, void __user *argp)
0390 {
0391 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
0392 struct nilfs_sustat sustat;
0393 int ret;
0394
0395 down_read(&nilfs->ns_segctor_sem);
0396 ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
0397 up_read(&nilfs->ns_segctor_sem);
0398 if (ret < 0)
0399 return ret;
0400
0401 if (copy_to_user(argp, &sustat, sizeof(sustat)))
0402 ret = -EFAULT;
0403 return ret;
0404 }
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 static ssize_t
0422 nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
0423 void *buf, size_t size, size_t nmembs)
0424 {
0425 int ret;
0426
0427 down_read(&nilfs->ns_segctor_sem);
0428 ret = nilfs_dat_get_vinfo(nilfs->ns_dat, buf, size, nmembs);
0429 up_read(&nilfs->ns_segctor_sem);
0430 return ret;
0431 }
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448 static ssize_t
0449 nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
0450 void *buf, size_t size, size_t nmembs)
0451 {
0452 struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
0453 struct nilfs_bdesc *bdescs = buf;
0454 int ret, i;
0455
0456 down_read(&nilfs->ns_segctor_sem);
0457 for (i = 0; i < nmembs; i++) {
0458 ret = nilfs_bmap_lookup_at_level(bmap,
0459 bdescs[i].bd_offset,
0460 bdescs[i].bd_level + 1,
0461 &bdescs[i].bd_blocknr);
0462 if (ret < 0) {
0463 if (ret != -ENOENT) {
0464 up_read(&nilfs->ns_segctor_sem);
0465 return ret;
0466 }
0467 bdescs[i].bd_blocknr = 0;
0468 }
0469 }
0470 up_read(&nilfs->ns_segctor_sem);
0471 return nmembs;
0472 }
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497 static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
0498 unsigned int cmd, void __user *argp)
0499 {
0500 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
0501 struct nilfs_argv argv;
0502 int ret;
0503
0504 if (copy_from_user(&argv, argp, sizeof(argv)))
0505 return -EFAULT;
0506
0507 if (argv.v_size != sizeof(struct nilfs_bdesc))
0508 return -EINVAL;
0509
0510 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
0511 nilfs_ioctl_do_get_bdescs);
0512 if (ret < 0)
0513 return ret;
0514
0515 if (copy_to_user(argp, &argv, sizeof(argv)))
0516 ret = -EFAULT;
0517 return ret;
0518 }
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540 static int nilfs_ioctl_move_inode_block(struct inode *inode,
0541 struct nilfs_vdesc *vdesc,
0542 struct list_head *buffers)
0543 {
0544 struct buffer_head *bh;
0545 int ret;
0546
0547 if (vdesc->vd_flags == 0)
0548 ret = nilfs_gccache_submit_read_data(
0549 inode, vdesc->vd_offset, vdesc->vd_blocknr,
0550 vdesc->vd_vblocknr, &bh);
0551 else
0552 ret = nilfs_gccache_submit_read_node(
0553 inode, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh);
0554
0555 if (unlikely(ret < 0)) {
0556 if (ret == -ENOENT)
0557 nilfs_crit(inode->i_sb,
0558 "%s: invalid virtual block address (%s): ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
0559 __func__, vdesc->vd_flags ? "node" : "data",
0560 (unsigned long long)vdesc->vd_ino,
0561 (unsigned long long)vdesc->vd_cno,
0562 (unsigned long long)vdesc->vd_offset,
0563 (unsigned long long)vdesc->vd_blocknr,
0564 (unsigned long long)vdesc->vd_vblocknr);
0565 return ret;
0566 }
0567 if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
0568 nilfs_crit(inode->i_sb,
0569 "%s: conflicting %s buffer: ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
0570 __func__, vdesc->vd_flags ? "node" : "data",
0571 (unsigned long long)vdesc->vd_ino,
0572 (unsigned long long)vdesc->vd_cno,
0573 (unsigned long long)vdesc->vd_offset,
0574 (unsigned long long)vdesc->vd_blocknr,
0575 (unsigned long long)vdesc->vd_vblocknr);
0576 brelse(bh);
0577 return -EEXIST;
0578 }
0579 list_add_tail(&bh->b_assoc_buffers, buffers);
0580 return 0;
0581 }
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596 static int nilfs_ioctl_move_blocks(struct super_block *sb,
0597 struct nilfs_argv *argv, void *buf)
0598 {
0599 size_t nmembs = argv->v_nmembs;
0600 struct the_nilfs *nilfs = sb->s_fs_info;
0601 struct inode *inode;
0602 struct nilfs_vdesc *vdesc;
0603 struct buffer_head *bh, *n;
0604 LIST_HEAD(buffers);
0605 ino_t ino;
0606 __u64 cno;
0607 int i, ret;
0608
0609 for (i = 0, vdesc = buf; i < nmembs; ) {
0610 ino = vdesc->vd_ino;
0611 cno = vdesc->vd_cno;
0612 inode = nilfs_iget_for_gc(sb, ino, cno);
0613 if (IS_ERR(inode)) {
0614 ret = PTR_ERR(inode);
0615 goto failed;
0616 }
0617 if (list_empty(&NILFS_I(inode)->i_dirty)) {
0618
0619
0620
0621
0622
0623 igrab(inode);
0624 list_add(&NILFS_I(inode)->i_dirty,
0625 &nilfs->ns_gc_inodes);
0626 }
0627
0628 do {
0629 ret = nilfs_ioctl_move_inode_block(inode, vdesc,
0630 &buffers);
0631 if (unlikely(ret < 0)) {
0632 iput(inode);
0633 goto failed;
0634 }
0635 vdesc++;
0636 } while (++i < nmembs &&
0637 vdesc->vd_ino == ino && vdesc->vd_cno == cno);
0638
0639 iput(inode);
0640 }
0641
0642 list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
0643 ret = nilfs_gccache_wait_and_mark_dirty(bh);
0644 if (unlikely(ret < 0)) {
0645 WARN_ON(ret == -EEXIST);
0646 goto failed;
0647 }
0648 list_del_init(&bh->b_assoc_buffers);
0649 brelse(bh);
0650 }
0651 return nmembs;
0652
0653 failed:
0654 list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
0655 list_del_init(&bh->b_assoc_buffers);
0656 brelse(bh);
0657 }
0658 return ret;
0659 }
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680 static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
0681 struct nilfs_argv *argv, void *buf)
0682 {
0683 size_t nmembs = argv->v_nmembs;
0684 struct inode *cpfile = nilfs->ns_cpfile;
0685 struct nilfs_period *periods = buf;
0686 int ret, i;
0687
0688 for (i = 0; i < nmembs; i++) {
0689 ret = nilfs_cpfile_delete_checkpoints(
0690 cpfile, periods[i].p_start, periods[i].p_end);
0691 if (ret < 0)
0692 return ret;
0693 }
0694 return nmembs;
0695 }
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715 static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
0716 struct nilfs_argv *argv, void *buf)
0717 {
0718 size_t nmembs = argv->v_nmembs;
0719 int ret;
0720
0721 ret = nilfs_dat_freev(nilfs->ns_dat, buf, nmembs);
0722
0723 return (ret < 0) ? ret : nmembs;
0724 }
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744 static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
0745 struct nilfs_argv *argv, void *buf)
0746 {
0747 size_t nmembs = argv->v_nmembs;
0748 struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
0749 struct nilfs_bdesc *bdescs = buf;
0750 struct buffer_head *bh;
0751 int ret, i;
0752
0753 for (i = 0; i < nmembs; i++) {
0754
0755 ret = nilfs_bmap_lookup_at_level(bmap,
0756 bdescs[i].bd_offset,
0757 bdescs[i].bd_level + 1,
0758 &bdescs[i].bd_blocknr);
0759 if (ret < 0) {
0760 if (ret != -ENOENT)
0761 return ret;
0762 bdescs[i].bd_blocknr = 0;
0763 }
0764 if (bdescs[i].bd_blocknr != bdescs[i].bd_oblocknr)
0765
0766 continue;
0767 if (bdescs[i].bd_level == 0) {
0768 ret = nilfs_mdt_get_block(nilfs->ns_dat,
0769 bdescs[i].bd_offset,
0770 false, NULL, &bh);
0771 if (unlikely(ret)) {
0772 WARN_ON(ret == -ENOENT);
0773 return ret;
0774 }
0775 mark_buffer_dirty(bh);
0776 nilfs_mdt_mark_dirty(nilfs->ns_dat);
0777 put_bh(bh);
0778 } else {
0779 ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset,
0780 bdescs[i].bd_level);
0781 if (ret < 0) {
0782 WARN_ON(ret == -ENOENT);
0783 return ret;
0784 }
0785 }
0786 }
0787 return nmembs;
0788 }
0789
0790 int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
0791 struct nilfs_argv *argv, void **kbufs)
0792 {
0793 const char *msg;
0794 int ret;
0795
0796 ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
0797 if (ret < 0) {
0798
0799
0800
0801
0802 msg = "cannot delete checkpoints";
0803 goto failed;
0804 }
0805 ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]);
0806 if (ret < 0) {
0807
0808
0809
0810
0811 msg = "cannot delete virtual blocks from DAT file";
0812 goto failed;
0813 }
0814 ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]);
0815 if (ret < 0) {
0816
0817
0818
0819 msg = "cannot mark copying blocks dirty";
0820 goto failed;
0821 }
0822 return 0;
0823
0824 failed:
0825 nilfs_err(nilfs->ns_sb, "error %d preparing GC: %s", ret, msg);
0826 return ret;
0827 }
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843 static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
0844 unsigned int cmd, void __user *argp)
0845 {
0846 struct nilfs_argv argv[5];
0847 static const size_t argsz[5] = {
0848 sizeof(struct nilfs_vdesc),
0849 sizeof(struct nilfs_period),
0850 sizeof(__u64),
0851 sizeof(struct nilfs_bdesc),
0852 sizeof(__u64),
0853 };
0854 void __user *base;
0855 void *kbufs[5];
0856 struct the_nilfs *nilfs;
0857 size_t len, nsegs;
0858 int n, ret;
0859
0860 if (!capable(CAP_SYS_ADMIN))
0861 return -EPERM;
0862
0863 ret = mnt_want_write_file(filp);
0864 if (ret)
0865 return ret;
0866
0867 ret = -EFAULT;
0868 if (copy_from_user(argv, argp, sizeof(argv)))
0869 goto out;
0870
0871 ret = -EINVAL;
0872 nsegs = argv[4].v_nmembs;
0873 if (argv[4].v_size != argsz[4])
0874 goto out;
0875 if (nsegs > UINT_MAX / sizeof(__u64))
0876 goto out;
0877
0878
0879
0880
0881
0882
0883 kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
0884 nsegs * sizeof(__u64));
0885 if (IS_ERR(kbufs[4])) {
0886 ret = PTR_ERR(kbufs[4]);
0887 goto out;
0888 }
0889 nilfs = inode->i_sb->s_fs_info;
0890
0891 for (n = 0; n < 4; n++) {
0892 ret = -EINVAL;
0893 if (argv[n].v_size != argsz[n])
0894 goto out_free;
0895
0896 if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment)
0897 goto out_free;
0898
0899 if (argv[n].v_nmembs >= UINT_MAX / argv[n].v_size)
0900 goto out_free;
0901
0902 len = argv[n].v_size * argv[n].v_nmembs;
0903 base = (void __user *)(unsigned long)argv[n].v_base;
0904 if (len == 0) {
0905 kbufs[n] = NULL;
0906 continue;
0907 }
0908
0909 kbufs[n] = vmalloc(len);
0910 if (!kbufs[n]) {
0911 ret = -ENOMEM;
0912 goto out_free;
0913 }
0914 if (copy_from_user(kbufs[n], base, len)) {
0915 ret = -EFAULT;
0916 vfree(kbufs[n]);
0917 goto out_free;
0918 }
0919 }
0920
0921
0922
0923
0924
0925
0926
0927 if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) {
0928 ret = -EBUSY;
0929 goto out_free;
0930 }
0931
0932 ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]);
0933 if (ret < 0) {
0934 nilfs_err(inode->i_sb,
0935 "error %d preparing GC: cannot read source blocks",
0936 ret);
0937 } else {
0938 if (nilfs_sb_need_update(nilfs))
0939 set_nilfs_discontinued(nilfs);
0940 ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
0941 }
0942
0943 nilfs_remove_all_gcinodes(nilfs);
0944 clear_nilfs_gc_running(nilfs);
0945
0946 out_free:
0947 while (--n >= 0)
0948 vfree(kbufs[n]);
0949 kfree(kbufs[4]);
0950 out:
0951 mnt_drop_write_file(filp);
0952 return ret;
0953 }
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982 static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
0983 unsigned int cmd, void __user *argp)
0984 {
0985 __u64 cno;
0986 int ret;
0987 struct the_nilfs *nilfs;
0988
0989 ret = nilfs_construct_segment(inode->i_sb);
0990 if (ret < 0)
0991 return ret;
0992
0993 nilfs = inode->i_sb->s_fs_info;
0994 ret = nilfs_flush_device(nilfs);
0995 if (ret < 0)
0996 return ret;
0997
0998 if (argp != NULL) {
0999 down_read(&nilfs->ns_segctor_sem);
1000 cno = nilfs->ns_cno - 1;
1001 up_read(&nilfs->ns_segctor_sem);
1002 if (copy_to_user(argp, &cno, sizeof(cno)))
1003 return -EFAULT;
1004 }
1005 return 0;
1006 }
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 static int nilfs_ioctl_resize(struct inode *inode, struct file *filp,
1017 void __user *argp)
1018 {
1019 __u64 newsize;
1020 int ret = -EPERM;
1021
1022 if (!capable(CAP_SYS_ADMIN))
1023 goto out;
1024
1025 ret = mnt_want_write_file(filp);
1026 if (ret)
1027 goto out;
1028
1029 ret = -EFAULT;
1030 if (copy_from_user(&newsize, argp, sizeof(newsize)))
1031 goto out_drop_write;
1032
1033 ret = nilfs_resize_fs(inode->i_sb, newsize);
1034
1035 out_drop_write:
1036 mnt_drop_write_file(filp);
1037 out:
1038 return ret;
1039 }
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052 static int nilfs_ioctl_trim_fs(struct inode *inode, void __user *argp)
1053 {
1054 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1055 struct fstrim_range range;
1056 int ret;
1057
1058 if (!capable(CAP_SYS_ADMIN))
1059 return -EPERM;
1060
1061 if (!bdev_max_discard_sectors(nilfs->ns_bdev))
1062 return -EOPNOTSUPP;
1063
1064 if (copy_from_user(&range, argp, sizeof(range)))
1065 return -EFAULT;
1066
1067 range.minlen = max_t(u64, range.minlen,
1068 bdev_discard_granularity(nilfs->ns_bdev));
1069
1070 down_read(&nilfs->ns_segctor_sem);
1071 ret = nilfs_sufile_trim_fs(nilfs->ns_sufile, &range);
1072 up_read(&nilfs->ns_segctor_sem);
1073
1074 if (ret < 0)
1075 return ret;
1076
1077 if (copy_to_user(argp, &range, sizeof(range)))
1078 return -EFAULT;
1079
1080 return 0;
1081 }
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094 static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp)
1095 {
1096 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1097 __u64 range[2];
1098 __u64 minseg, maxseg;
1099 unsigned long segbytes;
1100 int ret = -EPERM;
1101
1102 if (!capable(CAP_SYS_ADMIN))
1103 goto out;
1104
1105 ret = -EFAULT;
1106 if (copy_from_user(range, argp, sizeof(__u64[2])))
1107 goto out;
1108
1109 ret = -ERANGE;
1110 if (range[1] > bdev_nr_bytes(inode->i_sb->s_bdev))
1111 goto out;
1112
1113 segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize;
1114
1115 minseg = range[0] + segbytes - 1;
1116 do_div(minseg, segbytes);
1117 maxseg = NILFS_SB2_OFFSET_BYTES(range[1]);
1118 do_div(maxseg, segbytes);
1119 maxseg--;
1120
1121 ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg);
1122 out:
1123 return ret;
1124 }
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148 static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
1149 unsigned int cmd, void __user *argp,
1150 size_t membsz,
1151 ssize_t (*dofunc)(struct the_nilfs *,
1152 __u64 *, int,
1153 void *, size_t, size_t))
1154
1155 {
1156 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1157 struct nilfs_argv argv;
1158 int ret;
1159
1160 if (copy_from_user(&argv, argp, sizeof(argv)))
1161 return -EFAULT;
1162
1163 if (argv.v_size < membsz)
1164 return -EINVAL;
1165
1166 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
1167 if (ret < 0)
1168 return ret;
1169
1170 if (copy_to_user(argp, &argv, sizeof(argv)))
1171 ret = -EFAULT;
1172 return ret;
1173 }
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199 static int nilfs_ioctl_set_suinfo(struct inode *inode, struct file *filp,
1200 unsigned int cmd, void __user *argp)
1201 {
1202 struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1203 struct nilfs_transaction_info ti;
1204 struct nilfs_argv argv;
1205 size_t len;
1206 void __user *base;
1207 void *kbuf;
1208 int ret;
1209
1210 if (!capable(CAP_SYS_ADMIN))
1211 return -EPERM;
1212
1213 ret = mnt_want_write_file(filp);
1214 if (ret)
1215 return ret;
1216
1217 ret = -EFAULT;
1218 if (copy_from_user(&argv, argp, sizeof(argv)))
1219 goto out;
1220
1221 ret = -EINVAL;
1222 if (argv.v_size < sizeof(struct nilfs_suinfo_update))
1223 goto out;
1224
1225 if (argv.v_nmembs > nilfs->ns_nsegments)
1226 goto out;
1227
1228 if (argv.v_nmembs >= UINT_MAX / argv.v_size)
1229 goto out;
1230
1231 len = argv.v_size * argv.v_nmembs;
1232 if (!len) {
1233 ret = 0;
1234 goto out;
1235 }
1236
1237 base = (void __user *)(unsigned long)argv.v_base;
1238 kbuf = vmalloc(len);
1239 if (!kbuf) {
1240 ret = -ENOMEM;
1241 goto out;
1242 }
1243
1244 if (copy_from_user(kbuf, base, len)) {
1245 ret = -EFAULT;
1246 goto out_free;
1247 }
1248
1249 nilfs_transaction_begin(inode->i_sb, &ti, 0);
1250 ret = nilfs_sufile_set_suinfo(nilfs->ns_sufile, kbuf, argv.v_size,
1251 argv.v_nmembs);
1252 if (unlikely(ret < 0))
1253 nilfs_transaction_abort(inode->i_sb);
1254 else
1255 nilfs_transaction_commit(inode->i_sb);
1256
1257 out_free:
1258 vfree(kbuf);
1259 out:
1260 mnt_drop_write_file(filp);
1261 return ret;
1262 }
1263
1264 long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1265 {
1266 struct inode *inode = file_inode(filp);
1267 void __user *argp = (void __user *)arg;
1268
1269 switch (cmd) {
1270 case FS_IOC_GETVERSION:
1271 return nilfs_ioctl_getversion(inode, argp);
1272 case NILFS_IOCTL_CHANGE_CPMODE:
1273 return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp);
1274 case NILFS_IOCTL_DELETE_CHECKPOINT:
1275 return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
1276 case NILFS_IOCTL_GET_CPINFO:
1277 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1278 sizeof(struct nilfs_cpinfo),
1279 nilfs_ioctl_do_get_cpinfo);
1280 case NILFS_IOCTL_GET_CPSTAT:
1281 return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
1282 case NILFS_IOCTL_GET_SUINFO:
1283 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1284 sizeof(struct nilfs_suinfo),
1285 nilfs_ioctl_do_get_suinfo);
1286 case NILFS_IOCTL_SET_SUINFO:
1287 return nilfs_ioctl_set_suinfo(inode, filp, cmd, argp);
1288 case NILFS_IOCTL_GET_SUSTAT:
1289 return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
1290 case NILFS_IOCTL_GET_VINFO:
1291 return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1292 sizeof(struct nilfs_vinfo),
1293 nilfs_ioctl_do_get_vinfo);
1294 case NILFS_IOCTL_GET_BDESCS:
1295 return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
1296 case NILFS_IOCTL_CLEAN_SEGMENTS:
1297 return nilfs_ioctl_clean_segments(inode, filp, cmd, argp);
1298 case NILFS_IOCTL_SYNC:
1299 return nilfs_ioctl_sync(inode, filp, cmd, argp);
1300 case NILFS_IOCTL_RESIZE:
1301 return nilfs_ioctl_resize(inode, filp, argp);
1302 case NILFS_IOCTL_SET_ALLOC_RANGE:
1303 return nilfs_ioctl_set_alloc_range(inode, argp);
1304 case FITRIM:
1305 return nilfs_ioctl_trim_fs(inode, argp);
1306 default:
1307 return -ENOTTY;
1308 }
1309 }
1310
1311 #ifdef CONFIG_COMPAT
1312 long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1313 {
1314 switch (cmd) {
1315 case FS_IOC32_GETVERSION:
1316 cmd = FS_IOC_GETVERSION;
1317 break;
1318 case NILFS_IOCTL_CHANGE_CPMODE:
1319 case NILFS_IOCTL_DELETE_CHECKPOINT:
1320 case NILFS_IOCTL_GET_CPINFO:
1321 case NILFS_IOCTL_GET_CPSTAT:
1322 case NILFS_IOCTL_GET_SUINFO:
1323 case NILFS_IOCTL_SET_SUINFO:
1324 case NILFS_IOCTL_GET_SUSTAT:
1325 case NILFS_IOCTL_GET_VINFO:
1326 case NILFS_IOCTL_GET_BDESCS:
1327 case NILFS_IOCTL_CLEAN_SEGMENTS:
1328 case NILFS_IOCTL_SYNC:
1329 case NILFS_IOCTL_RESIZE:
1330 case NILFS_IOCTL_SET_ALLOC_RANGE:
1331 case FITRIM:
1332 break;
1333 default:
1334 return -ENOIOCTLCMD;
1335 }
1336 return nilfs_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
1337 }
1338 #endif