1 // SPDX-License-Identifier: GPL-2.0 2 3 #include "bcachefs.h" 4 #include "acl.h" 5 #include "btree_update.h" 6 #include "dirent.h" 7 #include "fs-common.h" 8 #include "inode.h" 9 #include "subvolume.h" 10 #include "xattr.h" 11 12 #include <linux/posix_acl.h> 13 14 static inline int is_subdir_for_nlink(struct bch_inode_unpacked *inode) 15 { 16 return S_ISDIR(inode->bi_mode) && !inode->bi_subvol; 17 } 18 19 int bch2_create_trans(struct btree_trans *trans, 20 subvol_inum dir, 21 struct bch_inode_unpacked *dir_u, 22 struct bch_inode_unpacked *new_inode, 23 const struct qstr *name, 24 uid_t uid, gid_t gid, umode_t mode, dev_t rdev, 25 struct posix_acl *default_acl, 26 struct posix_acl *acl, 27 subvol_inum snapshot_src, 28 unsigned flags) 29 { 30 struct bch_fs *c = trans->c; 31 struct btree_iter dir_iter = { NULL }; 32 struct btree_iter inode_iter = { NULL }; 33 subvol_inum new_inum = dir; 34 u64 now = bch2_current_time(c); 35 u64 cpu = raw_smp_processor_id(); 36 u64 dir_target; 37 u32 snapshot; 38 unsigned dir_type = mode_to_type(mode); 39 int ret; 40 41 ret = bch2_subvolume_get_snapshot(trans, dir.subvol, &snapshot); 42 if (ret) 43 goto err; 44 45 ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_intent); 46 if (ret) 47 goto err; 48 49 if (!(flags & BCH_CREATE_SNAPSHOT)) { 50 /* Normal create path - allocate a new inode: */ 51 bch2_inode_init_late(new_inode, now, uid, gid, mode, rdev, dir_u); 52 53 if (flags & BCH_CREATE_TMPFILE) 54 new_inode->bi_flags |= BCH_INODE_unlinked; 55 56 ret = bch2_inode_create(trans, &inode_iter, new_inode, snapshot, cpu); 57 if (ret) 58 goto err; 59 60 snapshot_src = (subvol_inum) { 0 }; 61 } else { 62 /* 63 * Creating a snapshot - we're not allocating a new inode, but 64 * we do have to lookup the root inode of the subvolume we're 65 * snapshotting and update it (in the new snapshot): 66 */ 67 68 if (!snapshot_src.inum) { 69 /* Inode wasn't specified, just snapshot: */ 70 struct bch_subvolume s; 71 72 ret = bch2_subvolume_get(trans, snapshot_src.subvol, true, 73 BTREE_ITER_cached, &s); 74 if (ret) 75 goto err; 76 77 snapshot_src.inum = le64_to_cpu(s.inode); 78 } 79 80 ret = bch2_inode_peek(trans, &inode_iter, new_inode, snapshot_src, 81 BTREE_ITER_intent); 82 if (ret) 83 goto err; 84 85 if (new_inode->bi_subvol != snapshot_src.subvol) { 86 /* Not a subvolume root: */ 87 ret = -EINVAL; 88 goto err; 89 } 90 91 /* 92 * If we're not root, we have to own the subvolume being 93 * snapshotted: 94 */ 95 if (uid && new_inode->bi_uid != uid) { 96 ret = -EPERM; 97 goto err; 98 } 99 100 flags |= BCH_CREATE_SUBVOL; 101 } 102 103 new_inum.inum = new_inode->bi_inum; 104 dir_target = new_inode->bi_inum; 105 106 if (flags & BCH_CREATE_SUBVOL) { 107 u32 new_subvol, dir_snapshot; 108 109 ret = bch2_subvolume_create(trans, new_inode->bi_inum, 110 dir.subvol, 111 snapshot_src.subvol, 112 &new_subvol, &snapshot, 113 (flags & BCH_CREATE_SNAPSHOT_RO) != 0); 114 if (ret) 115 goto err; 116 117 new_inode->bi_parent_subvol = dir.subvol; 118 new_inode->bi_subvol = new_subvol; 119 new_inum.subvol = new_subvol; 120 dir_target = new_subvol; 121 dir_type = DT_SUBVOL; 122 123 ret = bch2_subvolume_get_snapshot(trans, dir.subvol, &dir_snapshot); 124 if (ret) 125 goto err; 126 127 bch2_btree_iter_set_snapshot(&dir_iter, dir_snapshot); 128 ret = bch2_btree_iter_traverse(&dir_iter); 129 if (ret) 130 goto err; 131 } 132 133 if (!(flags & BCH_CREATE_SNAPSHOT)) { 134 if (default_acl) { 135 ret = bch2_set_acl_trans(trans, new_inum, new_inode, 136 default_acl, ACL_TYPE_DEFAULT); 137 if (ret) 138 goto err; 139 } 140 141 if (acl) { 142 ret = bch2_set_acl_trans(trans, new_inum, new_inode, 143 acl, ACL_TYPE_ACCESS); 144 if (ret) 145 goto err; 146 } 147 } 148 149 if (!(flags & BCH_CREATE_TMPFILE)) { 150 struct bch_hash_info dir_hash = bch2_hash_info_init(c, dir_u); 151 u64 dir_offset; 152 153 if (is_subdir_for_nlink(new_inode)) 154 dir_u->bi_nlink++; 155 dir_u->bi_mtime = dir_u->bi_ctime = now; 156 157 ret = bch2_inode_write(trans, &dir_iter, dir_u); 158 if (ret) 159 goto err; 160 161 ret = bch2_dirent_create(trans, dir, &dir_hash, 162 dir_type, 163 name, 164 dir_target, 165 &dir_offset, 166 STR_HASH_must_create); 167 if (ret) 168 goto err; 169 170 new_inode->bi_dir = dir_u->bi_inum; 171 new_inode->bi_dir_offset = dir_offset; 172 } 173 174 inode_iter.flags &= ~BTREE_ITER_all_snapshots; 175 bch2_btree_iter_set_snapshot(&inode_iter, snapshot); 176 177 ret = bch2_btree_iter_traverse(&inode_iter) ?: 178 bch2_inode_write(trans, &inode_iter, new_inode); 179 err: 180 bch2_trans_iter_exit(trans, &inode_iter); 181 bch2_trans_iter_exit(trans, &dir_iter); 182 return ret; 183 } 184 185 int bch2_link_trans(struct btree_trans *trans, 186 subvol_inum dir, struct bch_inode_unpacked *dir_u, 187 subvol_inum inum, struct bch_inode_unpacked *inode_u, 188 const struct qstr *name) 189 { 190 struct bch_fs *c = trans->c; 191 struct btree_iter dir_iter = { NULL }; 192 struct btree_iter inode_iter = { NULL }; 193 struct bch_hash_info dir_hash; 194 u64 now = bch2_current_time(c); 195 u64 dir_offset = 0; 196 int ret; 197 198 if (dir.subvol != inum.subvol) 199 return -EXDEV; 200 201 ret = bch2_inode_peek(trans, &inode_iter, inode_u, inum, BTREE_ITER_intent); 202 if (ret) 203 return ret; 204 205 inode_u->bi_ctime = now; 206 ret = bch2_inode_nlink_inc(inode_u); 207 if (ret) 208 goto err; 209 210 ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_intent); 211 if (ret) 212 goto err; 213 214 if (bch2_reinherit_attrs(inode_u, dir_u)) { 215 ret = -EXDEV; 216 goto err; 217 } 218 219 dir_u->bi_mtime = dir_u->bi_ctime = now; 220 221 dir_hash = bch2_hash_info_init(c, dir_u); 222 223 ret = bch2_dirent_create(trans, dir, &dir_hash, 224 mode_to_type(inode_u->bi_mode), 225 name, inum.inum, &dir_offset, 226 STR_HASH_must_create); 227 if (ret) 228 goto err; 229 230 inode_u->bi_dir = dir.inum; 231 inode_u->bi_dir_offset = dir_offset; 232 233 ret = bch2_inode_write(trans, &dir_iter, dir_u) ?: 234 bch2_inode_write(trans, &inode_iter, inode_u); 235 err: 236 bch2_trans_iter_exit(trans, &dir_iter); 237 bch2_trans_iter_exit(trans, &inode_iter); 238 return ret; 239 } 240 241 int bch2_unlink_trans(struct btree_trans *trans, 242 subvol_inum dir, 243 struct bch_inode_unpacked *dir_u, 244 struct bch_inode_unpacked *inode_u, 245 const struct qstr *name, 246 bool deleting_subvol) 247 { 248 struct bch_fs *c = trans->c; 249 struct btree_iter dir_iter = { NULL }; 250 struct btree_iter dirent_iter = { NULL }; 251 struct btree_iter inode_iter = { NULL }; 252 struct bch_hash_info dir_hash; 253 subvol_inum inum; 254 u64 now = bch2_current_time(c); 255 struct bkey_s_c k; 256 int ret; 257 258 ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_intent); 259 if (ret) 260 goto err; 261 262 dir_hash = bch2_hash_info_init(c, dir_u); 263 264 ret = bch2_dirent_lookup_trans(trans, &dirent_iter, dir, &dir_hash, 265 name, &inum, BTREE_ITER_intent); 266 if (ret) 267 goto err; 268 269 ret = bch2_inode_peek(trans, &inode_iter, inode_u, inum, 270 BTREE_ITER_intent); 271 if (ret) 272 goto err; 273 274 if (!deleting_subvol && S_ISDIR(inode_u->bi_mode)) { 275 ret = bch2_empty_dir_trans(trans, inum); 276 if (ret) 277 goto err; 278 } 279 280 if (deleting_subvol && !inode_u->bi_subvol) { 281 ret = -BCH_ERR_ENOENT_not_subvol; 282 goto err; 283 } 284 285 if (inode_u->bi_subvol) { 286 /* Recursive subvolume destroy not allowed (yet?) */ 287 ret = bch2_subvol_has_children(trans, inode_u->bi_subvol); 288 if (ret) 289 goto err; 290 } 291 292 if (deleting_subvol || inode_u->bi_subvol) { 293 ret = bch2_subvolume_unlink(trans, inode_u->bi_subvol); 294 if (ret) 295 goto err; 296 297 k = bch2_btree_iter_peek_slot(&dirent_iter); 298 ret = bkey_err(k); 299 if (ret) 300 goto err; 301 302 /* 303 * If we're deleting a subvolume, we need to really delete the 304 * dirent, not just emit a whiteout in the current snapshot: 305 */ 306 bch2_btree_iter_set_snapshot(&dirent_iter, k.k->p.snapshot); 307 ret = bch2_btree_iter_traverse(&dirent_iter); 308 if (ret) 309 goto err; 310 } else { 311 bch2_inode_nlink_dec(trans, inode_u); 312 } 313 314 if (inode_u->bi_dir == dirent_iter.pos.inode && 315 inode_u->bi_dir_offset == dirent_iter.pos.offset) { 316 inode_u->bi_dir = 0; 317 inode_u->bi_dir_offset = 0; 318 } 319 320 dir_u->bi_mtime = dir_u->bi_ctime = inode_u->bi_ctime = now; 321 dir_u->bi_nlink -= is_subdir_for_nlink(inode_u); 322 323 ret = bch2_hash_delete_at(trans, bch2_dirent_hash_desc, 324 &dir_hash, &dirent_iter, 325 BTREE_UPDATE_internal_snapshot_node) ?: 326 bch2_inode_write(trans, &dir_iter, dir_u) ?: 327 bch2_inode_write(trans, &inode_iter, inode_u); 328 err: 329 bch2_trans_iter_exit(trans, &inode_iter); 330 bch2_trans_iter_exit(trans, &dirent_iter); 331 bch2_trans_iter_exit(trans, &dir_iter); 332 return ret; 333 } 334 335 bool bch2_reinherit_attrs(struct bch_inode_unpacked *dst_u, 336 struct bch_inode_unpacked *src_u) 337 { 338 u64 src, dst; 339 unsigned id; 340 bool ret = false; 341 342 for (id = 0; id < Inode_opt_nr; id++) { 343 /* Skip attributes that were explicitly set on this inode */ 344 if (dst_u->bi_fields_set & (1 << id)) 345 continue; 346 347 src = bch2_inode_opt_get(src_u, id); 348 dst = bch2_inode_opt_get(dst_u, id); 349 350 if (src == dst) 351 continue; 352 353 bch2_inode_opt_set(dst_u, id, src); 354 ret = true; 355 } 356 357 return ret; 358 } 359 360 static int subvol_update_parent(struct btree_trans *trans, u32 subvol, u32 new_parent) 361 { 362 struct btree_iter iter; 363 struct bkey_i_subvolume *s = 364 bch2_bkey_get_mut_typed(trans, &iter, 365 BTREE_ID_subvolumes, POS(0, subvol), 366 BTREE_ITER_cached, subvolume); 367 int ret = PTR_ERR_OR_ZERO(s); 368 if (ret) 369 return ret; 370 371 s->v.fs_path_parent = cpu_to_le32(new_parent); 372 bch2_trans_iter_exit(trans, &iter); 373 return 0; 374 } 375 376 int bch2_rename_trans(struct btree_trans *trans, 377 subvol_inum src_dir, struct bch_inode_unpacked *src_dir_u, 378 subvol_inum dst_dir, struct bch_inode_unpacked *dst_dir_u, 379 struct bch_inode_unpacked *src_inode_u, 380 struct bch_inode_unpacked *dst_inode_u, 381 const struct qstr *src_name, 382 const struct qstr *dst_name, 383 enum bch_rename_mode mode) 384 { 385 struct bch_fs *c = trans->c; 386 struct btree_iter src_dir_iter = { NULL }; 387 struct btree_iter dst_dir_iter = { NULL }; 388 struct btree_iter src_inode_iter = { NULL }; 389 struct btree_iter dst_inode_iter = { NULL }; 390 struct bch_hash_info src_hash, dst_hash; 391 subvol_inum src_inum, dst_inum; 392 u64 src_offset, dst_offset; 393 u64 now = bch2_current_time(c); 394 int ret; 395 396 ret = bch2_inode_peek(trans, &src_dir_iter, src_dir_u, src_dir, 397 BTREE_ITER_intent); 398 if (ret) 399 goto err; 400 401 src_hash = bch2_hash_info_init(c, src_dir_u); 402 403 if (dst_dir.inum != src_dir.inum || 404 dst_dir.subvol != src_dir.subvol) { 405 ret = bch2_inode_peek(trans, &dst_dir_iter, dst_dir_u, dst_dir, 406 BTREE_ITER_intent); 407 if (ret) 408 goto err; 409 410 dst_hash = bch2_hash_info_init(c, dst_dir_u); 411 } else { 412 dst_dir_u = src_dir_u; 413 dst_hash = src_hash; 414 } 415 416 ret = bch2_dirent_rename(trans, 417 src_dir, &src_hash, 418 dst_dir, &dst_hash, 419 src_name, &src_inum, &src_offset, 420 dst_name, &dst_inum, &dst_offset, 421 mode); 422 if (ret) 423 goto err; 424 425 ret = bch2_inode_peek(trans, &src_inode_iter, src_inode_u, src_inum, 426 BTREE_ITER_intent); 427 if (ret) 428 goto err; 429 430 if (dst_inum.inum) { 431 ret = bch2_inode_peek(trans, &dst_inode_iter, dst_inode_u, dst_inum, 432 BTREE_ITER_intent); 433 if (ret) 434 goto err; 435 } 436 437 if (src_inode_u->bi_subvol && 438 dst_dir.subvol != src_inode_u->bi_parent_subvol) { 439 ret = subvol_update_parent(trans, src_inode_u->bi_subvol, dst_dir.subvol); 440 if (ret) 441 goto err; 442 } 443 444 if (mode == BCH_RENAME_EXCHANGE && 445 dst_inode_u->bi_subvol && 446 src_dir.subvol != dst_inode_u->bi_parent_subvol) { 447 ret = subvol_update_parent(trans, dst_inode_u->bi_subvol, src_dir.subvol); 448 if (ret) 449 goto err; 450 } 451 452 /* Can't move across subvolumes, unless it's a subvolume root: */ 453 if (src_dir.subvol != dst_dir.subvol && 454 (!src_inode_u->bi_subvol || 455 (dst_inum.inum && !dst_inode_u->bi_subvol))) { 456 ret = -EXDEV; 457 goto err; 458 } 459 460 if (src_inode_u->bi_parent_subvol) 461 src_inode_u->bi_parent_subvol = dst_dir.subvol; 462 463 if ((mode == BCH_RENAME_EXCHANGE) && 464 dst_inode_u->bi_parent_subvol) 465 dst_inode_u->bi_parent_subvol = src_dir.subvol; 466 467 src_inode_u->bi_dir = dst_dir_u->bi_inum; 468 src_inode_u->bi_dir_offset = dst_offset; 469 470 if (mode == BCH_RENAME_EXCHANGE) { 471 dst_inode_u->bi_dir = src_dir_u->bi_inum; 472 dst_inode_u->bi_dir_offset = src_offset; 473 } 474 475 if (mode == BCH_RENAME_OVERWRITE && 476 dst_inode_u->bi_dir == dst_dir_u->bi_inum && 477 dst_inode_u->bi_dir_offset == src_offset) { 478 dst_inode_u->bi_dir = 0; 479 dst_inode_u->bi_dir_offset = 0; 480 } 481 482 if (mode == BCH_RENAME_OVERWRITE) { 483 if (S_ISDIR(src_inode_u->bi_mode) != 484 S_ISDIR(dst_inode_u->bi_mode)) { 485 ret = -ENOTDIR; 486 goto err; 487 } 488 489 if (S_ISDIR(dst_inode_u->bi_mode)) { 490 ret = bch2_empty_dir_trans(trans, dst_inum); 491 if (ret) 492 goto err; 493 } 494 } 495 496 if (bch2_reinherit_attrs(src_inode_u, dst_dir_u) && 497 S_ISDIR(src_inode_u->bi_mode)) { 498 ret = -EXDEV; 499 goto err; 500 } 501 502 if (mode == BCH_RENAME_EXCHANGE && 503 bch2_reinherit_attrs(dst_inode_u, src_dir_u) && 504 S_ISDIR(dst_inode_u->bi_mode)) { 505 ret = -EXDEV; 506 goto err; 507 } 508 509 if (is_subdir_for_nlink(src_inode_u)) { 510 src_dir_u->bi_nlink--; 511 dst_dir_u->bi_nlink++; 512 } 513 514 if (dst_inum.inum && is_subdir_for_nlink(dst_inode_u)) { 515 dst_dir_u->bi_nlink--; 516 src_dir_u->bi_nlink += mode == BCH_RENAME_EXCHANGE; 517 } 518 519 if (mode == BCH_RENAME_OVERWRITE) 520 bch2_inode_nlink_dec(trans, dst_inode_u); 521 522 src_dir_u->bi_mtime = now; 523 src_dir_u->bi_ctime = now; 524 525 if (src_dir.inum != dst_dir.inum) { 526 dst_dir_u->bi_mtime = now; 527 dst_dir_u->bi_ctime = now; 528 } 529 530 src_inode_u->bi_ctime = now; 531 532 if (dst_inum.inum) 533 dst_inode_u->bi_ctime = now; 534 535 ret = bch2_inode_write(trans, &src_dir_iter, src_dir_u) ?: 536 (src_dir.inum != dst_dir.inum 537 ? bch2_inode_write(trans, &dst_dir_iter, dst_dir_u) 538 : 0) ?: 539 bch2_inode_write(trans, &src_inode_iter, src_inode_u) ?: 540 (dst_inum.inum 541 ? bch2_inode_write(trans, &dst_inode_iter, dst_inode_u) 542 : 0); 543 err: 544 bch2_trans_iter_exit(trans, &dst_inode_iter); 545 bch2_trans_iter_exit(trans, &src_inode_iter); 546 bch2_trans_iter_exit(trans, &dst_dir_iter); 547 bch2_trans_iter_exit(trans, &src_dir_iter); 548 return ret; 549 } 550
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.