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