1 // SPDX-License-Identifier: GPL-2.0 2 #ifndef NO_BCACHEFS_FS 3 4 #include "bcachefs.h" 5 #include "chardev.h" 6 #include "dirent.h" 7 #include "fs.h" 8 #include "fs-ioctl.h" 9 #include "namei.h" 10 #include "quota.h" 11 12 #include <linux/compat.h> 13 #include <linux/fsnotify.h> 14 #include <linux/mount.h> 15 #include <linux/namei.h> 16 #include <linux/security.h> 17 #include <linux/writeback.h> 18 19 #define FS_IOC_GOINGDOWN _IOR('X', 125, __u32) 20 #define FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */ 21 #define FSOP_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */ 22 #define FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ 23 24 static int bch2_reinherit_attrs_fn(struct btree_trans *trans, 25 struct bch_inode_info *inode, 26 struct bch_inode_unpacked *bi, 27 void *p) 28 { 29 struct bch_inode_info *dir = p; 30 31 return !bch2_reinherit_attrs(bi, &dir->ei_inode); 32 } 33 34 static int bch2_ioc_reinherit_attrs(struct bch_fs *c, 35 struct file *file, 36 struct bch_inode_info *src, 37 const char __user *name) 38 { 39 struct bch_hash_info hash = bch2_hash_info_init(c, &src->ei_inode); 40 struct bch_inode_info *dst; 41 struct inode *vinode = NULL; 42 char *kname = NULL; 43 struct qstr qstr; 44 int ret = 0; 45 subvol_inum inum; 46 47 kname = kmalloc(BCH_NAME_MAX, GFP_KERNEL); 48 if (!kname) 49 return -ENOMEM; 50 51 ret = strncpy_from_user(kname, name, BCH_NAME_MAX); 52 if (unlikely(ret < 0)) 53 goto err1; 54 55 qstr.len = ret; 56 qstr.name = kname; 57 58 ret = bch2_dirent_lookup(c, inode_inum(src), &hash, &qstr, &inum); 59 if (ret) 60 goto err1; 61 62 vinode = bch2_vfs_inode_get(c, inum); 63 ret = PTR_ERR_OR_ZERO(vinode); 64 if (ret) 65 goto err1; 66 67 dst = to_bch_ei(vinode); 68 69 ret = mnt_want_write_file(file); 70 if (ret) 71 goto err2; 72 73 bch2_lock_inodes(INODE_UPDATE_LOCK, src, dst); 74 75 if (inode_attr_changing(src, dst, Inode_opt_project)) { 76 ret = bch2_fs_quota_transfer(c, dst, 77 src->ei_qid, 78 1 << QTYP_PRJ, 79 KEY_TYPE_QUOTA_PREALLOC); 80 if (ret) 81 goto err3; 82 } 83 84 ret = bch2_write_inode(c, dst, bch2_reinherit_attrs_fn, src, 0); 85 err3: 86 bch2_unlock_inodes(INODE_UPDATE_LOCK, src, dst); 87 88 /* return true if we did work */ 89 if (ret >= 0) 90 ret = !ret; 91 92 mnt_drop_write_file(file); 93 err2: 94 iput(vinode); 95 err1: 96 kfree(kname); 97 98 return ret; 99 } 100 101 static int bch2_ioc_getversion(struct bch_inode_info *inode, u32 __user *arg) 102 { 103 return put_user(inode->v.i_generation, arg); 104 } 105 106 static int bch2_ioc_getlabel(struct bch_fs *c, char __user *user_label) 107 { 108 int ret; 109 size_t len; 110 char label[BCH_SB_LABEL_SIZE]; 111 112 BUILD_BUG_ON(BCH_SB_LABEL_SIZE >= FSLABEL_MAX); 113 114 mutex_lock(&c->sb_lock); 115 memcpy(label, c->disk_sb.sb->label, BCH_SB_LABEL_SIZE); 116 mutex_unlock(&c->sb_lock); 117 118 len = strnlen(label, BCH_SB_LABEL_SIZE); 119 if (len == BCH_SB_LABEL_SIZE) { 120 bch_warn(c, 121 "label is too long, return the first %zu bytes", 122 --len); 123 } 124 125 ret = copy_to_user(user_label, label, len); 126 127 return ret ? -EFAULT : 0; 128 } 129 130 static int bch2_ioc_setlabel(struct bch_fs *c, 131 struct file *file, 132 struct bch_inode_info *inode, 133 const char __user *user_label) 134 { 135 int ret; 136 char label[BCH_SB_LABEL_SIZE]; 137 138 if (!capable(CAP_SYS_ADMIN)) 139 return -EPERM; 140 141 if (copy_from_user(label, user_label, sizeof(label))) 142 return -EFAULT; 143 144 if (strnlen(label, BCH_SB_LABEL_SIZE) == BCH_SB_LABEL_SIZE) { 145 bch_err(c, 146 "unable to set label with more than %d bytes", 147 BCH_SB_LABEL_SIZE - 1); 148 return -EINVAL; 149 } 150 151 ret = mnt_want_write_file(file); 152 if (ret) 153 return ret; 154 155 mutex_lock(&c->sb_lock); 156 strscpy(c->disk_sb.sb->label, label, BCH_SB_LABEL_SIZE); 157 ret = bch2_write_super(c); 158 mutex_unlock(&c->sb_lock); 159 160 mnt_drop_write_file(file); 161 return ret; 162 } 163 164 static int bch2_ioc_goingdown(struct bch_fs *c, u32 __user *arg) 165 { 166 u32 flags; 167 int ret = 0; 168 169 if (!capable(CAP_SYS_ADMIN)) 170 return -EPERM; 171 172 if (get_user(flags, arg)) 173 return -EFAULT; 174 175 struct printbuf buf = PRINTBUF; 176 bch2_log_msg_start(c, &buf); 177 178 prt_printf(&buf, "shutdown by ioctl type %u", flags); 179 180 switch (flags) { 181 case FSOP_GOING_FLAGS_DEFAULT: 182 ret = bdev_freeze(c->vfs_sb->s_bdev); 183 if (ret) 184 break; 185 bch2_journal_flush(&c->journal); 186 bch2_fs_emergency_read_only2(c, &buf); 187 bdev_thaw(c->vfs_sb->s_bdev); 188 break; 189 case FSOP_GOING_FLAGS_LOGFLUSH: 190 bch2_journal_flush(&c->journal); 191 fallthrough; 192 case FSOP_GOING_FLAGS_NOLOGFLUSH: 193 bch2_fs_emergency_read_only2(c, &buf); 194 break; 195 default: 196 ret = -EINVAL; 197 goto noprint; 198 } 199 200 bch2_print_str(c, KERN_ERR, buf.buf); 201 noprint: 202 printbuf_exit(&buf); 203 return ret; 204 } 205 206 static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp, 207 struct bch_ioctl_subvolume arg) 208 { 209 struct inode *dir; 210 struct bch_inode_info *inode; 211 struct user_namespace *s_user_ns; 212 struct dentry *dst_dentry; 213 struct path src_path, dst_path; 214 int how = LOOKUP_FOLLOW; 215 int error; 216 subvol_inum snapshot_src = { 0 }; 217 unsigned lookup_flags = 0; 218 unsigned create_flags = BCH_CREATE_SUBVOL; 219 220 if (arg.flags & ~(BCH_SUBVOL_SNAPSHOT_CREATE| 221 BCH_SUBVOL_SNAPSHOT_RO)) 222 return -EINVAL; 223 224 if (!(arg.flags & BCH_SUBVOL_SNAPSHOT_CREATE) && 225 (arg.src_ptr || 226 (arg.flags & BCH_SUBVOL_SNAPSHOT_RO))) 227 return -EINVAL; 228 229 if (arg.flags & BCH_SUBVOL_SNAPSHOT_CREATE) 230 create_flags |= BCH_CREATE_SNAPSHOT; 231 232 if (arg.flags & BCH_SUBVOL_SNAPSHOT_RO) 233 create_flags |= BCH_CREATE_SNAPSHOT_RO; 234 235 if (arg.flags & BCH_SUBVOL_SNAPSHOT_CREATE) { 236 /* sync_inodes_sb enforce s_umount is locked */ 237 down_read(&c->vfs_sb->s_umount); 238 sync_inodes_sb(c->vfs_sb); 239 up_read(&c->vfs_sb->s_umount); 240 } 241 242 if (arg.src_ptr) { 243 error = user_path_at(arg.dirfd, 244 (const char __user *)(unsigned long)arg.src_ptr, 245 how, &src_path); 246 if (error) 247 goto err1; 248 249 if (src_path.dentry->d_sb->s_fs_info != c) { 250 path_put(&src_path); 251 error = -EXDEV; 252 goto err1; 253 } 254 255 snapshot_src = inode_inum(to_bch_ei(src_path.dentry->d_inode)); 256 } 257 258 dst_dentry = user_path_create(arg.dirfd, 259 (const char __user *)(unsigned long)arg.dst_ptr, 260 &dst_path, lookup_flags); 261 error = PTR_ERR_OR_ZERO(dst_dentry); 262 if (error) 263 goto err2; 264 265 if (dst_dentry->d_sb->s_fs_info != c) { 266 error = -EXDEV; 267 goto err3; 268 } 269 270 if (dst_dentry->d_inode) { 271 error = bch_err_throw(c, EEXIST_subvolume_create); 272 goto err3; 273 } 274 275 dir = dst_path.dentry->d_inode; 276 if (IS_DEADDIR(dir)) { 277 error = bch_err_throw(c, ENOENT_directory_dead); 278 goto err3; 279 } 280 281 s_user_ns = dir->i_sb->s_user_ns; 282 if (!kuid_has_mapping(s_user_ns, current_fsuid()) || 283 !kgid_has_mapping(s_user_ns, current_fsgid())) { 284 error = -EOVERFLOW; 285 goto err3; 286 } 287 288 error = inode_permission(file_mnt_idmap(filp), 289 dir, MAY_WRITE | MAY_EXEC); 290 if (error) 291 goto err3; 292 293 if (!IS_POSIXACL(dir)) 294 arg.mode &= ~current_umask(); 295 296 error = security_path_mkdir(&dst_path, dst_dentry, arg.mode); 297 if (error) 298 goto err3; 299 300 if ((arg.flags & BCH_SUBVOL_SNAPSHOT_CREATE) && 301 !arg.src_ptr) 302 snapshot_src.subvol = inode_inum(to_bch_ei(dir)).subvol; 303 304 down_write(&c->snapshot_create_lock); 305 inode = __bch2_create(file_mnt_idmap(filp), to_bch_ei(dir), 306 dst_dentry, arg.mode|S_IFDIR, 307 0, snapshot_src, create_flags); 308 up_write(&c->snapshot_create_lock); 309 310 error = PTR_ERR_OR_ZERO(inode); 311 if (error) 312 goto err3; 313 314 d_instantiate(dst_dentry, &inode->v); 315 fsnotify_mkdir(dir, dst_dentry); 316 err3: 317 done_path_create(&dst_path, dst_dentry); 318 err2: 319 if (arg.src_ptr) 320 path_put(&src_path); 321 err1: 322 return error; 323 } 324 325 static long bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp, 326 struct bch_ioctl_subvolume arg) 327 { 328 const char __user *name = (void __user *)(unsigned long)arg.dst_ptr; 329 struct path path; 330 struct inode *dir; 331 struct dentry *victim; 332 int ret = 0; 333 334 if (arg.flags) 335 return -EINVAL; 336 337 victim = user_path_locked_at(arg.dirfd, name, &path); 338 if (IS_ERR(victim)) 339 return PTR_ERR(victim); 340 341 dir = d_inode(path.dentry); 342 if (victim->d_sb->s_fs_info != c) { 343 ret = -EXDEV; 344 goto err; 345 } 346 347 ret = inode_permission(file_mnt_idmap(filp), d_inode(victim), MAY_WRITE) ?: 348 __bch2_unlink(dir, victim, true); 349 if (!ret) { 350 fsnotify_rmdir(dir, victim); 351 d_invalidate(victim); 352 } 353 err: 354 inode_unlock(dir); 355 dput(victim); 356 path_put(&path); 357 return ret; 358 } 359 360 long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg) 361 { 362 struct bch_inode_info *inode = file_bch_inode(file); 363 struct bch_fs *c = inode->v.i_sb->s_fs_info; 364 long ret; 365 366 switch (cmd) { 367 case BCHFS_IOC_REINHERIT_ATTRS: 368 ret = bch2_ioc_reinherit_attrs(c, file, inode, 369 (void __user *) arg); 370 break; 371 372 case FS_IOC_GETVERSION: 373 ret = bch2_ioc_getversion(inode, (u32 __user *) arg); 374 break; 375 376 case FS_IOC_SETVERSION: 377 ret = -ENOTTY; 378 break; 379 380 case FS_IOC_GETFSLABEL: 381 ret = bch2_ioc_getlabel(c, (void __user *) arg); 382 break; 383 384 case FS_IOC_SETFSLABEL: 385 ret = bch2_ioc_setlabel(c, file, inode, (const void __user *) arg); 386 break; 387 388 case FS_IOC_GOINGDOWN: 389 ret = bch2_ioc_goingdown(c, (u32 __user *) arg); 390 break; 391 392 case BCH_IOCTL_SUBVOLUME_CREATE: { 393 struct bch_ioctl_subvolume i; 394 395 ret = copy_from_user(&i, (void __user *) arg, sizeof(i)) 396 ? -EFAULT 397 : bch2_ioctl_subvolume_create(c, file, i); 398 break; 399 } 400 401 case BCH_IOCTL_SUBVOLUME_DESTROY: { 402 struct bch_ioctl_subvolume i; 403 404 ret = copy_from_user(&i, (void __user *) arg, sizeof(i)) 405 ? -EFAULT 406 : bch2_ioctl_subvolume_destroy(c, file, i); 407 break; 408 } 409 410 default: 411 ret = bch2_fs_ioctl(c, cmd, (void __user *) arg); 412 break; 413 } 414 415 return bch2_err_class(ret); 416 } 417 418 #ifdef CONFIG_COMPAT 419 long bch2_compat_fs_ioctl(struct file *file, unsigned cmd, unsigned long arg) 420 { 421 /* These are just misnamed, they actually get/put from/to user an int */ 422 switch (cmd) { 423 case FS_IOC32_GETFLAGS: 424 cmd = FS_IOC_GETFLAGS; 425 break; 426 case FS_IOC32_SETFLAGS: 427 cmd = FS_IOC_SETFLAGS; 428 break; 429 case FS_IOC32_GETVERSION: 430 cmd = FS_IOC_GETVERSION; 431 break; 432 case FS_IOC_GETFSLABEL: 433 case FS_IOC_SETFSLABEL: 434 break; 435 default: 436 return -ENOIOCTLCMD; 437 } 438 return bch2_fs_file_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); 439 } 440 #endif 441 442 #endif /* NO_BCACHEFS_FS */ 443