^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/ioctl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/writeback.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/buffer_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/falloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/fiemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/ioctls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* So that the fiemap access checks can't overflow on 32 bit machines. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * vfs_ioctl - call filesystem specific ioctl methods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * @filp: open file to invoke ioctl method on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @cmd: ioctl command to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @arg: command-specific argument for ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * returns -ENOTTY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Returns 0 on success, -errno on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int error = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (!filp->f_op->unlocked_ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (error == -ENOIOCTLCMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) error = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) EXPORT_SYMBOL(vfs_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int ioctl_fibmap(struct file *filp, int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int error, ur_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) sector_t block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!capable(CAP_SYS_RAWIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) error = get_user(ur_block, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (ur_block < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) block = ur_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) error = bmap(inode, &block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (block > INT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) error = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) current->comm, task_pid_nr(current),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) sb->s_id, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ur_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ur_block = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (put_user(ur_block, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * fiemap_fill_next_extent - Fiemap helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * @fieinfo: Fiemap context passed into ->fiemap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @logical: Extent logical start offset, in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @phys: Extent physical start offset, in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @len: Extent length, in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @flags: FIEMAP_EXTENT flags that describe this extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * Called from file system ->fiemap callback. Will populate extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * info as passed in via arguments and copy to user memory. On
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * success, extent count on fieinfo is incremented.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Returns 0 on success, -errno on error, 1 if this was the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * extent that will fit in user array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define SET_UNKNOWN_FLAGS (FIEMAP_EXTENT_DELALLOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define SET_NO_UNMOUNTED_IO_FLAGS (FIEMAP_EXTENT_DATA_ENCRYPTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define SET_NOT_ALIGNED_FLAGS (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u64 phys, u64 len, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct fiemap_extent extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* only count the extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (fieinfo->fi_extents_max == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) fieinfo->fi_extents_mapped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (flags & SET_UNKNOWN_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) flags |= FIEMAP_EXTENT_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) flags |= FIEMAP_EXTENT_ENCODED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (flags & SET_NOT_ALIGNED_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) flags |= FIEMAP_EXTENT_NOT_ALIGNED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) memset(&extent, 0, sizeof(extent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) extent.fe_logical = logical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) extent.fe_physical = phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) extent.fe_length = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) extent.fe_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dest += fieinfo->fi_extents_mapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (copy_to_user(dest, &extent, sizeof(extent)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) fieinfo->fi_extents_mapped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) EXPORT_SYMBOL_NS(fiemap_fill_next_extent, ANDROID_GKI_VFS_EXPORT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * fiemap_prep - check validity of requested flags for fiemap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @inode: Inode to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @fieinfo: Fiemap context passed into ->fiemap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @start: Start of the mapped range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @len: Length of the mapped range, can be truncated by this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @supported_flags: Set of fiemap flags that the file system understands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * This function must be called from each ->fiemap instance to validate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * fiemap request against the file system parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * Returns 0 on success, or a negative error on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) u64 start, u64 *len, u32 supported_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u64 maxbytes = inode->i_sb->s_maxbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u32 incompat_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (*len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (start > maxbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * Shrink request scope to what the fs can actually handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (*len > maxbytes || (maxbytes - *len) < start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *len = maxbytes - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) supported_flags |= FIEMAP_FLAG_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) supported_flags &= FIEMAP_FLAGS_COMPAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) incompat_flags = fieinfo->fi_flags & ~supported_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (incompat_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) fieinfo->fi_flags = incompat_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -EBADR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ret = filemap_write_and_wait(inode->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) EXPORT_SYMBOL_NS(fiemap_prep, ANDROID_GKI_VFS_EXPORT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct fiemap fiemap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct fiemap_extent_info fieinfo = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!inode->i_op->fiemap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) fieinfo.fi_flags = fiemap.fm_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) fieinfo.fi_extents_max = fiemap.fm_extent_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) fieinfo.fi_extents_start = ufiemap->fm_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) fiemap.fm_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) fiemap.fm_flags = fieinfo.fi_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u64 off, u64 olen, u64 destoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct fd src_file = fdget(srcfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) loff_t cloned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (!src_file.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ret = -EXDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) goto fdput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) olen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (cloned < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ret = cloned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) else if (olen && cloned != olen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) fdput:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) fdput(src_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static long ioctl_file_clone_range(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct file_clone_range __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct file_clone_range args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (copy_from_user(&args, argp, sizeof(args)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return ioctl_file_clone(file, args.src_fd, args.src_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) args.src_length, args.dest_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #ifdef CONFIG_BLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return (offset >> inode->i_blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return (blk << inode->i_blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * __generic_block_fiemap - FIEMAP for block based inodes (no locking)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * @inode: the inode to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * @fieinfo: the fiemap info struct that will be passed back to userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * @start: where to start mapping in the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * @len: how much space to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * @get_block: the fs's get_block function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * This does FIEMAP for block based inodes. Basically it will just loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * through get_block until we hit the number of extents we want to map, or we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * go past the end of the file and hit a hole.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * If it is possible to have data blocks beyond a hole past @inode->i_size, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * please do not use this function, it will stop at the first unmapped block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * beyond i_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * If you use this function directly, you need to do your own locking. Use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * generic_block_fiemap if you want the locking done for you.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int __generic_block_fiemap(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct fiemap_extent_info *fieinfo, loff_t start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) loff_t len, get_block_t *get_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct buffer_head map_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sector_t start_blk, last_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) loff_t isize = i_size_read(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) u64 logical = 0, phys = 0, size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) u32 flags = FIEMAP_EXTENT_MERGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) bool past_eof = false, whole_file = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = fiemap_prep(inode, fieinfo, start, &len, FIEMAP_FLAG_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * Either the i_mutex or other appropriate locking needs to be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * since we expect isize to not change at all through the duration of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * this call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (len >= isize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) whole_file = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) len = isize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * Some filesystems can't deal with being asked to map less than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * blocksize, so make sure our len is at least block length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (logical_to_blk(inode, len) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) len = blk_to_logical(inode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) start_blk = logical_to_blk(inode, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) last_blk = logical_to_blk(inode, start + len - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * we set b_size to the total size we want so it will map as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * many contiguous blocks as possible at once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) memset(&map_bh, 0, sizeof(struct buffer_head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) map_bh.b_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ret = get_block(inode, start_blk, &map_bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* HOLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!buffer_mapped(&map_bh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) start_blk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * We want to handle the case where there is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * allocated block at the front of the file, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * nothing but holes up to the end of the file properly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * to make sure that extent at the front gets properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * marked with FIEMAP_EXTENT_LAST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!past_eof &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) blk_to_logical(inode, start_blk) >= isize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) past_eof = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * First hole after going past the EOF, this is our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * last extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (past_eof && size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = fiemap_fill_next_extent(fieinfo, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) phys, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) } else if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ret = fiemap_fill_next_extent(fieinfo, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) phys, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* if we have holes up to/past EOF then we're done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (start_blk > last_blk || past_eof || ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * We have gone over the length of what we wanted to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * map, and it wasn't the entire file, so add the extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * we got last time and exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * This is for the case where say we want to map all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * way up to the second to the last block in a file, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * the last block is a hole, making the second to last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * block FIEMAP_EXTENT_LAST. In this case we want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * see if there is a hole after the second to last block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * so we can mark it properly. If we found data after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * we exceeded the length we were requesting, then we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * are good to go, just add the extent to the fieinfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * and break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (start_blk > last_blk && !whole_file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ret = fiemap_fill_next_extent(fieinfo, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) phys, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * if size != 0 then we know we already have an extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * to add, so add it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ret = fiemap_fill_next_extent(fieinfo, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) phys, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) logical = blk_to_logical(inode, start_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) phys = blk_to_logical(inode, map_bh.b_blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) size = map_bh.b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) flags = FIEMAP_EXTENT_MERGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) start_blk += logical_to_blk(inode, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * If we are past the EOF, then we need to make sure as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * soon as we find a hole that the last extent we found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * is marked with FIEMAP_EXTENT_LAST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!past_eof && logical + size >= isize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) past_eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (fatal_signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ret = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* If ret is 1 then we just hit the end of the extent array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (ret == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * generic_block_fiemap - FIEMAP for block based inodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * @inode: The inode to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * @fieinfo: The mapping information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * @start: The initial block to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * @len: The length of the extect to attempt to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * @get_block: The block mapping function for the fs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * Calls __generic_block_fiemap to map the inode, after taking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * the inode's mutex lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int generic_block_fiemap(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct fiemap_extent_info *fieinfo, u64 start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) u64 len, get_block_t *get_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ret = __generic_block_fiemap(inode, fieinfo, start, len, get_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) EXPORT_SYMBOL(generic_block_fiemap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #endif /* CONFIG_BLOCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * This provides compatibility with legacy XFS pre-allocation ioctls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * which predate the fallocate syscall.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * are used here, rest are ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct space_resv sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (copy_from_user(&sr, argp, sizeof(sr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) switch (sr.l_whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) case SEEK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) sr.l_start += filp->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case SEEK_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sr.l_start += i_size_read(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) sr.l_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* on ia32 l_start is on a 32-bit boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* just account for different alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int compat_ioctl_preallocate(struct file *file, int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct space_resv_32 __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct space_resv_32 sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (copy_from_user(&sr, argp, sizeof(sr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) switch (sr.l_whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case SEEK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) sr.l_start += file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) case SEEK_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) sr.l_start += i_size_read(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) case FIBMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return ioctl_fibmap(filp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) case FS_IOC_RESVSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case FS_IOC_RESVSP64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return ioctl_preallocate(filp, 0, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case FS_IOC_UNRESVSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) case FS_IOC_UNRESVSP64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) case FS_IOC_ZERO_RANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static int ioctl_fionbio(struct file *filp, int __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) unsigned int flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int on, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) error = get_user(on, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) flag = O_NONBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) #ifdef __sparc__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* SunOS compatibility item. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (O_NONBLOCK != O_NDELAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) flag |= O_NDELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) spin_lock(&filp->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) filp->f_flags |= flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) filp->f_flags &= ~flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) spin_unlock(&filp->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int ioctl_fioasync(unsigned int fd, struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) unsigned int flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int on, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) error = get_user(on, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) flag = on ? FASYNC : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Did FASYNC state change ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if ((flag ^ filp->f_flags) & FASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (filp->f_op->fasync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* fasync() adjusts filp->f_flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) error = filp->f_op->fasync(fd, filp, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) error = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return error < 0 ? error : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static int ioctl_fsfreeze(struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct super_block *sb = file_inode(filp)->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* If filesystem doesn't support freeze feature, return. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Freeze */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (sb->s_op->freeze_super)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return sb->s_op->freeze_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return freeze_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int ioctl_fsthaw(struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct super_block *sb = file_inode(filp)->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /* Thaw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (sb->s_op->thaw_super)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return sb->s_op->thaw_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return thaw_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static int ioctl_file_dedupe_range(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct file_dedupe_range __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct file_dedupe_range *same = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) u16 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (get_user(count, &argp->dest_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) size = offsetof(struct file_dedupe_range __user, info[count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (size > PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) same = memdup_user(argp, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (IS_ERR(same)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ret = PTR_ERR(same);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) same = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) same->dest_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ret = vfs_dedupe_file_range(file, same);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) ret = copy_to_user(argp, same, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) kfree(same);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * When you add any new common ioctls to the switches above and below,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * please ensure they have compatible arguments in compat mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int do_vfs_ioctl(struct file *filp, unsigned int fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case FIOCLEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) set_close_on_exec(fd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case FIONCLEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) set_close_on_exec(fd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case FIONBIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return ioctl_fionbio(filp, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) case FIOASYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return ioctl_fioasync(fd, filp, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) case FIOQSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) S_ISLNK(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) loff_t res = inode_get_bytes(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return copy_to_user(argp, &res, sizeof(res)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) case FIFREEZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return ioctl_fsfreeze(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) case FITHAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return ioctl_fsthaw(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) case FS_IOC_FIEMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return ioctl_fiemap(filp, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) case FIGETBSZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* anon_bdev filesystems may not have a block size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!inode->i_sb->s_blocksize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return put_user(inode->i_sb->s_blocksize, (int __user *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) case FICLONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return ioctl_file_clone(filp, arg, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) case FICLONERANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return ioctl_file_clone_range(filp, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case FIDEDUPERANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return ioctl_file_dedupe_range(filp, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) case FIONREAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (!S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return vfs_ioctl(filp, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return put_user(i_size_read(inode) - filp->f_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) (int __user *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return file_ioctl(filp, cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct fd f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) error = security_file_ioctl(f.file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) error = do_vfs_ioctl(f.file, fd, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (error == -ENOIOCTLCMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) error = vfs_ioctl(f.file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * compat_ptr_ioctl - generic implementation of .compat_ioctl file operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * This is not normally called as a function, but instead set in struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * file_operations as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * .compat_ioctl = compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * On most architectures, the compat_ptr_ioctl() just passes all arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * to the corresponding ->ioctl handler. The exception is arch/s390, where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * compat_ptr() clears the top bit of a 32-bit pointer value, so user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * pointers to the second 2GB alias the first 2GB, as is the case for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * native 32-bit s390 user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * The compat_ptr_ioctl() function must therefore be used only with ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * functions that either ignore the argument or pass a pointer to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * compatible data type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * If any ioctl command handled by fops->unlocked_ioctl passes a plain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * integer instead of a pointer, or any of the passed data types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * is incompatible between 32-bit and 64-bit architectures, a proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * handler is required instead of compat_ptr_ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (!file->f_op->unlocked_ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) EXPORT_SYMBOL(compat_ptr_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) compat_ulong_t, arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct fd f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* RED-PEN how should LSM module know it's handling 32bit? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) error = security_file_ioctl(f.file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* FICLONE takes an int argument, so don't use compat_ptr() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) case FICLONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) error = ioctl_file_clone(f.file, arg, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #if defined(CONFIG_X86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* these get messy on amd64 due to alignment differences */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case FS_IOC_RESVSP_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case FS_IOC_RESVSP64_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) case FS_IOC_UNRESVSP_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) case FS_IOC_UNRESVSP64_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) compat_ptr(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) case FS_IOC_ZERO_RANGE_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) compat_ptr(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * everything else in do_vfs_ioctl() takes either a compatible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * pointer argument or no argument -- call it with a modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) error = do_vfs_ioctl(f.file, fd, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) (unsigned long)compat_ptr(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (error != -ENOIOCTLCMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (f.file->f_op->compat_ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (error == -ENOIOCTLCMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) error = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) #endif