^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/ext4/ioctl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1993, 1994, 1995
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Remy Card (card@masi.ibp.fr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Laboratoire MASI - Institut Blaise Pascal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Universite Pierre et Marie Curie (Paris VI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/quotaops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/uuid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "ext4_jbd2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "ext4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/fsmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "fsmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <trace/events/ext4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Swap memory between @a and @b for @len bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * @a: pointer to first memory area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @b: pointer to second memory area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @len: number of bytes to swap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static void memswap(void *a, void *b, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned char *ap, *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ap = (unsigned char *)a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) bp = (unsigned char *)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) while (len-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) swap(*ap, *bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ap++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) bp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Swap i_data and associated attributes between @inode1 and @inode2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * This function is used for the primary swap between inode1 and inode2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * and also to revert this primary swap in case of errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Therefore you have to make sure, that calling this method twice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * will revert all changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @inode1: pointer to first inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @inode2: pointer to second inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void swap_inode_data(struct inode *inode1, struct inode *inode2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) loff_t isize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct ext4_inode_info *ei1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct ext4_inode_info *ei2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ei1 = EXT4_I(inode1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ei2 = EXT4_I(inode2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) swap(inode1->i_version, inode2->i_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) swap(inode1->i_atime, inode2->i_atime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) swap(inode1->i_mtime, inode2->i_mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ei1->i_flags = (ei2->i_flags & EXT4_FL_SHOULD_SWAP) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) (ei1->i_flags & ~EXT4_FL_SHOULD_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ei2->i_flags = tmp | (ei2->i_flags & ~EXT4_FL_SHOULD_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) swap(ei1->i_disksize, ei2->i_disksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) isize = i_size_read(inode1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) i_size_write(inode1, i_size_read(inode2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) i_size_write(inode2, isize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) void ext4_reset_inode_seed(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct ext4_inode_info *ei = EXT4_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) __le32 inum = cpu_to_le32(inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) __le32 gen = cpu_to_le32(inode->i_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) __u32 csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!ext4_has_metadata_csum(inode->i_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&inum, sizeof(inum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ei->i_csum_seed = ext4_chksum(sbi, csum, (__u8 *)&gen, sizeof(gen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Swap the information from the given @inode and the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * EXT4_BOOT_LOADER_INO. It will basically swap i_data and all other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * important fields of the inodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @sb: the super block of the filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @inode: the inode to swap with EXT4_BOOT_LOADER_INO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static long swap_inode_boot_loader(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct inode *inode_bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct ext4_inode_info *ei_bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) qsize_t size, size_bl, diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) blkcnt_t blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned short bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (IS_ERR(inode_bl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return PTR_ERR(inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ei_bl = EXT4_I(inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Protect orig inodes against a truncate and make sure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * that only 1 swap_inode_boot_loader is running. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) lock_two_nondirectories(inode, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) IS_SWAPFILE(inode) || IS_ENCRYPTED(inode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ext4_has_inline_data(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto journal_err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (IS_RDONLY(inode) || IS_APPEND(inode) || IS_IMMUTABLE(inode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) goto journal_err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) down_write(&EXT4_I(inode)->i_mmap_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) err = filemap_write_and_wait(inode->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) err = filemap_write_and_wait(inode_bl->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* Wait for all existing dio workers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) inode_dio_wait(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) inode_dio_wait(inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) truncate_inode_pages(&inode->i_data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) truncate_inode_pages(&inode_bl->i_data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ext4_fc_start_ineligible(sb, EXT4_FC_REASON_SWAP_BOOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Protect extent tree against block allocations via delalloc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ext4_double_down_write_data_sem(inode, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (inode_bl->i_nlink == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* this inode has never been used as a BOOT_LOADER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) set_nlink(inode_bl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) i_uid_write(inode_bl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) i_gid_write(inode_bl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) inode_bl->i_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ei_bl->i_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) inode_set_iversion(inode_bl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) i_size_write(inode_bl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) inode_bl->i_mode = S_IFREG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (ext4_has_feature_extents(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ext4_ext_tree_init(handle, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data));
^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) err = dquot_initialize(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) goto err_out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) size = (qsize_t)(inode->i_blocks) * (1 << 9) + inode->i_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) size_bl = (qsize_t)(inode_bl->i_blocks) * (1 << 9) + inode_bl->i_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) diff = size - size_bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) swap_inode_data(inode, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) inode->i_ctime = inode_bl->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) inode->i_generation = prandom_u32();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) inode_bl->i_generation = prandom_u32();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ext4_reset_inode_seed(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ext4_reset_inode_seed(inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ext4_discard_preallocations(inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) err = ext4_mark_inode_dirty(handle, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* No need to update quota information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ext4_warning(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) "couldn't mark inode #%lu dirty (err %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) inode->i_ino, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Revert all changes: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) swap_inode_data(inode, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ext4_mark_inode_dirty(handle, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) goto err_out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) blocks = inode_bl->i_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) bytes = inode_bl->i_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) inode_bl->i_blocks = inode->i_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) inode_bl->i_bytes = inode->i_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) err = ext4_mark_inode_dirty(handle, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* No need to update quota information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ext4_warning(inode_bl->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) "couldn't mark inode #%lu dirty (err %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) inode_bl->i_ino, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) goto revert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Bootloader inode should not be counted into quota information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (diff > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dquot_free_space(inode, diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) err = dquot_alloc_space(inode, -1 * diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) revert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* Revert all changes: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) inode_bl->i_blocks = blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) inode_bl->i_bytes = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) swap_inode_data(inode, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ext4_mark_inode_dirty(handle, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ext4_mark_inode_dirty(handle, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) err_out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ext4_journal_stop(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ext4_fc_stop_ineligible(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ext4_double_up_write_data_sem(inode, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) up_write(&EXT4_I(inode)->i_mmap_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) journal_err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) unlock_two_nondirectories(inode, inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) iput(inode_bl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #ifdef CONFIG_FS_ENCRYPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int uuid_is_zero(__u8 u[16])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) for (i = 0; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (u[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #endif
^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) * If immutable is set and we are not clearing it, we're not allowed to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * anything else in the inode. Don't error out if we're only trying to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * immutable on an immutable file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static int ext4_ioctl_check_immutable(struct inode *inode, __u32 new_projid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct ext4_inode_info *ei = EXT4_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned int oldflags = ei->i_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (!(oldflags & EXT4_IMMUTABLE_FL) || !(flags & EXT4_IMMUTABLE_FL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if ((oldflags & ~EXT4_IMMUTABLE_FL) != (flags & ~EXT4_IMMUTABLE_FL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (ext4_has_feature_project(inode->i_sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) __kprojid_val(ei->i_projid) != new_projid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void ext4_dax_dontcache(struct inode *inode, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct ext4_inode_info *ei = EXT4_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (test_opt2(inode->i_sb, DAX_NEVER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) test_opt(inode->i_sb, DAX_ALWAYS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if ((ei->i_flags ^ flags) & EXT4_DAX_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) d_mark_dontcache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static bool dax_compatible(struct inode *inode, unsigned int oldflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* Allow the DAX flag to be changed on inline directories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (S_ISDIR(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) flags &= ~EXT4_INLINE_DATA_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) oldflags &= ~EXT4_INLINE_DATA_FL;
^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) if (flags & EXT4_DAX_FL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if ((oldflags & EXT4_DAX_MUT_EXCL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ext4_test_inode_state(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) EXT4_STATE_VERITY_IN_PROGRESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if ((flags & EXT4_DAX_MUT_EXCL) && (oldflags & EXT4_DAX_FL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int ext4_ioctl_setflags(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct ext4_inode_info *ei = EXT4_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) handle_t *handle = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int err = -EPERM, migrate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct ext4_iloc iloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned int oldflags, mask, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* Is it quota file? Do not allow user to mess with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (ext4_is_quota_file(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) oldflags = ei->i_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) err = vfs_ioc_setflags_prepare(inode, oldflags, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * The JOURNAL_DATA flag can only be changed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * the relevant capability.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (!capable(CAP_SYS_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!dax_compatible(inode, oldflags, flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) migrate = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (!ext4_has_feature_casefold(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (!S_ISDIR(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) err = -ENOTDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!ext4_empty_dir(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) err = -ENOTEMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * Wait for all pending directio and then flush all the dirty pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * for this file. The flush marks all the pages readonly, so any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * subsequent attempt to write to the file (particularly mmap pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * will come through the filesystem and fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (S_ISREG(inode->i_mode) && !IS_IMMUTABLE(inode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) (flags & EXT4_IMMUTABLE_FL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) inode_dio_wait(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) err = filemap_write_and_wait(inode->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) err = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (IS_SYNC(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ext4_handle_sync(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) err = ext4_reserve_inode_write(handle, inode, &iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) goto flags_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ext4_dax_dontcache(inode, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (!(mask & EXT4_FL_USER_MODIFIABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* These flags get special treatment later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (mask == EXT4_JOURNAL_DATA_FL || mask == EXT4_EXTENTS_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (mask & flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ext4_set_inode_flag(inode, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ext4_clear_inode_flag(inode, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ext4_set_inode_flags(inode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) err = ext4_mark_iloc_dirty(handle, inode, &iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) flags_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ext4_journal_stop(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * Changes to the journaling mode can cause unsafe changes to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * S_DAX if the inode is DAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (IS_DAX(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) err = ext4_change_inode_journal_flag(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) flags & EXT4_JOURNAL_DATA_FL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto flags_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (migrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (flags & EXT4_EXTENTS_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) err = ext4_ext_migrate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) err = ext4_ind_migrate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) flags_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #ifdef CONFIG_QUOTA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct ext4_inode_info *ei = EXT4_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int err, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) kprojid_t kprojid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct ext4_iloc iloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct ext4_inode *raw_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct dquot *transfer_to[MAXQUOTAS] = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (!ext4_has_feature_project(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (projid != EXT4_DEF_PROJID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (EXT4_INODE_SIZE(sb) <= EXT4_GOOD_OLD_INODE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* Is it quota file? Do not allow user to mess with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (ext4_is_quota_file(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) err = ext4_get_inode_loc(inode, &iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) raw_inode = ext4_raw_inode(&iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) err = ext4_expand_extra_isize(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) EXT4_SB(sb)->s_want_extra_isize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) &iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) brelse(iloc.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) err = dquot_initialize(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) EXT4_QUOTA_INIT_BLOCKS(sb) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (IS_ERR(handle))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) err = ext4_reserve_inode_write(handle, inode, &iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) goto out_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (!IS_ERR(transfer_to[PRJQUOTA])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* __dquot_transfer() calls back ext4_get_inode_usage() which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * counts xattr inode references.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) down_read(&EXT4_I(inode)->xattr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) err = __dquot_transfer(inode, transfer_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) up_read(&EXT4_I(inode)->xattr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) dqput(transfer_to[PRJQUOTA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) goto out_dirty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) EXT4_I(inode)->i_projid = kprojid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) out_dirty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) err = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) out_stop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ext4_journal_stop(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (projid != EXT4_DEF_PROJID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* Transfer internal flags to xflags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) __u32 xflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (iflags & EXT4_SYNC_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) xflags |= FS_XFLAG_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (iflags & EXT4_IMMUTABLE_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) xflags |= FS_XFLAG_IMMUTABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (iflags & EXT4_APPEND_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) xflags |= FS_XFLAG_APPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (iflags & EXT4_NODUMP_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) xflags |= FS_XFLAG_NODUMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (iflags & EXT4_NOATIME_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) xflags |= FS_XFLAG_NOATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (iflags & EXT4_PROJINHERIT_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) xflags |= FS_XFLAG_PROJINHERIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (iflags & EXT4_DAX_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) xflags |= FS_XFLAG_DAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return xflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) #define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) FS_XFLAG_DAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* Transfer xflags flags to internal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) unsigned long iflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (xflags & FS_XFLAG_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) iflags |= EXT4_SYNC_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (xflags & FS_XFLAG_IMMUTABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) iflags |= EXT4_IMMUTABLE_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (xflags & FS_XFLAG_APPEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) iflags |= EXT4_APPEND_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (xflags & FS_XFLAG_NODUMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) iflags |= EXT4_NODUMP_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (xflags & FS_XFLAG_NOATIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) iflags |= EXT4_NOATIME_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (xflags & FS_XFLAG_PROJINHERIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) iflags |= EXT4_PROJINHERIT_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (xflags & FS_XFLAG_DAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) iflags |= EXT4_DAX_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return iflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int ext4_shutdown(struct super_block *sb, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct ext4_sb_info *sbi = EXT4_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) __u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (get_user(flags, (__u32 __user *)arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (flags > EXT4_GOING_FLAGS_NOLOGFLUSH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (ext4_forced_shutdown(sbi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ext4_msg(sb, KERN_ALERT, "shut down requested (%d)", flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) trace_ext4_shutdown(sb, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) switch (flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) case EXT4_GOING_FLAGS_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) freeze_bdev(sb->s_bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) thaw_bdev(sb->s_bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case EXT4_GOING_FLAGS_LOGFLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) (void) ext4_force_commit(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) case EXT4_GOING_FLAGS_NOLOGFLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (sbi->s_journal && !is_journal_aborted(sbi->s_journal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) clear_opt(sb, DISCARD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct getfsmap_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct super_block *gi_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct fsmap_head __user *gi_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) unsigned int gi_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) __u32 gi_last_flags;
^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) static int ext4_getfsmap_format(struct ext4_fsmap *xfm, void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct getfsmap_info *info = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct fsmap fm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) trace_ext4_getfsmap_mapping(info->gi_sb, xfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) info->gi_last_flags = xfm->fmr_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ext4_fsmap_from_internal(info->gi_sb, &fm, xfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (copy_to_user(&info->gi_data->fmh_recs[info->gi_idx++], &fm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) sizeof(struct fsmap)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static int ext4_ioc_getfsmap(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct fsmap_head __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct getfsmap_info info = { NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct ext4_fsmap_head xhead = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct fsmap_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) bool aborted = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (copy_from_user(&head, arg, sizeof(struct fsmap_head)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) memchr_inv(head.fmh_keys[0].fmr_reserved, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) sizeof(head.fmh_keys[0].fmr_reserved)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) memchr_inv(head.fmh_keys[1].fmr_reserved, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) sizeof(head.fmh_keys[1].fmr_reserved)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * ext4 doesn't report file extents at all, so the only valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * file offsets are the magic ones (all zeroes or all ones).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (head.fmh_keys[0].fmr_offset ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) (head.fmh_keys[1].fmr_offset != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) head.fmh_keys[1].fmr_offset != -1ULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) xhead.fmh_iflags = head.fmh_iflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) xhead.fmh_count = head.fmh_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ext4_fsmap_to_internal(sb, &xhead.fmh_keys[0], &head.fmh_keys[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ext4_fsmap_to_internal(sb, &xhead.fmh_keys[1], &head.fmh_keys[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) trace_ext4_getfsmap_low_key(sb, &xhead.fmh_keys[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) trace_ext4_getfsmap_high_key(sb, &xhead.fmh_keys[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) info.gi_sb = sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) info.gi_data = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) error = ext4_getfsmap(sb, &xhead, ext4_getfsmap_format, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (error == EXT4_QUERY_RANGE_ABORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) aborted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) } else if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* If we didn't abort, set the "last" flag in the last fmx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (!aborted && info.gi_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) info.gi_last_flags |= FMR_OF_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (copy_to_user(&info.gi_data->fmh_recs[info.gi_idx - 1].fmr_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) &info.gi_last_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) sizeof(info.gi_last_flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* copy back header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) head.fmh_entries = xhead.fmh_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) head.fmh_oflags = xhead.fmh_oflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (copy_to_user(arg, &head, sizeof(struct fsmap_head)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static long ext4_ioctl_group_add(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct ext4_new_group_data *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct super_block *sb = file_inode(file)->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) int err, err2=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) err = ext4_resize_begin(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (ext4_has_feature_bigalloc(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ext4_msg(sb, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) "Online resizing not supported with bigalloc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) goto group_add_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) err = mnt_want_write_file(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) goto group_add_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) err = ext4_group_add(sb, input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (EXT4_SB(sb)->s_journal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) err = err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) mnt_drop_write_file(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!err && ext4_has_group_desc_csum(sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) test_opt(sb, INIT_INODE_TABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) err = ext4_register_li_request(sb, input->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) group_add_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ext4_resize_end(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static void ext4_fill_fsxattr(struct inode *inode, struct fsxattr *fa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct ext4_inode_info *ei = EXT4_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) simple_fill_fsxattr(fa, ext4_iflags_to_xflags(ei->i_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) EXT4_FL_USER_VISIBLE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (ext4_has_feature_project(inode->i_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /* So that the fiemap access checks can't overflow on 32 bit machines. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) #define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct fiemap fiemap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct fiemap __user *ufiemap = (struct fiemap __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct fiemap_extent_info fieinfo = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) fieinfo.fi_flags = fiemap.fm_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) fieinfo.fi_extents_max = fiemap.fm_extent_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) fieinfo.fi_extents_start = ufiemap->fm_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) error = ext4_get_es_cache(inode, &fieinfo, fiemap.fm_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) fiemap.fm_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) fiemap.fm_flags = fieinfo.fi_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct ext4_inode_info *ei = EXT4_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ext4_debug("cmd = %u, arg = %lu\n", cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case FS_IOC_GETFSMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return ext4_ioc_getfsmap(sb, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) case FS_IOC_GETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) flags &= ~EXT4_PROJINHERIT_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return put_user(flags, (int __user *) arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case FS_IOC_SETFLAGS: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (!inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (get_user(flags, (int __user *) arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (flags & ~EXT4_FL_USER_VISIBLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * chattr(1) grabs flags via GETFLAGS, modifies the result and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * passes that to SETFLAGS. So we cannot easily make SETFLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * more restrictive than just silently masking off visible but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * not settable flags as we always did.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) flags &= EXT4_FL_USER_MODIFIABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (ext4_mask_flags(inode->i_mode, flags) != flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) err = ext4_ioctl_check_immutable(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) from_kprojid(&init_user_ns, ei->i_projid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) err = ext4_ioctl_setflags(inode, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) case EXT4_IOC_GETVERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) case EXT4_IOC_GETVERSION_OLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return put_user(inode->i_generation, (int __user *) arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case EXT4_IOC_SETVERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) case EXT4_IOC_SETVERSION_OLD: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct ext4_iloc iloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) __u32 generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (!inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (ext4_has_metadata_csum(inode->i_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ext4_warning(sb, "Setting inode version is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) "supported with metadata_csum enabled.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (get_user(generation, (int __user *) arg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) goto setversion_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) err = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) goto unlock_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) err = ext4_reserve_inode_write(handle, inode, &iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) inode->i_generation = generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) err = ext4_mark_iloc_dirty(handle, inode, &iloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) ext4_journal_stop(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) unlock_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) setversion_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) case EXT4_IOC_GROUP_EXTEND: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ext4_fsblk_t n_blocks_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int err, err2=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) err = ext4_resize_begin(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (get_user(n_blocks_count, (__u32 __user *)arg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) goto group_extend_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (ext4_has_feature_bigalloc(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ext4_msg(sb, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) "Online resizing not supported with bigalloc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) goto group_extend_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) goto group_extend_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (EXT4_SB(sb)->s_journal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) err = err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) group_extend_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ext4_resize_end(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) case EXT4_IOC_MOVE_EXT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct move_extent me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct fd donor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (!(filp->f_mode & FMODE_READ) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) !(filp->f_mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (copy_from_user(&me,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) (struct move_extent __user *)arg, sizeof(me)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) me.moved_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) donor = fdget(me.donor_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (!donor.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (!(donor.file->f_mode & FMODE_WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) err = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) goto mext_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (ext4_has_feature_bigalloc(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) ext4_msg(sb, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) "Online defrag not supported with bigalloc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) goto mext_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) } else if (IS_DAX(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) ext4_msg(sb, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) "Online defrag not supported with DAX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) goto mext_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) goto mext_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) err = ext4_move_extents(filp, donor.file, me.orig_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) me.donor_start, me.len, &me.moved_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (copy_to_user((struct move_extent __user *)arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) &me, sizeof(me)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) mext_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) fdput(donor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) case EXT4_IOC_GROUP_ADD: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct ext4_new_group_data input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) sizeof(input)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return ext4_ioctl_group_add(filp, &input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) case EXT4_IOC_MIGRATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (!inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * inode_mutex prevent write and truncate on the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * Read still goes through. We take i_data_sem in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * ext4_ext_swap_inode_data before we switch the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * inode format to prevent read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) inode_lock((inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) err = ext4_ext_migrate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) inode_unlock((inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) case EXT4_IOC_ALLOC_DA_BLKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (!inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) err = ext4_alloc_da_blocks(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) case EXT4_IOC_SWAP_BOOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (!(filp->f_mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) err = swap_inode_boot_loader(sb, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) case EXT4_IOC_RESIZE_FS: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ext4_fsblk_t n_blocks_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) int err = 0, err2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) ext4_group_t o_group = EXT4_SB(sb)->s_groups_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (copy_from_user(&n_blocks_count, (__u64 __user *)arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) sizeof(__u64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) err = ext4_resize_begin(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) goto resizefs_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) err = ext4_resize_fs(sb, n_blocks_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (EXT4_SB(sb)->s_journal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_RESIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) err = err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (!err && (o_group < EXT4_SB(sb)->s_groups_count) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ext4_has_group_desc_csum(sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) test_opt(sb, INIT_INODE_TABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) err = ext4_register_li_request(sb, o_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) resizefs_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) ext4_resize_end(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) case FITRIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct request_queue *q = bdev_get_queue(sb->s_bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct fstrim_range range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (!blk_queue_discard(q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * We haven't replayed the journal, so we cannot use our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * block-bitmap-guided storage zapping commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (copy_from_user(&range, (struct fstrim_range __user *)arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) sizeof(range)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) ret = ext4_trim_fs(sb, &range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (copy_to_user((struct fstrim_range __user *)arg, &range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) sizeof(range)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) case EXT4_IOC_PRECACHE_EXTENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return ext4_ext_precache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) case FS_IOC_SET_ENCRYPTION_POLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) case FS_IOC_GET_ENCRYPTION_PWSALT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) #ifdef CONFIG_FS_ENCRYPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) int err, err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct ext4_sb_info *sbi = EXT4_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (uuid_is_zero(sbi->s_es->s_encrypt_pw_salt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) err = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) goto pwsalt_err_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) err = ext4_journal_get_write_access(handle, sbi->s_sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) goto pwsalt_err_journal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) lock_buffer(sbi->s_sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) generate_random_uuid(sbi->s_es->s_encrypt_pw_salt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) ext4_superblock_csum_set(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) unlock_buffer(sbi->s_sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) err = ext4_handle_dirty_metadata(handle, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) sbi->s_sbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) pwsalt_err_journal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) err2 = ext4_journal_stop(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (err2 && !err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) err = err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) pwsalt_err_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (copy_to_user((void __user *) arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) sbi->s_es->s_encrypt_pw_salt, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) case FS_IOC_GET_ENCRYPTION_POLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) return fscrypt_ioctl_get_policy(filp, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) case FS_IOC_GET_ENCRYPTION_POLICY_EX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) return fscrypt_ioctl_get_policy_ex(filp, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) case FS_IOC_ADD_ENCRYPTION_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return fscrypt_ioctl_add_key(filp, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) case FS_IOC_REMOVE_ENCRYPTION_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return fscrypt_ioctl_remove_key(filp, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return fscrypt_ioctl_remove_key_all_users(filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) case FS_IOC_GET_ENCRYPTION_KEY_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return fscrypt_ioctl_get_key_status(filp, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) case FS_IOC_GET_ENCRYPTION_NONCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (!ext4_has_feature_encrypt(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return fscrypt_ioctl_get_nonce(filp, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) case EXT4_IOC_CLEAR_ES_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (!inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) ext4_clear_inode_es(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) case EXT4_IOC_GETSTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) __u32 state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (ext4_test_inode_state(inode, EXT4_STATE_EXT_PRECACHED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) state |= EXT4_STATE_FLAG_EXT_PRECACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (ext4_test_inode_state(inode, EXT4_STATE_NEW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) state |= EXT4_STATE_FLAG_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) state |= EXT4_STATE_FLAG_NEWENTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (ext4_test_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) state |= EXT4_STATE_FLAG_DA_ALLOC_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return put_user(state, (__u32 __user *) arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) case EXT4_IOC_GET_ES_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return ext4_ioctl_get_es_cache(filp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) case FS_IOC_FSGETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) struct fsxattr fa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ext4_fill_fsxattr(inode, &fa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (copy_to_user((struct fsxattr __user *)arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) &fa, sizeof(fa)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) case FS_IOC_FSSETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) struct fsxattr fa, old_fa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (copy_from_user(&fa, (struct fsxattr __user *)arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) sizeof(fa)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) /* Make sure caller has proper permission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (!inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if (fa.fsx_xflags & ~EXT4_SUPPORTED_FS_XFLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) flags = ext4_xflags_to_iflags(fa.fsx_xflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (ext4_mask_flags(inode->i_mode, flags) != flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) err = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) ext4_fill_fsxattr(inode, &old_fa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) err = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) (flags & EXT4_FL_XFLAG_VISIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) err = ext4_ioctl_check_immutable(inode, fa.fsx_projid, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) err = ext4_ioctl_setflags(inode, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) err = ext4_ioctl_setproject(filp, fa.fsx_projid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) case EXT4_IOC_SHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return ext4_shutdown(sb, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) case FS_IOC_ENABLE_VERITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (!ext4_has_feature_verity(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return fsverity_ioctl_enable(filp, (const void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) case FS_IOC_MEASURE_VERITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (!ext4_has_feature_verity(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return fsverity_ioctl_measure(filp, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) case FS_IOC_READ_VERITY_METADATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (!ext4_has_feature_verity(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return fsverity_ioctl_read_metadata(filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) (const void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) ext4_fc_start_update(file_inode(filp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) ret = __ext4_ioctl(filp, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ext4_fc_stop_update(file_inode(filp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) /* These are just misnamed, they actually get/put from/to user an int */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) case FS_IOC32_GETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) cmd = FS_IOC_GETFLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) case FS_IOC32_SETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) cmd = FS_IOC_SETFLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) case EXT4_IOC32_GETVERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) cmd = EXT4_IOC_GETVERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) case EXT4_IOC32_SETVERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) cmd = EXT4_IOC_SETVERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) case EXT4_IOC32_GROUP_EXTEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) cmd = EXT4_IOC_GROUP_EXTEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) case EXT4_IOC32_GETVERSION_OLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) cmd = EXT4_IOC_GETVERSION_OLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) case EXT4_IOC32_SETVERSION_OLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) cmd = EXT4_IOC_SETVERSION_OLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) case EXT4_IOC32_GETRSVSZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) cmd = EXT4_IOC_GETRSVSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) case EXT4_IOC32_SETRSVSZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) cmd = EXT4_IOC_SETRSVSZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) case EXT4_IOC32_GROUP_ADD: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) struct compat_ext4_new_group_input __user *uinput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) struct ext4_new_group_data input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) uinput = compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) err = get_user(input.group, &uinput->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) err |= get_user(input.block_bitmap, &uinput->block_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) err |= get_user(input.inode_bitmap, &uinput->inode_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) err |= get_user(input.inode_table, &uinput->inode_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) err |= get_user(input.blocks_count, &uinput->blocks_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) err |= get_user(input.reserved_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) &uinput->reserved_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return ext4_ioctl_group_add(file, &input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) case EXT4_IOC_MOVE_EXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) case EXT4_IOC_RESIZE_FS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) case FITRIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) case EXT4_IOC_PRECACHE_EXTENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) case FS_IOC_SET_ENCRYPTION_POLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) case FS_IOC_GET_ENCRYPTION_PWSALT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) case FS_IOC_GET_ENCRYPTION_POLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) case FS_IOC_GET_ENCRYPTION_POLICY_EX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) case FS_IOC_ADD_ENCRYPTION_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) case FS_IOC_REMOVE_ENCRYPTION_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) case FS_IOC_GET_ENCRYPTION_KEY_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) case FS_IOC_GET_ENCRYPTION_NONCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) case EXT4_IOC_SHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) case FS_IOC_GETFSMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) case FS_IOC_ENABLE_VERITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) case FS_IOC_MEASURE_VERITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) case FS_IOC_READ_VERITY_METADATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) case EXT4_IOC_CLEAR_ES_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) case EXT4_IOC_GETSTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) case EXT4_IOC_GET_ES_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) case FS_IOC_FSGETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) case FS_IOC_FSSETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) return ext4_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) #endif