Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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