VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100    1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700    2) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700    3)  *  linux/fs/ioctl.c
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700    4)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700    5)  *  Copyright (C) 1991, 1992  Linus Torvalds
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700    6)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700    7) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700    8) #include <linux/syscalls.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700    9) #include <linux/mm.h>
16f7e0fe2ecc3 (Randy Dunlap       2006-01-11 12:17:46 -0800   10) #include <linux/capability.h>
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200   11) #include <linux/compat.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   12) #include <linux/file.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   13) #include <linux/fs.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   14) #include <linux/security.h>
630d9c47274aa (Paul Gortmaker     2011-11-16 23:57:37 -0500   15) #include <linux/export.h>
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800   16) #include <linux/uaccess.h>
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400   17) #include <linux/writeback.h>
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400   18) #include <linux/buffer_head.h>
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400   19) #include <linux/falloc.h>
f361bf4a66c9b (Ingo Molnar        2017-02-03 23:47:37 +0100   20) #include <linux/sched/signal.h>
10c5db286452b (Christoph Hellwig  2020-05-23 09:30:11 +0200   21) #include <linux/fiemap.h>
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200   22) #include <linux/mount.h>
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200   23) #include <linux/fscrypt.h>
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200   24) #include <linux/fileattr.h>
f361bf4a66c9b (Ingo Molnar        2017-02-03 23:47:37 +0100   25) 
66cf191f3eae4 (Al Viro            2016-01-07 09:53:30 -0500   26) #include "internal.h"
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   27) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   28) #include <asm/ioctls.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   29) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400   30) /* So that the fiemap access checks can't overflow on 32 bit machines. */
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400   31) #define FIEMAP_MAX_EXTENTS	(UINT_MAX / sizeof(struct fiemap_extent))
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400   32) 
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800   33) /**
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800   34)  * vfs_ioctl - call filesystem specific ioctl methods
f6a4c8bdb3037 (Christoph Hellwig  2008-02-09 00:10:16 -0800   35)  * @filp:	open file to invoke ioctl method on
f6a4c8bdb3037 (Christoph Hellwig  2008-02-09 00:10:16 -0800   36)  * @cmd:	ioctl command to execute
f6a4c8bdb3037 (Christoph Hellwig  2008-02-09 00:10:16 -0800   37)  * @arg:	command-specific argument for ioctl
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800   38)  *
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800   39)  * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800   40)  * returns -ENOTTY.
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800   41)  *
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800   42)  * Returns 0 on success, -errno on error.
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800   43)  */
66cf191f3eae4 (Al Viro            2016-01-07 09:53:30 -0500   44) long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   45) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   46) 	int error = -ENOTTY;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   47) 
72c2d53192004 (Al Viro            2013-09-22 16:27:52 -0400   48) 	if (!filp->f_op->unlocked_ioctl)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   49) 		goto out;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   50) 
b19dd42faf413 (Arnd Bergmann      2010-07-04 00:15:10 +0200   51) 	error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
b19dd42faf413 (Arnd Bergmann      2010-07-04 00:15:10 +0200   52) 	if (error == -ENOIOCTLCMD)
07d106d0a33d6 (Linus Torvalds     2012-01-05 15:40:12 -0800   53) 		error = -ENOTTY;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   54)  out:
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   55) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   56) }
9df6702ad0e85 (Miklos Szeredi     2018-07-18 15:44:40 +0200   57) EXPORT_SYMBOL(vfs_ioctl);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   58) 
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800   59) static int ioctl_fibmap(struct file *filp, int __user *p)
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800   60) {
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   61) 	struct inode *inode = file_inode(filp);
b75dfde121299 (Ritesh Harjani     2020-04-30 07:57:46 -0700   62) 	struct super_block *sb = inode->i_sb;
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   63) 	int error, ur_block;
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   64) 	sector_t block;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800   65) 
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800   66) 	if (!capable(CAP_SYS_RAWIO))
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800   67) 		return -EPERM;
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   68) 
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   69) 	error = get_user(ur_block, p);
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   70) 	if (error)
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   71) 		return error;
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   72) 
324282c0252a4 (Carlos Maiolino    2020-01-09 14:30:45 +0100   73) 	if (ur_block < 0)
324282c0252a4 (Carlos Maiolino    2020-01-09 14:30:45 +0100   74) 		return -EINVAL;
324282c0252a4 (Carlos Maiolino    2020-01-09 14:30:45 +0100   75) 
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   76) 	block = ur_block;
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   77) 	error = bmap(inode, &block);
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   78) 
b75dfde121299 (Ritesh Harjani     2020-04-30 07:57:46 -0700   79) 	if (block > INT_MAX) {
b75dfde121299 (Ritesh Harjani     2020-04-30 07:57:46 -0700   80) 		error = -ERANGE;
b75dfde121299 (Ritesh Harjani     2020-04-30 07:57:46 -0700   81) 		pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n",
b75dfde121299 (Ritesh Harjani     2020-04-30 07:57:46 -0700   82) 				    current->comm, task_pid_nr(current),
b75dfde121299 (Ritesh Harjani     2020-04-30 07:57:46 -0700   83) 				    sb->s_id, filp);
b75dfde121299 (Ritesh Harjani     2020-04-30 07:57:46 -0700   84) 	}
b75dfde121299 (Ritesh Harjani     2020-04-30 07:57:46 -0700   85) 
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   86) 	if (error)
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   87) 		ur_block = 0;
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   88) 	else
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   89) 		ur_block = block;
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   90) 
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   91) 	if (put_user(ur_block, p))
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   92) 		error = -EFAULT;
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   93) 
0d89fdae2afe8 (Carlos Maiolino    2020-01-09 14:30:44 +0100   94) 	return error;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800   95) }
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800   96) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400   97) /**
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400   98)  * fiemap_fill_next_extent - Fiemap helper function
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400   99)  * @fieinfo:	Fiemap context passed into ->fiemap
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  100)  * @logical:	Extent logical start offset, in bytes
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  101)  * @phys:	Extent physical start offset, in bytes
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  102)  * @len:	Extent length, in bytes
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  103)  * @flags:	FIEMAP_EXTENT flags that describe this extent
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  104)  *
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  105)  * Called from file system ->fiemap callback. Will populate extent
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  106)  * info as passed in via arguments and copy to user memory. On
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  107)  * success, extent count on fieinfo is incremented.
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  108)  *
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  109)  * Returns 0 on success, -errno on error, 1 if this was the last
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  110)  * extent that will fit in user array.
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  111)  */
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  112) #define SET_UNKNOWN_FLAGS	(FIEMAP_EXTENT_DELALLOC)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  113) #define SET_NO_UNMOUNTED_IO_FLAGS	(FIEMAP_EXTENT_DATA_ENCRYPTED)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  114) #define SET_NOT_ALIGNED_FLAGS	(FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  115) int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  116) 			    u64 phys, u64 len, u32 flags)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  117) {
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  118) 	struct fiemap_extent extent;
ecf5632dd189a (Namhyung Kim       2011-01-16 23:28:17 +0900  119) 	struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  120) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  121) 	/* only count the extents */
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  122) 	if (fieinfo->fi_extents_max == 0) {
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  123) 		fieinfo->fi_extents_mapped++;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  124) 		return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  125) 	}
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  126) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  127) 	if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  128) 		return 1;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  129) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  130) 	if (flags & SET_UNKNOWN_FLAGS)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  131) 		flags |= FIEMAP_EXTENT_UNKNOWN;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  132) 	if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  133) 		flags |= FIEMAP_EXTENT_ENCODED;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  134) 	if (flags & SET_NOT_ALIGNED_FLAGS)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  135) 		flags |= FIEMAP_EXTENT_NOT_ALIGNED;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  136) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  137) 	memset(&extent, 0, sizeof(extent));
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  138) 	extent.fe_logical = logical;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  139) 	extent.fe_physical = phys;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  140) 	extent.fe_length = len;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  141) 	extent.fe_flags = flags;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  142) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  143) 	dest += fieinfo->fi_extents_mapped;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  144) 	if (copy_to_user(dest, &extent, sizeof(extent)))
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  145) 		return -EFAULT;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  146) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  147) 	fieinfo->fi_extents_mapped++;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  148) 	if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  149) 		return 1;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  150) 	return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  151) }
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  152) EXPORT_SYMBOL(fiemap_fill_next_extent);
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  153) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  154) /**
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  155)  * fiemap_prep - check validity of requested flags for fiemap
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  156)  * @inode:	Inode to operate on
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  157)  * @fieinfo:	Fiemap context passed into ->fiemap
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  158)  * @start:	Start of the mapped range
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  159)  * @len:	Length of the mapped range, can be truncated by this function.
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  160)  * @supported_flags:	Set of fiemap flags that the file system understands
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  161)  *
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  162)  * This function must be called from each ->fiemap instance to validate the
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  163)  * fiemap request against the file system parameters.
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  164)  *
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  165)  * Returns 0 on success, or a negative error on failure.
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  166)  */
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  167) int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  168) 		u64 start, u64 *len, u32 supported_flags)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  169) {
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  170) 	u64 maxbytes = inode->i_sb->s_maxbytes;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  171) 	u32 incompat_flags;
45dd052e67ad1 (Christoph Hellwig  2020-05-23 09:30:14 +0200  172) 	int ret = 0;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  173) 
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  174) 	if (*len == 0)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  175) 		return -EINVAL;
5aa98b706e83d (Jeff Layton        2009-09-18 13:05:50 -0700  176) 	if (start > maxbytes)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  177) 		return -EFBIG;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  178) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  179) 	/*
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  180) 	 * Shrink request scope to what the fs can actually handle.
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  181) 	 */
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  182) 	if (*len > maxbytes || (maxbytes - *len) < start)
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  183) 		*len = maxbytes - start;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  184) 
45dd052e67ad1 (Christoph Hellwig  2020-05-23 09:30:14 +0200  185) 	supported_flags |= FIEMAP_FLAG_SYNC;
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  186) 	supported_flags &= FIEMAP_FLAGS_COMPAT;
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  187) 	incompat_flags = fieinfo->fi_flags & ~supported_flags;
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  188) 	if (incompat_flags) {
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  189) 		fieinfo->fi_flags = incompat_flags;
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  190) 		return -EBADR;
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  191) 	}
45dd052e67ad1 (Christoph Hellwig  2020-05-23 09:30:14 +0200  192) 
45dd052e67ad1 (Christoph Hellwig  2020-05-23 09:30:14 +0200  193) 	if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
45dd052e67ad1 (Christoph Hellwig  2020-05-23 09:30:14 +0200  194) 		ret = filemap_write_and_wait(inode->i_mapping);
45dd052e67ad1 (Christoph Hellwig  2020-05-23 09:30:14 +0200  195) 	return ret;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  196) }
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  197) EXPORT_SYMBOL(fiemap_prep);
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  198) 
34d3d0e65e3a8 (Al Viro            2019-04-21 18:45:28 -0400  199) static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  200) {
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  201) 	struct fiemap fiemap;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  202) 	struct fiemap_extent_info fieinfo = { 0, };
496ad9aa8ef44 (Al Viro            2013-01-23 17:07:38 -0500  203) 	struct inode *inode = file_inode(filp);
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  204) 	int error;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  205) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  206) 	if (!inode->i_op->fiemap)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  207) 		return -EOPNOTSUPP;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  208) 
ecf5632dd189a (Namhyung Kim       2011-01-16 23:28:17 +0900  209) 	if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  210) 		return -EFAULT;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  211) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  212) 	if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  213) 		return -EINVAL;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  214) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  215) 	fieinfo.fi_flags = fiemap.fm_flags;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  216) 	fieinfo.fi_extents_max = fiemap.fm_extent_count;
ecf5632dd189a (Namhyung Kim       2011-01-16 23:28:17 +0900  217) 	fieinfo.fi_extents_start = ufiemap->fm_extents;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  218) 
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  219) 	error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start,
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  220) 			fiemap.fm_length);
c7d216e8c44cf (Christoph Hellwig  2020-05-23 09:30:15 +0200  221) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  222) 	fiemap.fm_flags = fieinfo.fi_flags;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  223) 	fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
ecf5632dd189a (Namhyung Kim       2011-01-16 23:28:17 +0900  224) 	if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  225) 		error = -EFAULT;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  226) 
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  227) 	return error;
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  228) }
c4b929b85bdb6 (Mark Fasheh        2008-10-08 19:44:18 -0400  229) 
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  230) static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  231) 			     u64 off, u64 olen, u64 destoff)
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  232) {
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  233) 	struct fd src_file = fdget(srcfd);
42ec3d4c02187 (Darrick J. Wong    2018-10-30 10:41:49 +1100  234) 	loff_t cloned;
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  235) 	int ret;
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  236) 
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  237) 	if (!src_file.file)
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  238) 		return -EBADF;
913b86e92e1f6 (Amir Goldstein     2016-09-23 11:38:10 +0300  239) 	ret = -EXDEV;
913b86e92e1f6 (Amir Goldstein     2016-09-23 11:38:10 +0300  240) 	if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
913b86e92e1f6 (Amir Goldstein     2016-09-23 11:38:10 +0300  241) 		goto fdput;
42ec3d4c02187 (Darrick J. Wong    2018-10-30 10:41:49 +1100  242) 	cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
452ce65951a2f (Darrick J. Wong    2018-10-30 10:41:56 +1100  243) 				      olen, 0);
42ec3d4c02187 (Darrick J. Wong    2018-10-30 10:41:49 +1100  244) 	if (cloned < 0)
42ec3d4c02187 (Darrick J. Wong    2018-10-30 10:41:49 +1100  245) 		ret = cloned;
42ec3d4c02187 (Darrick J. Wong    2018-10-30 10:41:49 +1100  246) 	else if (olen && cloned != olen)
42ec3d4c02187 (Darrick J. Wong    2018-10-30 10:41:49 +1100  247) 		ret = -EINVAL;
42ec3d4c02187 (Darrick J. Wong    2018-10-30 10:41:49 +1100  248) 	else
42ec3d4c02187 (Darrick J. Wong    2018-10-30 10:41:49 +1100  249) 		ret = 0;
913b86e92e1f6 (Amir Goldstein     2016-09-23 11:38:10 +0300  250) fdput:
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  251) 	fdput(src_file);
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  252) 	return ret;
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  253) }
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  254) 
34d3d0e65e3a8 (Al Viro            2019-04-21 18:45:28 -0400  255) static long ioctl_file_clone_range(struct file *file,
34d3d0e65e3a8 (Al Viro            2019-04-21 18:45:28 -0400  256) 				   struct file_clone_range __user *argp)
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  257) {
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  258) 	struct file_clone_range args;
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  259) 
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  260) 	if (copy_from_user(&args, argp, sizeof(args)))
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  261) 		return -EFAULT;
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  262) 	return ioctl_file_clone(file, args.src_fd, args.src_offset,
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  263) 				args.src_length, args.dest_offset);
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  264) }
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100  265) 
06270d5d6aefb (Adrian Bunk        2008-10-12 07:15:19 +0300  266) #ifdef CONFIG_BLOCK
06270d5d6aefb (Adrian Bunk        2008-10-12 07:15:19 +0300  267) 
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  268) static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  269) {
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  270) 	return (offset >> inode->i_blkbits);
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  271) }
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  272) 
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  273) static inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  274) {
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  275) 	return (blk << inode->i_blkbits);
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  276) }
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  277) 
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  278) /**
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  279)  * __generic_block_fiemap - FIEMAP for block based inodes (no locking)
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  280)  * @inode: the inode to map
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  281)  * @fieinfo: the fiemap info struct that will be passed back to userspace
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  282)  * @start: where to start mapping in the inode
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  283)  * @len: how much space to map
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  284)  * @get_block: the fs's get_block function
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  285)  *
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  286)  * This does FIEMAP for block based inodes.  Basically it will just loop
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  287)  * through get_block until we hit the number of extents we want to map, or we
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  288)  * go past the end of the file and hit a hole.
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  289)  *
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  290)  * If it is possible to have data blocks beyond a hole past @inode->i_size, then
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  291)  * please do not use this function, it will stop at the first unmapped block
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  292)  * beyond i_size.
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  293)  *
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  294)  * If you use this function directly, you need to do your own locking. Use
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  295)  * generic_block_fiemap if you want the locking done for you.
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  296)  */
44ebcd06bbb3a (Christoph Hellwig  2020-05-23 09:30:10 +0200  297) static int __generic_block_fiemap(struct inode *inode,
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  298) 			   struct fiemap_extent_info *fieinfo, loff_t start,
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  299) 			   loff_t len, get_block_t *get_block)
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  300) {
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  301) 	struct buffer_head map_bh;
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  302) 	sector_t start_blk, last_blk;
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  303) 	loff_t isize = i_size_read(inode);
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  304) 	u64 logical = 0, phys = 0, size = 0;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  305) 	u32 flags = FIEMAP_EXTENT_MERGED;
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  306) 	bool past_eof = false, whole_file = false;
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  307) 	int ret = 0;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  308) 
cddf8a2c4a828 (Christoph Hellwig  2020-05-23 09:30:13 +0200  309) 	ret = fiemap_prep(inode, fieinfo, start, &len, FIEMAP_FLAG_SYNC);
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  310) 	if (ret)
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  311) 		return ret;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  312) 
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  313) 	/*
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  314) 	 * Either the i_mutex or other appropriate locking needs to be held
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  315) 	 * since we expect isize to not change at all through the duration of
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  316) 	 * this call.
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  317) 	 */
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  318) 	if (len >= isize) {
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  319) 		whole_file = true;
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  320) 		len = isize;
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  321) 	}
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  322) 
d54cdc8ca7aab (Josef Bacik        2011-02-01 15:52:47 -0800  323) 	/*
d54cdc8ca7aab (Josef Bacik        2011-02-01 15:52:47 -0800  324) 	 * Some filesystems can't deal with being asked to map less than
d54cdc8ca7aab (Josef Bacik        2011-02-01 15:52:47 -0800  325) 	 * blocksize, so make sure our len is at least block length.
d54cdc8ca7aab (Josef Bacik        2011-02-01 15:52:47 -0800  326) 	 */
d54cdc8ca7aab (Josef Bacik        2011-02-01 15:52:47 -0800  327) 	if (logical_to_blk(inode, len) == 0)
d54cdc8ca7aab (Josef Bacik        2011-02-01 15:52:47 -0800  328) 		len = blk_to_logical(inode, 1);
d54cdc8ca7aab (Josef Bacik        2011-02-01 15:52:47 -0800  329) 
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  330) 	start_blk = logical_to_blk(inode, start);
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  331) 	last_blk = logical_to_blk(inode, start + len - 1);
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  332) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  333) 	do {
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  334) 		/*
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  335) 		 * we set b_size to the total size we want so it will map as
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  336) 		 * many contiguous blocks as possible at once
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  337) 		 */
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  338) 		memset(&map_bh, 0, sizeof(struct buffer_head));
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  339) 		map_bh.b_size = len;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  340) 
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  341) 		ret = get_block(inode, start_blk, &map_bh, 0);
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  342) 		if (ret)
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  343) 			break;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  344) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  345) 		/* HOLE */
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  346) 		if (!buffer_mapped(&map_bh)) {
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  347) 			start_blk++;
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  348) 
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  349) 			/*
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  350) 			 * We want to handle the case where there is an
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  351) 			 * allocated block at the front of the file, and then
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  352) 			 * nothing but holes up to the end of the file properly,
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  353) 			 * to make sure that extent at the front gets properly
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  354) 			 * marked with FIEMAP_EXTENT_LAST
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  355) 			 */
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  356) 			if (!past_eof &&
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  357) 			    blk_to_logical(inode, start_blk) >= isize)
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  358) 				past_eof = 1;
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  359) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  360) 			/*
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  361) 			 * First hole after going past the EOF, this is our
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  362) 			 * last extent
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  363) 			 */
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  364) 			if (past_eof && size) {
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  365) 				flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  366) 				ret = fiemap_fill_next_extent(fieinfo, logical,
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  367) 							      phys, size,
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  368) 							      flags);
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  369) 			} else if (size) {
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  370) 				ret = fiemap_fill_next_extent(fieinfo, logical,
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  371) 							      phys, size, flags);
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  372) 				size = 0;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  373) 			}
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  374) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  375) 			/* if we have holes up to/past EOF then we're done */
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  376) 			if (start_blk > last_blk || past_eof || ret)
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  377) 				break;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  378) 		} else {
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  379) 			/*
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  380) 			 * We have gone over the length of what we wanted to
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  381) 			 * map, and it wasn't the entire file, so add the extent
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  382) 			 * we got last time and exit.
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  383) 			 *
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  384) 			 * This is for the case where say we want to map all the
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  385) 			 * way up to the second to the last block in a file, but
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  386) 			 * the last block is a hole, making the second to last
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  387) 			 * block FIEMAP_EXTENT_LAST.  In this case we want to
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  388) 			 * see if there is a hole after the second to last block
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  389) 			 * so we can mark it properly.  If we found data after
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  390) 			 * we exceeded the length we were requesting, then we
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  391) 			 * are good to go, just add the extent to the fieinfo
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  392) 			 * and break
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  393) 			 */
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  394) 			if (start_blk > last_blk && !whole_file) {
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  395) 				ret = fiemap_fill_next_extent(fieinfo, logical,
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  396) 							      phys, size,
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  397) 							      flags);
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  398) 				break;
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  399) 			}
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  400) 
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  401) 			/*
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  402) 			 * if size != 0 then we know we already have an extent
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  403) 			 * to add, so add it.
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  404) 			 */
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  405) 			if (size) {
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  406) 				ret = fiemap_fill_next_extent(fieinfo, logical,
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  407) 							      phys, size,
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  408) 							      flags);
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  409) 				if (ret)
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  410) 					break;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  411) 			}
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  412) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  413) 			logical = blk_to_logical(inode, start_blk);
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  414) 			phys = blk_to_logical(inode, map_bh.b_blocknr);
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  415) 			size = map_bh.b_size;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  416) 			flags = FIEMAP_EXTENT_MERGED;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  417) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  418) 			start_blk += logical_to_blk(inode, size);
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  419) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  420) 			/*
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  421) 			 * If we are past the EOF, then we need to make sure as
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  422) 			 * soon as we find a hole that the last extent we found
df3935ffd6166 (Josef Bacik        2009-05-06 16:02:53 -0700  423) 			 * is marked with FIEMAP_EXTENT_LAST
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  424) 			 */
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  425) 			if (!past_eof && logical + size >= isize)
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  426) 				past_eof = true;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  427) 		}
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  428) 		cond_resched();
913e027ca17ee (Dmitry Monakhov    2015-02-10 14:09:29 -0800  429) 		if (fatal_signal_pending(current)) {
913e027ca17ee (Dmitry Monakhov    2015-02-10 14:09:29 -0800  430) 			ret = -EINTR;
913e027ca17ee (Dmitry Monakhov    2015-02-10 14:09:29 -0800  431) 			break;
913e027ca17ee (Dmitry Monakhov    2015-02-10 14:09:29 -0800  432) 		}
913e027ca17ee (Dmitry Monakhov    2015-02-10 14:09:29 -0800  433) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  434) 	} while (1);
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  435) 
3a3076f4d6e2f (Josef Bacik        2010-04-23 12:17:17 -0400  436) 	/* If ret is 1 then we just hit the end of the extent array */
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  437) 	if (ret == 1)
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  438) 		ret = 0;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  439) 
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  440) 	return ret;
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  441) }
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  442) 
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  443) /**
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  444)  * generic_block_fiemap - FIEMAP for block based inodes
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  445)  * @inode: The inode to map
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  446)  * @fieinfo: The mapping information
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  447)  * @start: The initial block to map
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  448)  * @len: The length of the extect to attempt to map
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  449)  * @get_block: The block mapping function for the fs
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  450)  *
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  451)  * Calls __generic_block_fiemap to map the inode, after taking
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  452)  * the inode's mutex lock.
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  453)  */
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  454) 
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  455) int generic_block_fiemap(struct inode *inode,
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  456) 			 struct fiemap_extent_info *fieinfo, u64 start,
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  457) 			 u64 len, get_block_t *get_block)
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  458) {
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  459) 	int ret;
5955102c9984f (Al Viro            2016-01-22 15:40:57 -0500  460) 	inode_lock(inode);
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  461) 	ret = __generic_block_fiemap(inode, fieinfo, start, len, get_block);
5955102c9984f (Al Viro            2016-01-22 15:40:57 -0500  462) 	inode_unlock(inode);
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  463) 	return ret;
e9079cce20178 (Steven Whitehouse  2008-10-14 14:43:29 +0100  464) }
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  465) EXPORT_SYMBOL(generic_block_fiemap);
68c9d702bb72f (Josef Bacik        2008-10-03 17:32:43 -0400  466) 
06270d5d6aefb (Adrian Bunk        2008-10-12 07:15:19 +0300  467) #endif  /*  CONFIG_BLOCK  */
06270d5d6aefb (Adrian Bunk        2008-10-12 07:15:19 +0300  468) 
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  469) /*
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  470)  * This provides compatibility with legacy XFS pre-allocation ioctls
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  471)  * which predate the fallocate syscall.
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  472)  *
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  473)  * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  474)  * are used here, rest are ignored.
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  475)  */
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  476) static int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  477) {
496ad9aa8ef44 (Al Viro            2013-01-23 17:07:38 -0500  478) 	struct inode *inode = file_inode(filp);
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  479) 	struct space_resv sr;
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  480) 
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  481) 	if (copy_from_user(&sr, argp, sizeof(sr)))
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  482) 		return -EFAULT;
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  483) 
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  484) 	switch (sr.l_whence) {
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  485) 	case SEEK_SET:
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  486) 		break;
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  487) 	case SEEK_CUR:
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  488) 		sr.l_start += filp->f_pos;
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  489) 		break;
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  490) 	case SEEK_END:
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  491) 		sr.l_start += i_size_read(inode);
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  492) 		break;
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  493) 	default:
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  494) 		return -EINVAL;
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  495) 	}
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  496) 
837a6e7f5cdb5 (Christoph Hellwig  2019-10-24 22:26:02 -0700  497) 	return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start,
837a6e7f5cdb5 (Christoph Hellwig  2019-10-24 22:26:02 -0700  498) 			sr.l_len);
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  499) }
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  500) 
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  501) /* on ia32 l_start is on a 32-bit boundary */
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  502) #if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  503) /* just account for different alignment */
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  504) static int compat_ioctl_preallocate(struct file *file, int mode,
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  505) 				    struct space_resv_32 __user *argp)
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  506) {
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  507) 	struct inode *inode = file_inode(file);
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  508) 	struct space_resv_32 sr;
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  509) 
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  510) 	if (copy_from_user(&sr, argp, sizeof(sr)))
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  511) 		return -EFAULT;
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  512) 
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  513) 	switch (sr.l_whence) {
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  514) 	case SEEK_SET:
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  515) 		break;
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  516) 	case SEEK_CUR:
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  517) 		sr.l_start += file->f_pos;
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  518) 		break;
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  519) 	case SEEK_END:
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  520) 		sr.l_start += i_size_read(inode);
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  521) 		break;
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  522) 	default:
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  523) 		return -EINVAL;
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  524) 	}
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  525) 
97eeb4d9d7556 (Linus Torvalds     2019-12-02 14:46:22 -0800  526) 	return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  527) }
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  528) #endif
011da44bc5b65 (Al Viro            2019-04-21 19:24:03 -0400  529) 
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  530) static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  531) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  532) 	switch (cmd) {
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  533) 	case FIBMAP:
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  534) 		return ioctl_fibmap(filp, p);
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  535) 	case FS_IOC_RESVSP:
3e63cbb1efca7 (Ankit Jain         2009-06-19 14:28:07 -0400  536) 	case FS_IOC_RESVSP64:
837a6e7f5cdb5 (Christoph Hellwig  2019-10-24 22:26:02 -0700  537) 		return ioctl_preallocate(filp, 0, p);
837a6e7f5cdb5 (Christoph Hellwig  2019-10-24 22:26:02 -0700  538) 	case FS_IOC_UNRESVSP:
837a6e7f5cdb5 (Christoph Hellwig  2019-10-24 22:26:02 -0700  539) 	case FS_IOC_UNRESVSP64:
837a6e7f5cdb5 (Christoph Hellwig  2019-10-24 22:26:02 -0700  540) 		return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
837a6e7f5cdb5 (Christoph Hellwig  2019-10-24 22:26:02 -0700  541) 	case FS_IOC_ZERO_RANGE:
837a6e7f5cdb5 (Christoph Hellwig  2019-10-24 22:26:02 -0700  542) 		return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  543) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  544) 
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  545) 	return -ENOIOCTLCMD;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  546) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  547) 
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  548) static int ioctl_fionbio(struct file *filp, int __user *argp)
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  549) {
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  550) 	unsigned int flag;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  551) 	int on, error;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  552) 
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  553) 	error = get_user(on, argp);
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  554) 	if (error)
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  555) 		return error;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  556) 	flag = O_NONBLOCK;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  557) #ifdef __sparc__
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  558) 	/* SunOS compatibility item. */
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  559) 	if (O_NONBLOCK != O_NDELAY)
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  560) 		flag |= O_NDELAY;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  561) #endif
db1dd4d376134 (Jonathan Corbet    2009-02-06 15:25:24 -0700  562) 	spin_lock(&filp->f_lock);
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  563) 	if (on)
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  564) 		filp->f_flags |= flag;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  565) 	else
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  566) 		filp->f_flags &= ~flag;
db1dd4d376134 (Jonathan Corbet    2009-02-06 15:25:24 -0700  567) 	spin_unlock(&filp->f_lock);
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  568) 	return error;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  569) }
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  570) 
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  571) static int ioctl_fioasync(unsigned int fd, struct file *filp,
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  572) 			  int __user *argp)
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  573) {
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  574) 	unsigned int flag;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  575) 	int on, error;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  576) 
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  577) 	error = get_user(on, argp);
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  578) 	if (error)
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  579) 		return error;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  580) 	flag = on ? FASYNC : 0;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  581) 
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  582) 	/* Did FASYNC state change ? */
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  583) 	if ((flag ^ filp->f_flags) & FASYNC) {
72c2d53192004 (Al Viro            2013-09-22 16:27:52 -0400  584) 		if (filp->f_op->fasync)
76398425bb06b (Jonathan Corbet    2009-02-01 14:26:59 -0700  585) 			/* fasync() adjusts filp->f_flags */
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  586) 			error = filp->f_op->fasync(fd, filp, on);
218d11a8b071b (Jonathan Corbet    2008-12-05 16:12:48 -0700  587) 		else
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  588) 			error = -ENOTTY;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  589) 	}
60aa49243d09a (Jonathan Corbet    2009-02-01 14:52:56 -0700  590) 	return error < 0 ? error : 0;
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  591) }
aa81a7c7120ad (Erez Zadok         2008-02-07 00:13:25 -0800  592) 
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  593) static int ioctl_fsfreeze(struct file *filp)
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  594) {
496ad9aa8ef44 (Al Viro            2013-01-23 17:07:38 -0500  595) 	struct super_block *sb = file_inode(filp)->i_sb;
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  596) 
f3f1a18330ac1 (Seth Forshee       2015-02-15 14:35:35 -0600  597) 	if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  598) 		return -EPERM;
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  599) 
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  600) 	/* If filesystem doesn't support freeze feature, return. */
48b6bca6b7b83 (Benjamin Marzinski 2014-11-13 20:42:03 -0600  601) 	if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL)
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  602) 		return -EOPNOTSUPP;
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  603) 
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  604) 	/* Freeze */
48b6bca6b7b83 (Benjamin Marzinski 2014-11-13 20:42:03 -0600  605) 	if (sb->s_op->freeze_super)
48b6bca6b7b83 (Benjamin Marzinski 2014-11-13 20:42:03 -0600  606) 		return sb->s_op->freeze_super(sb);
18e9e5104fcd9 (Josef Bacik        2010-03-23 10:34:56 -0400  607) 	return freeze_super(sb);
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  608) }
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  609) 
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  610) static int ioctl_fsthaw(struct file *filp)
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  611) {
496ad9aa8ef44 (Al Viro            2013-01-23 17:07:38 -0500  612) 	struct super_block *sb = file_inode(filp)->i_sb;
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  613) 
f3f1a18330ac1 (Seth Forshee       2015-02-15 14:35:35 -0600  614) 	if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  615) 		return -EPERM;
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  616) 
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  617) 	/* Thaw */
48b6bca6b7b83 (Benjamin Marzinski 2014-11-13 20:42:03 -0600  618) 	if (sb->s_op->thaw_super)
48b6bca6b7b83 (Benjamin Marzinski 2014-11-13 20:42:03 -0600  619) 		return sb->s_op->thaw_super(sb);
18e9e5104fcd9 (Josef Bacik        2010-03-23 10:34:56 -0400  620) 	return thaw_super(sb);
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  621) }
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800  622) 
34d3d0e65e3a8 (Al Viro            2019-04-21 18:45:28 -0400  623) static int ioctl_file_dedupe_range(struct file *file,
34d3d0e65e3a8 (Al Viro            2019-04-21 18:45:28 -0400  624) 				   struct file_dedupe_range __user *argp)
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  625) {
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  626) 	struct file_dedupe_range *same = NULL;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  627) 	int ret;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  628) 	unsigned long size;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  629) 	u16 count;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  630) 
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  631) 	if (get_user(count, &argp->dest_count)) {
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  632) 		ret = -EFAULT;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  633) 		goto out;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  634) 	}
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  635) 
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  636) 	size = offsetof(struct file_dedupe_range __user, info[count]);
b71dbf1032f54 (Darrick J. Wong    2016-09-14 20:20:44 -0700  637) 	if (size > PAGE_SIZE) {
b71dbf1032f54 (Darrick J. Wong    2016-09-14 20:20:44 -0700  638) 		ret = -ENOMEM;
b71dbf1032f54 (Darrick J. Wong    2016-09-14 20:20:44 -0700  639) 		goto out;
b71dbf1032f54 (Darrick J. Wong    2016-09-14 20:20:44 -0700  640) 	}
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  641) 
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  642) 	same = memdup_user(argp, size);
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  643) 	if (IS_ERR(same)) {
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  644) 		ret = PTR_ERR(same);
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  645) 		same = NULL;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  646) 		goto out;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  647) 	}
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  648) 
10eec60ce7918 (Scott Bauer        2016-07-27 19:11:29 -0600  649) 	same->dest_count = count;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  650) 	ret = vfs_dedupe_file_range(file, same);
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  651) 	if (ret)
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  652) 		goto out;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  653) 
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  654) 	ret = copy_to_user(argp, same, size);
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  655) 	if (ret)
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  656) 		ret = -EFAULT;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  657) 
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  658) out:
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  659) 	kfree(same);
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  660) 	return ret;
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  661) }
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800  662) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  663) /**
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  664)  * fileattr_fill_xflags - initialize fileattr with xflags
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  665)  * @fa:		fileattr pointer
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  666)  * @xflags:	FS_XFLAG_* flags
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  667)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  668)  * Set ->fsx_xflags, ->fsx_valid and ->flags (translated xflags).  All
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  669)  * other fields are zeroed.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  670)  */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  671) void fileattr_fill_xflags(struct fileattr *fa, u32 xflags)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  672) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  673) 	memset(fa, 0, sizeof(*fa));
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  674) 	fa->fsx_valid = true;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  675) 	fa->fsx_xflags = xflags;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  676) 	if (fa->fsx_xflags & FS_XFLAG_IMMUTABLE)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  677) 		fa->flags |= FS_IMMUTABLE_FL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  678) 	if (fa->fsx_xflags & FS_XFLAG_APPEND)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  679) 		fa->flags |= FS_APPEND_FL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  680) 	if (fa->fsx_xflags & FS_XFLAG_SYNC)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  681) 		fa->flags |= FS_SYNC_FL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  682) 	if (fa->fsx_xflags & FS_XFLAG_NOATIME)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  683) 		fa->flags |= FS_NOATIME_FL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  684) 	if (fa->fsx_xflags & FS_XFLAG_NODUMP)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  685) 		fa->flags |= FS_NODUMP_FL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  686) 	if (fa->fsx_xflags & FS_XFLAG_DAX)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  687) 		fa->flags |= FS_DAX_FL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  688) 	if (fa->fsx_xflags & FS_XFLAG_PROJINHERIT)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  689) 		fa->flags |= FS_PROJINHERIT_FL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  690) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  691) EXPORT_SYMBOL(fileattr_fill_xflags);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  692) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  693) /**
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  694)  * fileattr_fill_flags - initialize fileattr with flags
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  695)  * @fa:		fileattr pointer
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  696)  * @flags:	FS_*_FL flags
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  697)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  698)  * Set ->flags, ->flags_valid and ->fsx_xflags (translated flags).
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  699)  * All other fields are zeroed.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  700)  */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  701) void fileattr_fill_flags(struct fileattr *fa, u32 flags)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  702) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  703) 	memset(fa, 0, sizeof(*fa));
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  704) 	fa->flags_valid = true;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  705) 	fa->flags = flags;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  706) 	if (fa->flags & FS_SYNC_FL)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  707) 		fa->fsx_xflags |= FS_XFLAG_SYNC;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  708) 	if (fa->flags & FS_IMMUTABLE_FL)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  709) 		fa->fsx_xflags |= FS_XFLAG_IMMUTABLE;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  710) 	if (fa->flags & FS_APPEND_FL)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  711) 		fa->fsx_xflags |= FS_XFLAG_APPEND;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  712) 	if (fa->flags & FS_NODUMP_FL)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  713) 		fa->fsx_xflags |= FS_XFLAG_NODUMP;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  714) 	if (fa->flags & FS_NOATIME_FL)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  715) 		fa->fsx_xflags |= FS_XFLAG_NOATIME;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  716) 	if (fa->flags & FS_DAX_FL)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  717) 		fa->fsx_xflags |= FS_XFLAG_DAX;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  718) 	if (fa->flags & FS_PROJINHERIT_FL)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  719) 		fa->fsx_xflags |= FS_XFLAG_PROJINHERIT;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  720) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  721) EXPORT_SYMBOL(fileattr_fill_flags);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  722) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  723) /**
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  724)  * vfs_fileattr_get - retrieve miscellaneous file attributes
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  725)  * @dentry:	the object to retrieve from
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  726)  * @fa:		fileattr pointer
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  727)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  728)  * Call i_op->fileattr_get() callback, if exists.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  729)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  730)  * Return: 0 on success, or a negative error on failure.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  731)  */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  732) int vfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  733) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  734) 	struct inode *inode = d_inode(dentry);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  735) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  736) 	if (!inode->i_op->fileattr_get)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  737) 		return -ENOIOCTLCMD;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  738) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  739) 	return inode->i_op->fileattr_get(dentry, fa);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  740) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  741) EXPORT_SYMBOL(vfs_fileattr_get);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  742) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  743) /**
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  744)  * copy_fsxattr_to_user - copy fsxattr to userspace.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  745)  * @fa:		fileattr pointer
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  746)  * @ufa:	fsxattr user pointer
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  747)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  748)  * Return: 0 on success, or -EFAULT on failure.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  749)  */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  750) int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  751) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  752) 	struct fsxattr xfa;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  753) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  754) 	memset(&xfa, 0, sizeof(xfa));
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  755) 	xfa.fsx_xflags = fa->fsx_xflags;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  756) 	xfa.fsx_extsize = fa->fsx_extsize;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  757) 	xfa.fsx_nextents = fa->fsx_nextents;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  758) 	xfa.fsx_projid = fa->fsx_projid;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  759) 	xfa.fsx_cowextsize = fa->fsx_cowextsize;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  760) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  761) 	if (copy_to_user(ufa, &xfa, sizeof(xfa)))
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  762) 		return -EFAULT;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  763) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  764) 	return 0;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  765) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  766) EXPORT_SYMBOL(copy_fsxattr_to_user);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  767) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  768) static int copy_fsxattr_from_user(struct fileattr *fa,
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  769) 				  struct fsxattr __user *ufa)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  770) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  771) 	struct fsxattr xfa;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  772) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  773) 	if (copy_from_user(&xfa, ufa, sizeof(xfa)))
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  774) 		return -EFAULT;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  775) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  776) 	fileattr_fill_xflags(fa, xfa.fsx_xflags);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  777) 	fa->fsx_extsize = xfa.fsx_extsize;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  778) 	fa->fsx_nextents = xfa.fsx_nextents;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  779) 	fa->fsx_projid = xfa.fsx_projid;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  780) 	fa->fsx_cowextsize = xfa.fsx_cowextsize;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  781) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  782) 	return 0;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  783) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  784) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  785) /*
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  786)  * Generic function to check FS_IOC_FSSETXATTR/FS_IOC_SETFLAGS values and reject
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  787)  * any invalid configurations.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  788)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  789)  * Note: must be called with inode lock held.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  790)  */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  791) static int fileattr_set_prepare(struct inode *inode,
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  792) 			      const struct fileattr *old_ma,
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  793) 			      struct fileattr *fa)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  794) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  795) 	int err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  796) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  797) 	/*
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  798) 	 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  799) 	 * the relevant capability.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  800) 	 */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  801) 	if ((fa->flags ^ old_ma->flags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) &&
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  802) 	    !capable(CAP_LINUX_IMMUTABLE))
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  803) 		return -EPERM;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  804) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  805) 	err = fscrypt_prepare_setflags(inode, old_ma->flags, fa->flags);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  806) 	if (err)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  807) 		return err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  808) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  809) 	/*
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  810) 	 * Project Quota ID state is only allowed to change from within the init
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  811) 	 * namespace. Enforce that restriction only if we are trying to change
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  812) 	 * the quota ID state. Everything else is allowed in user namespaces.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  813) 	 */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  814) 	if (current_user_ns() != &init_user_ns) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  815) 		if (old_ma->fsx_projid != fa->fsx_projid)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  816) 			return -EINVAL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  817) 		if ((old_ma->fsx_xflags ^ fa->fsx_xflags) &
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  818) 				FS_XFLAG_PROJINHERIT)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  819) 			return -EINVAL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  820) 	}
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  821) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  822) 	/* Check extent size hints. */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  823) 	if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(inode->i_mode))
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  824) 		return -EINVAL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  825) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  826) 	if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  827) 			!S_ISDIR(inode->i_mode))
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  828) 		return -EINVAL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  829) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  830) 	if ((fa->fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  831) 	    !S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  832) 		return -EINVAL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  833) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  834) 	/*
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  835) 	 * It is only valid to set the DAX flag on regular files and
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  836) 	 * directories on filesystems.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  837) 	 */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  838) 	if ((fa->fsx_xflags & FS_XFLAG_DAX) &&
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  839) 	    !(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  840) 		return -EINVAL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  841) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  842) 	/* Extent size hints of zero turn off the flags. */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  843) 	if (fa->fsx_extsize == 0)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  844) 		fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  845) 	if (fa->fsx_cowextsize == 0)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  846) 		fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  847) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  848) 	return 0;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  849) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  850) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  851) /**
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  852)  * vfs_fileattr_set - change miscellaneous file attributes
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  853)  * @mnt_userns:	user namespace of the mount
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  854)  * @dentry:	the object to change
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  855)  * @fa:		fileattr pointer
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  856)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  857)  * After verifying permissions, call i_op->fileattr_set() callback, if
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  858)  * exists.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  859)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  860)  * Verifying attributes involves retrieving current attributes with
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  861)  * i_op->fileattr_get(), this also allows initializing attributes that have
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  862)  * not been set by the caller to current values.  Inode lock is held
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  863)  * thoughout to prevent racing with another instance.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  864)  *
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  865)  * Return: 0 on success, or a negative error on failure.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  866)  */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  867) int vfs_fileattr_set(struct user_namespace *mnt_userns, struct dentry *dentry,
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  868) 		     struct fileattr *fa)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  869) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  870) 	struct inode *inode = d_inode(dentry);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  871) 	struct fileattr old_ma = {};
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  872) 	int err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  873) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  874) 	if (!inode->i_op->fileattr_set)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  875) 		return -ENOIOCTLCMD;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  876) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  877) 	if (!inode_owner_or_capable(mnt_userns, inode))
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  878) 		return -EPERM;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  879) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  880) 	inode_lock(inode);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  881) 	err = vfs_fileattr_get(dentry, &old_ma);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  882) 	if (!err) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  883) 		/* initialize missing bits from old_ma */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  884) 		if (fa->flags_valid) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  885) 			fa->fsx_xflags |= old_ma.fsx_xflags & ~FS_XFLAG_COMMON;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  886) 			fa->fsx_extsize = old_ma.fsx_extsize;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  887) 			fa->fsx_nextents = old_ma.fsx_nextents;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  888) 			fa->fsx_projid = old_ma.fsx_projid;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  889) 			fa->fsx_cowextsize = old_ma.fsx_cowextsize;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  890) 		} else {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  891) 			fa->flags |= old_ma.flags & ~FS_COMMON_FL;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  892) 		}
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  893) 		err = fileattr_set_prepare(inode, &old_ma, fa);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  894) 		if (!err)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  895) 			err = inode->i_op->fileattr_set(mnt_userns, dentry, fa);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  896) 	}
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  897) 	inode_unlock(inode);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  898) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  899) 	return err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  900) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  901) EXPORT_SYMBOL(vfs_fileattr_set);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  902) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  903) static int ioctl_getflags(struct file *file, unsigned int __user *argp)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  904) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  905) 	struct fileattr fa = { .flags_valid = true }; /* hint only */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  906) 	int err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  907) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  908) 	err = vfs_fileattr_get(file->f_path.dentry, &fa);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  909) 	if (!err)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  910) 		err = put_user(fa.flags, argp);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  911) 	return err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  912) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  913) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  914) static int ioctl_setflags(struct file *file, unsigned int __user *argp)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  915) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  916) 	struct user_namespace *mnt_userns = file_mnt_user_ns(file);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  917) 	struct dentry *dentry = file->f_path.dentry;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  918) 	struct fileattr fa;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  919) 	unsigned int flags;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  920) 	int err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  921) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  922) 	err = get_user(flags, argp);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  923) 	if (!err) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  924) 		err = mnt_want_write_file(file);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  925) 		if (!err) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  926) 			fileattr_fill_flags(&fa, flags);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  927) 			err = vfs_fileattr_set(mnt_userns, dentry, &fa);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  928) 			mnt_drop_write_file(file);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  929) 		}
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  930) 	}
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  931) 	return err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  932) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  933) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  934) static int ioctl_fsgetxattr(struct file *file, void __user *argp)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  935) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  936) 	struct fileattr fa = { .fsx_valid = true }; /* hint only */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  937) 	int err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  938) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  939) 	err = vfs_fileattr_get(file->f_path.dentry, &fa);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  940) 	if (!err)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  941) 		err = copy_fsxattr_to_user(&fa, argp);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  942) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  943) 	return err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  944) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  945) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  946) static int ioctl_fssetxattr(struct file *file, void __user *argp)
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  947) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  948) 	struct user_namespace *mnt_userns = file_mnt_user_ns(file);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  949) 	struct dentry *dentry = file->f_path.dentry;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  950) 	struct fileattr fa;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  951) 	int err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  952) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  953) 	err = copy_fsxattr_from_user(&fa, argp);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  954) 	if (!err) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  955) 		err = mnt_want_write_file(file);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  956) 		if (!err) {
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  957) 			err = vfs_fileattr_set(mnt_userns, dentry, &fa);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  958) 			mnt_drop_write_file(file);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  959) 		}
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  960) 	}
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  961) 	return err;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  962) }
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200  963) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  964) /*
deb21db7788b9 (Erez Zadok         2008-02-07 00:13:25 -0800  965)  * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  966)  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  967)  *
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  968)  * When you add any new common ioctls to the switches above and below,
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  969)  * please ensure they have compatible arguments in compat mode.
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  970)  */
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  971) static int do_vfs_ioctl(struct file *filp, unsigned int fd,
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  972) 			unsigned int cmd, unsigned long arg)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  973) {
34d3d0e65e3a8 (Al Viro            2019-04-21 18:45:28 -0400  974) 	void __user *argp = (void __user *)arg;
496ad9aa8ef44 (Al Viro            2013-01-23 17:07:38 -0500  975) 	struct inode *inode = file_inode(filp);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  976) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  977) 	switch (cmd) {
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  978) 	case FIOCLEX:
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  979) 		set_close_on_exec(fd, 1);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  980) 		return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  981) 
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  982) 	case FIONCLEX:
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  983) 		set_close_on_exec(fd, 0);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  984) 		return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  985) 
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  986) 	case FIONBIO:
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  987) 		return ioctl_fionbio(filp, argp);
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  988) 
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  989) 	case FIOASYNC:
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  990) 		return ioctl_fioasync(fd, filp, argp);
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  991) 
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800  992) 	case FIOQSIZE:
27a4f7e61e1eb (Namhyung Kim       2011-01-17 00:48:17 +0900  993) 		if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
27a4f7e61e1eb (Namhyung Kim       2011-01-17 00:48:17 +0900  994) 		    S_ISLNK(inode->i_mode)) {
27a4f7e61e1eb (Namhyung Kim       2011-01-17 00:48:17 +0900  995) 			loff_t res = inode_get_bytes(inode);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  996) 			return copy_to_user(argp, &res, sizeof(res)) ?
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  997) 					    -EFAULT : 0;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  998) 		}
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100  999) 
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1000) 		return -ENOTTY;
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800 1001) 
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800 1002) 	case FIFREEZE:
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1003) 		return ioctl_fsfreeze(filp);
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800 1004) 
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800 1005) 	case FITHAW:
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1006) 		return ioctl_fsthaw(filp);
fcccf502540e3 (Takashi Sato       2009-01-09 16:40:59 -0800 1007) 
19ba0559f9ce1 (Aneesh Kumar K.V   2009-05-13 18:12:05 -0400 1008) 	case FS_IOC_FIEMAP:
34d3d0e65e3a8 (Al Viro            2019-04-21 18:45:28 -0400 1009) 		return ioctl_fiemap(filp, argp);
19ba0559f9ce1 (Aneesh Kumar K.V   2009-05-13 18:12:05 -0400 1010) 
19ba0559f9ce1 (Aneesh Kumar K.V   2009-05-13 18:12:05 -0400 1011) 	case FIGETBSZ:
8f97d1e99149a (Amir Goldstein     2018-10-11 17:38:14 +0300 1012) 		/* anon_bdev filesystems may not have a block size */
8f97d1e99149a (Amir Goldstein     2018-10-11 17:38:14 +0300 1013) 		if (!inode->i_sb->s_blocksize)
8f97d1e99149a (Amir Goldstein     2018-10-11 17:38:14 +0300 1014) 			return -EINVAL;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1015) 
34d3d0e65e3a8 (Al Viro            2019-04-21 18:45:28 -0400 1016) 		return put_user(inode->i_sb->s_blocksize, (int __user *)argp);
19ba0559f9ce1 (Aneesh Kumar K.V   2009-05-13 18:12:05 -0400 1017) 
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100 1018) 	case FICLONE:
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100 1019) 		return ioctl_file_clone(filp, arg, 0, 0, 0);
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100 1020) 
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100 1021) 	case FICLONERANGE:
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100 1022) 		return ioctl_file_clone_range(filp, argp);
04b38d601239b (Christoph Hellwig  2015-12-03 12:59:50 +0100 1023) 
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800 1024) 	case FIDEDUPERANGE:
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800 1025) 		return ioctl_file_dedupe_range(filp, argp);
54dbc15172375 (Darrick J. Wong    2015-12-19 00:55:59 -0800 1026) 
0a061743af93f (Arnd Bergmann      2020-02-07 17:55:48 +0100 1027) 	case FIONREAD:
0a061743af93f (Arnd Bergmann      2020-02-07 17:55:48 +0100 1028) 		if (!S_ISREG(inode->i_mode))
0a061743af93f (Arnd Bergmann      2020-02-07 17:55:48 +0100 1029) 			return vfs_ioctl(filp, cmd, arg);
0a061743af93f (Arnd Bergmann      2020-02-07 17:55:48 +0100 1030) 
0a061743af93f (Arnd Bergmann      2020-02-07 17:55:48 +0100 1031) 		return put_user(i_size_read(inode) - filp->f_pos,
0a061743af93f (Arnd Bergmann      2020-02-07 17:55:48 +0100 1032) 				(int __user *)argp);
0a061743af93f (Arnd Bergmann      2020-02-07 17:55:48 +0100 1033) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1034) 	case FS_IOC_GETFLAGS:
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1035) 		return ioctl_getflags(filp, argp);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1036) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1037) 	case FS_IOC_SETFLAGS:
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1038) 		return ioctl_setflags(filp, argp);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1039) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1040) 	case FS_IOC_FSGETXATTR:
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1041) 		return ioctl_fsgetxattr(filp, argp);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1042) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1043) 	case FS_IOC_FSSETXATTR:
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1044) 		return ioctl_fssetxattr(filp, argp);
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1045) 
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800 1046) 	default:
27a4f7e61e1eb (Namhyung Kim       2011-01-17 00:48:17 +0900 1047) 		if (S_ISREG(inode->i_mode))
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1048) 			return file_ioctl(filp, cmd, argp);
c9845ff1df5ba (Erez Zadok         2008-02-07 00:13:23 -0800 1049) 		break;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 1050) 	}
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1051) 
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1052) 	return -ENOIOCTLCMD;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 1053) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 1054) 
863b67e15177a (Christoph Hellwig  2020-07-14 09:00:51 +0200 1055) SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 1056) {
2903ff019b346 (Al Viro            2012-08-28 12:52:22 -0400 1057) 	struct fd f = fdget(fd);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1058) 	int error;
2903ff019b346 (Al Viro            2012-08-28 12:52:22 -0400 1059) 
2903ff019b346 (Al Viro            2012-08-28 12:52:22 -0400 1060) 	if (!f.file)
2903ff019b346 (Al Viro            2012-08-28 12:52:22 -0400 1061) 		return -EBADF;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1062) 
2903ff019b346 (Al Viro            2012-08-28 12:52:22 -0400 1063) 	error = security_file_ioctl(f.file, cmd, arg);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1064) 	if (error)
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1065) 		goto out;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1066) 
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1067) 	error = do_vfs_ioctl(f.file, fd, cmd, arg);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1068) 	if (error == -ENOIOCTLCMD)
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1069) 		error = vfs_ioctl(f.file, cmd, arg);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1070) 
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1071) out:
2903ff019b346 (Al Viro            2012-08-28 12:52:22 -0400 1072) 	fdput(f);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 1073) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 1074) }
cbb60b924b9f3 (Dominik Brodowski  2018-03-13 21:43:59 +0100 1075) 
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1076) #ifdef CONFIG_COMPAT
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1077) /**
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1078)  * compat_ptr_ioctl - generic implementation of .compat_ioctl file operation
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1079)  *
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1080)  * This is not normally called as a function, but instead set in struct
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1081)  * file_operations as
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1082)  *
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1083)  *     .compat_ioctl = compat_ptr_ioctl,
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1084)  *
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1085)  * On most architectures, the compat_ptr_ioctl() just passes all arguments
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1086)  * to the corresponding ->ioctl handler. The exception is arch/s390, where
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1087)  * compat_ptr() clears the top bit of a 32-bit pointer value, so user space
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1088)  * pointers to the second 2GB alias the first 2GB, as is the case for
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1089)  * native 32-bit s390 user space.
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1090)  *
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1091)  * The compat_ptr_ioctl() function must therefore be used only with ioctl
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1092)  * functions that either ignore the argument or pass a pointer to a
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1093)  * compatible data type.
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1094)  *
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1095)  * If any ioctl command handled by fops->unlocked_ioctl passes a plain
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1096)  * integer instead of a pointer, or any of the passed data types
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1097)  * is incompatible between 32-bit and 64-bit architectures, a proper
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1098)  * handler is required instead of compat_ptr_ioctl.
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1099)  */
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1100) long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1101) {
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1102) 	if (!file->f_op->unlocked_ioctl)
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1103) 		return -ENOIOCTLCMD;
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1104) 
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1105) 	return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1106) }
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1107) EXPORT_SYMBOL(compat_ptr_ioctl);
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1108) 
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1109) COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1110) 		       compat_ulong_t, arg)
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1111) {
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1112) 	struct fd f = fdget(fd);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1113) 	int error;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1114) 
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1115) 	if (!f.file)
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1116) 		return -EBADF;
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1117) 
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1118) 	/* RED-PEN how should LSM module know it's handling 32bit? */
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1119) 	error = security_file_ioctl(f.file, cmd, arg);
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1120) 	if (error)
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1121) 		goto out;
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1122) 
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1123) 	switch (cmd) {
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1124) 	/* FICLONE takes an int argument, so don't use compat_ptr() */
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1125) 	case FICLONE:
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1126) 		error = ioctl_file_clone(f.file, arg, 0, 0, 0);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1127) 		break;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1128) 
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1129) #if defined(CONFIG_X86_64)
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1130) 	/* these get messy on amd64 due to alignment differences */
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1131) 	case FS_IOC_RESVSP_32:
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1132) 	case FS_IOC_RESVSP64_32:
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1133) 		error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1134) 		break;
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1135) 	case FS_IOC_UNRESVSP_32:
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1136) 	case FS_IOC_UNRESVSP64_32:
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1137) 		error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1138) 				compat_ptr(arg));
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1139) 		break;
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1140) 	case FS_IOC_ZERO_RANGE_32:
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1141) 		error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1142) 				compat_ptr(arg));
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1143) 		break;
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1144) #endif
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1145) 
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1146) 	/*
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1147) 	 * These access 32-bit values anyway so no further handling is
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1148) 	 * necessary.
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1149) 	 */
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1150) 	case FS_IOC32_GETFLAGS:
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1151) 	case FS_IOC32_SETFLAGS:
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1152) 		cmd = (cmd == FS_IOC32_GETFLAGS) ?
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1153) 			FS_IOC_GETFLAGS : FS_IOC_SETFLAGS;
4c5b479975212 (Miklos Szeredi     2021-04-07 14:36:42 +0200 1154) 		fallthrough;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1155) 	/*
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1156) 	 * everything else in do_vfs_ioctl() takes either a compatible
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1157) 	 * pointer argument or no argument -- call it with a modified
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1158) 	 * argument.
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1159) 	 */
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1160) 	default:
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1161) 		error = do_vfs_ioctl(f.file, fd, cmd,
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1162) 				     (unsigned long)compat_ptr(arg));
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1163) 		if (error != -ENOIOCTLCMD)
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1164) 			break;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1165) 
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1166) 		if (f.file->f_op->compat_ioctl)
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1167) 			error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1168) 		if (error == -ENOIOCTLCMD)
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1169) 			error = -ENOTTY;
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1170) 		break;
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1171) 	}
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1172) 
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1173)  out:
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1174) 	fdput(f);
77b9040195dea (Arnd Bergmann      2019-11-27 21:25:36 +0100 1175) 
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1176) 	return error;
2af563d071d63 (Arnd Bergmann      2019-06-07 10:06:42 +0200 1177) }
2952db0fd51b0 (Arnd Bergmann      2018-09-11 16:55:03 +0200 1178) #endif