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