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 btree_iter subvol_iter; 71 struct bkey_s_c k; 72 73 bch2_trans_iter_init(trans, &subvol_iter, BTREE_ID_subvolumes, 74 POS(0, snapshot_src.subvol), 0); 75 k = bch2_btree_iter_peek_slot(&subvol_iter); 76 77 ret = bkey_err(k); 78 if (!ret && k.k->type != KEY_TYPE_subvolume) { 79 bch_err(c, "subvolume %u not found", 80 snapshot_src.subvol); 81 ret = -ENOENT; 82 } 83 84 if (!ret) 85 snapshot_src.inum = le64_to_cpu(bkey_s_c_to_subvolume(k).v->inode); 86 bch2_trans_iter_exit(trans, &subvol_iter); 87 88 if (ret) 89 goto err; 90 } 91 92 ret = bch2_inode_peek(trans, &inode_iter, new_inode, snapshot_src, 93 BTREE_ITER_INTENT); 94 if (ret) 95 goto err; 96 97 if (new_inode->bi_subvol != snapshot_src.subvol) { 98 /* Not a subvolume root: */ 99 ret = -EINVAL; 100 goto err; 101 } 102 103 /* 104 * If we're not root, we have to own the subvolume being 105 * snapshotted: 106 */ 107 if (uid && new_inode->bi_uid != uid) { 108 ret = -EPERM; 109 goto err; 110 } 111 112 flags |= BCH_CREATE_SUBVOL; 113 } 114 115 new_inum.inum = new_inode->bi_inum; 116 dir_target = new_inode->bi_inum; 117 118 if (flags & BCH_CREATE_SUBVOL) { 119 u32 new_subvol, dir_snapshot; 120 121 ret = bch2_subvolume_create(trans, new_inode->bi_inum, 122 snapshot_src.subvol, 123 &new_subvol, &snapshot, 124 (flags & BCH_CREATE_SNAPSHOT_RO) != 0); 125 if (ret) 126 goto err; 127 128 new_inode->bi_parent_subvol = dir.subvol; 129 new_inode->bi_subvol = new_subvol; 130 new_inum.subvol = new_subvol; 131 dir_target = new_subvol; 132 dir_type = DT_SUBVOL; 133 134 ret = bch2_subvolume_get_snapshot(trans, dir.subvol, &dir_snapshot); 135 if (ret) 136 goto err; 137 138 bch2_btree_iter_set_snapshot(&dir_iter, dir_snapshot); 139 ret = bch2_btree_iter_traverse(&dir_iter); 140 if (ret) 141 goto err; 142 } 143 144 if (!(flags & BCH_CREATE_SNAPSHOT)) { 145 if (default_acl) { 146 ret = bch2_set_acl_trans(trans, new_inum, new_inode, 147 default_acl, ACL_TYPE_DEFAULT); 148 if (ret) 149 goto err; 150 } 151 152 if (acl) { 153 ret = bch2_set_acl_trans(trans, new_inum, new_inode, 154 acl, ACL_TYPE_ACCESS); 155 if (ret) 156 goto err; 157 } 158 } 159 160 if (!(flags & BCH_CREATE_TMPFILE)) { 161 struct bch_hash_info dir_hash = bch2_hash_info_init(c, dir_u); 162 u64 dir_offset; 163 164 if (is_subdir_for_nlink(new_inode)) 165 dir_u->bi_nlink++; 166 dir_u->bi_mtime = dir_u->bi_ctime = now; 167 168 ret = bch2_inode_write(trans, &dir_iter, dir_u); 169 if (ret) 170 goto err; 171 172 ret = bch2_dirent_create(trans, dir, &dir_hash, 173 dir_type, 174 name, 175 dir_target, 176 &dir_offset, 177 BCH_HASH_SET_MUST_CREATE); 178 if (ret) 179 goto err; 180 181 if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) { 182 new_inode->bi_dir = dir_u->bi_inum; 183 new_inode->bi_dir_offset = dir_offset; 184 } 185 } 186 187 inode_iter.flags &= ~BTREE_ITER_ALL_SNAPSHOTS; 188 bch2_btree_iter_set_snapshot(&inode_iter, snapshot); 189 190 ret = bch2_btree_iter_traverse(&inode_iter) ?: 191 bch2_inode_write(trans, &inode_iter, new_inode); 192 err: 193 bch2_trans_iter_exit(trans, &inode_iter); 194 bch2_trans_iter_exit(trans, &dir_iter); 195 return ret; 196 } 197 198 int bch2_link_trans(struct btree_trans *trans, 199 subvol_inum dir, struct bch_inode_unpacked *dir_u, 200 subvol_inum inum, struct bch_inode_unpacked *inode_u, 201 const struct qstr *name) 202 { 203 struct bch_fs *c = trans->c; 204 struct btree_iter dir_iter = { NULL }; 205 struct btree_iter inode_iter = { NULL }; 206 struct bch_hash_info dir_hash; 207 u64 now = bch2_current_time(c); 208 u64 dir_offset = 0; 209 int ret; 210 211 if (dir.subvol != inum.subvol) 212 return -EXDEV; 213 214 ret = bch2_inode_peek(trans, &inode_iter, inode_u, inum, BTREE_ITER_INTENT); 215 if (ret) 216 goto err; 217 218 inode_u->bi_ctime = now; 219 bch2_inode_nlink_inc(inode_u); 220 221 ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_INTENT); 222 if (ret) 223 goto err; 224 225 dir_u->bi_mtime = dir_u->bi_ctime = now; 226 227 dir_hash = bch2_hash_info_init(c, dir_u); 228 229 ret = bch2_dirent_create(trans, dir, &dir_hash, 230 mode_to_type(inode_u->bi_mode), 231 name, inum.inum, &dir_offset, 232 BCH_HASH_SET_MUST_CREATE); 233 if (ret) 234 goto err; 235 236 if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) { 237 inode_u->bi_dir = dir.inum; 238 inode_u->bi_dir_offset = dir_offset; 239 } 240 241 ret = bch2_inode_write(trans, &dir_iter, dir_u) ?: 242 bch2_inode_write(trans, &inode_iter, inode_u); 243 err: 244 bch2_trans_iter_exit(trans, &dir_iter); 245 bch2_trans_iter_exit(trans, &inode_iter); 246 return ret; 247 } 248 249 int bch2_unlink_trans(struct btree_trans *trans, 250 subvol_inum dir, 251 struct bch_inode_unpacked *dir_u, 252 struct bch_inode_unpacked *inode_u, 253 const struct qstr *name, 254 int deleting_snapshot) 255 { 256 struct bch_fs *c = trans->c; 257 struct btree_iter dir_iter = { NULL }; 258 struct btree_iter dirent_iter = { NULL }; 259 struct btree_iter inode_iter = { NULL }; 260 struct bch_hash_info dir_hash; 261 subvol_inum inum; 262 u64 now = bch2_current_time(c); 263 struct bkey_s_c k; 264 int ret; 265 266 ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_INTENT); 267 if (ret) 268 goto err; 269 270 dir_hash = bch2_hash_info_init(c, dir_u); 271 272 ret = __bch2_dirent_lookup_trans(trans, &dirent_iter, dir, &dir_hash, 273 name, &inum, BTREE_ITER_INTENT); 274 if (ret) 275 goto err; 276 277 ret = bch2_inode_peek(trans, &inode_iter, inode_u, inum, 278 BTREE_ITER_INTENT); 279 if (ret) 280 goto err; 281 282 if (deleting_snapshot == 1 && !inode_u->bi_subvol) { 283 ret = -ENOENT; 284 goto err; 285 } 286 287 if (deleting_snapshot <= 0 && S_ISDIR(inode_u->bi_mode)) { 288 ret = bch2_empty_dir_trans(trans, inum); 289 if (ret) 290 goto err; 291 } 292 293 if (inode_u->bi_subvol) { 294 ret = bch2_subvolume_delete(trans, inode_u->bi_subvol, 295 deleting_snapshot); 296 if (ret) 297 goto err; 298 299 k = bch2_btree_iter_peek_slot(&dirent_iter); 300 ret = bkey_err(k); 301 if (ret) 302 goto err; 303 304 /* 305 * If we're deleting a subvolume, we need to really delete the 306 * dirent, not just emit a whiteout in the current snapshot: 307 */ 308 bch2_btree_iter_set_snapshot(&dirent_iter, k.k->p.snapshot); 309 ret = bch2_btree_iter_traverse(&dirent_iter); 310 if (ret) 311 goto err; 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 bch2_inode_nlink_dec(inode_u); 323 324 ret = bch2_hash_delete_at(trans, bch2_dirent_hash_desc, 325 &dir_hash, &dirent_iter, 326 BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE) ?: 327 bch2_inode_write(trans, &dir_iter, dir_u) ?: 328 bch2_inode_write(trans, &inode_iter, inode_u); 329 err: 330 bch2_trans_iter_exit(trans, &inode_iter); 331 bch2_trans_iter_exit(trans, &dirent_iter); 332 bch2_trans_iter_exit(trans, &dir_iter); 333 return ret; 334 } 335 336 bool bch2_reinherit_attrs(struct bch_inode_unpacked *dst_u, 337 struct bch_inode_unpacked *src_u) 338 { 339 u64 src, dst; 340 unsigned id; 341 bool ret = false; 342 343 for (id = 0; id < Inode_opt_nr; id++) { 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 int bch2_rename_trans(struct btree_trans *trans, 361 subvol_inum src_dir, struct bch_inode_unpacked *src_dir_u, 362 subvol_inum dst_dir, struct bch_inode_unpacked *dst_dir_u, 363 struct bch_inode_unpacked *src_inode_u, 364 struct bch_inode_unpacked *dst_inode_u, 365 const struct qstr *src_name, 366 const struct qstr *dst_name, 367 enum bch_rename_mode mode) 368 { 369 struct bch_fs *c = trans->c; 370 struct btree_iter src_dir_iter = { NULL }; 371 struct btree_iter dst_dir_iter = { NULL }; 372 struct btree_iter src_inode_iter = { NULL }; 373 struct btree_iter dst_inode_iter = { NULL }; 374 struct bch_hash_info src_hash, dst_hash; 375 subvol_inum src_inum, dst_inum; 376 u64 src_offset, dst_offset; 377 u64 now = bch2_current_time(c); 378 int ret; 379 380 ret = bch2_inode_peek(trans, &src_dir_iter, src_dir_u, src_dir, 381 BTREE_ITER_INTENT); 382 if (ret) 383 goto err; 384 385 src_hash = bch2_hash_info_init(c, src_dir_u); 386 387 if (dst_dir.inum != src_dir.inum || 388 dst_dir.subvol != src_dir.subvol) { 389 ret = bch2_inode_peek(trans, &dst_dir_iter, dst_dir_u, dst_dir, 390 BTREE_ITER_INTENT); 391 if (ret) 392 goto err; 393 394 dst_hash = bch2_hash_info_init(c, dst_dir_u); 395 } else { 396 dst_dir_u = src_dir_u; 397 dst_hash = src_hash; 398 } 399 400 ret = bch2_dirent_rename(trans, 401 src_dir, &src_hash, 402 dst_dir, &dst_hash, 403 src_name, &src_inum, &src_offset, 404 dst_name, &dst_inum, &dst_offset, 405 mode); 406 if (ret) 407 goto err; 408 409 ret = bch2_inode_peek(trans, &src_inode_iter, src_inode_u, src_inum, 410 BTREE_ITER_INTENT); 411 if (ret) 412 goto err; 413 414 if (dst_inum.inum) { 415 ret = bch2_inode_peek(trans, &dst_inode_iter, dst_inode_u, dst_inum, 416 BTREE_ITER_INTENT); 417 if (ret) 418 goto err; 419 } 420 421 if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) { 422 src_inode_u->bi_dir = dst_dir_u->bi_inum; 423 src_inode_u->bi_dir_offset = dst_offset; 424 425 if (mode == BCH_RENAME_EXCHANGE) { 426 dst_inode_u->bi_dir = src_dir_u->bi_inum; 427 dst_inode_u->bi_dir_offset = src_offset; 428 } 429 430 if (mode == BCH_RENAME_OVERWRITE && 431 dst_inode_u->bi_dir == dst_dir_u->bi_inum && 432 dst_inode_u->bi_dir_offset == src_offset) { 433 dst_inode_u->bi_dir = 0; 434 dst_inode_u->bi_dir_offset = 0; 435 } 436 } 437 438 if (mode == BCH_RENAME_OVERWRITE) { 439 if (S_ISDIR(src_inode_u->bi_mode) != 440 S_ISDIR(dst_inode_u->bi_mode)) { 441 ret = -ENOTDIR; 442 goto err; 443 } 444 445 if (S_ISDIR(dst_inode_u->bi_mode) && 446 bch2_empty_dir_trans(trans, dst_inum)) { 447 ret = -ENOTEMPTY; 448 goto err; 449 } 450 } 451 452 if (bch2_reinherit_attrs(src_inode_u, dst_dir_u) && 453 S_ISDIR(src_inode_u->bi_mode)) { 454 ret = -EXDEV; 455 goto err; 456 } 457 458 if (mode == BCH_RENAME_EXCHANGE && 459 bch2_reinherit_attrs(dst_inode_u, src_dir_u) && 460 S_ISDIR(dst_inode_u->bi_mode)) { 461 ret = -EXDEV; 462 goto err; 463 } 464 465 if (is_subdir_for_nlink(src_inode_u)) { 466 src_dir_u->bi_nlink--; 467 dst_dir_u->bi_nlink++; 468 } 469 470 if (dst_inum.inum && is_subdir_for_nlink(dst_inode_u)) { 471 dst_dir_u->bi_nlink--; 472 src_dir_u->bi_nlink += mode == BCH_RENAME_EXCHANGE; 473 } 474 475 if (mode == BCH_RENAME_OVERWRITE) 476 bch2_inode_nlink_dec(dst_inode_u); 477 478 src_dir_u->bi_mtime = now; 479 src_dir_u->bi_ctime = now; 480 481 if (src_dir.inum != dst_dir.inum) { 482 dst_dir_u->bi_mtime = now; 483 dst_dir_u->bi_ctime = now; 484 } 485 486 src_inode_u->bi_ctime = now; 487 488 if (dst_inum.inum) 489 dst_inode_u->bi_ctime = now; 490 491 ret = bch2_inode_write(trans, &src_dir_iter, src_dir_u) ?: 492 (src_dir.inum != dst_dir.inum 493 ? bch2_inode_write(trans, &dst_dir_iter, dst_dir_u) 494 : 0 ) ?: 495 bch2_inode_write(trans, &src_inode_iter, src_inode_u) ?: 496 (dst_inum.inum 497 ? bch2_inode_write(trans, &dst_inode_iter, dst_inode_u) 498 : 0 ); 499 err: 500 bch2_trans_iter_exit(trans, &dst_inode_iter); 501 bch2_trans_iter_exit(trans, &src_inode_iter); 502 bch2_trans_iter_exit(trans, &dst_dir_iter); 503 bch2_trans_iter_exit(trans, &src_dir_iter); 504 return ret; 505 } 506