1 // SPDX-License-Identifier: GPL-2.0
5 #include "btree_update.h"
12 #include <linux/posix_acl.h>
14 static inline int is_subdir_for_nlink(struct bch_inode_unpacked
*inode
)
16 return S_ISDIR(inode
->bi_mode
) && !inode
->bi_subvol
;
19 int bch2_create_trans(struct btree_trans
*trans
,
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
,
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();
38 unsigned dir_type
= mode_to_type(mode
);
41 ret
= bch2_subvolume_get_snapshot(trans
, dir
.subvol
, &snapshot
);
45 ret
= bch2_inode_peek(trans
, &dir_iter
, dir_u
, dir
,
46 BTREE_ITER_intent
|BTREE_ITER_with_updates
);
50 if (!(flags
& BCH_CREATE_SNAPSHOT
)) {
51 /* Normal create path - allocate a new inode: */
52 bch2_inode_init_late(new_inode
, now
, uid
, gid
, mode
, rdev
, dir_u
);
54 if (flags
& BCH_CREATE_TMPFILE
)
55 new_inode
->bi_flags
|= BCH_INODE_unlinked
;
57 ret
= bch2_inode_create(trans
, &inode_iter
, new_inode
, snapshot
, cpu
);
61 snapshot_src
= (subvol_inum
) { 0 };
64 * Creating a snapshot - we're not allocating a new inode, but
65 * we do have to lookup the root inode of the subvolume we're
66 * snapshotting and update it (in the new snapshot):
69 if (!snapshot_src
.inum
) {
70 /* Inode wasn't specified, just snapshot: */
71 struct bch_subvolume s
;
73 ret
= bch2_subvolume_get(trans
, snapshot_src
.subvol
, true,
74 BTREE_ITER_cached
, &s
);
78 snapshot_src
.inum
= le64_to_cpu(s
.inode
);
81 ret
= bch2_inode_peek(trans
, &inode_iter
, new_inode
, snapshot_src
,
86 if (new_inode
->bi_subvol
!= snapshot_src
.subvol
) {
87 /* Not a subvolume root: */
93 * If we're not root, we have to own the subvolume being
96 if (uid
&& new_inode
->bi_uid
!= uid
) {
101 flags
|= BCH_CREATE_SUBVOL
;
104 new_inum
.inum
= new_inode
->bi_inum
;
105 dir_target
= new_inode
->bi_inum
;
107 if (flags
& BCH_CREATE_SUBVOL
) {
108 u32 new_subvol
, dir_snapshot
;
110 ret
= bch2_subvolume_create(trans
, new_inode
->bi_inum
,
113 &new_subvol
, &snapshot
,
114 (flags
& BCH_CREATE_SNAPSHOT_RO
) != 0);
118 new_inode
->bi_parent_subvol
= dir
.subvol
;
119 new_inode
->bi_subvol
= new_subvol
;
120 new_inum
.subvol
= new_subvol
;
121 dir_target
= new_subvol
;
122 dir_type
= DT_SUBVOL
;
124 ret
= bch2_subvolume_get_snapshot(trans
, dir
.subvol
, &dir_snapshot
);
128 bch2_btree_iter_set_snapshot(&dir_iter
, dir_snapshot
);
129 ret
= bch2_btree_iter_traverse(&dir_iter
);
134 if (!(flags
& BCH_CREATE_SNAPSHOT
)) {
136 ret
= bch2_set_acl_trans(trans
, new_inum
, new_inode
,
137 default_acl
, ACL_TYPE_DEFAULT
);
143 ret
= bch2_set_acl_trans(trans
, new_inum
, new_inode
,
144 acl
, ACL_TYPE_ACCESS
);
150 if (!(flags
& BCH_CREATE_TMPFILE
)) {
151 struct bch_hash_info dir_hash
= bch2_hash_info_init(c
, dir_u
);
154 if (is_subdir_for_nlink(new_inode
))
156 dir_u
->bi_mtime
= dir_u
->bi_ctime
= now
;
158 ret
= bch2_inode_write(trans
, &dir_iter
, dir_u
);
162 ret
= bch2_dirent_create(trans
, dir
, &dir_hash
,
167 STR_HASH_must_create
|BTREE_ITER_with_updates
);
171 new_inode
->bi_dir
= dir_u
->bi_inum
;
172 new_inode
->bi_dir_offset
= dir_offset
;
175 inode_iter
.flags
&= ~BTREE_ITER_all_snapshots
;
176 bch2_btree_iter_set_snapshot(&inode_iter
, snapshot
);
178 ret
= bch2_btree_iter_traverse(&inode_iter
) ?:
179 bch2_inode_write(trans
, &inode_iter
, new_inode
);
181 bch2_trans_iter_exit(trans
, &inode_iter
);
182 bch2_trans_iter_exit(trans
, &dir_iter
);
186 int bch2_link_trans(struct btree_trans
*trans
,
187 subvol_inum dir
, struct bch_inode_unpacked
*dir_u
,
188 subvol_inum inum
, struct bch_inode_unpacked
*inode_u
,
189 const struct qstr
*name
)
191 struct bch_fs
*c
= trans
->c
;
192 struct btree_iter dir_iter
= { NULL
};
193 struct btree_iter inode_iter
= { NULL
};
194 struct bch_hash_info dir_hash
;
195 u64 now
= bch2_current_time(c
);
199 if (dir
.subvol
!= inum
.subvol
)
202 ret
= bch2_inode_peek(trans
, &inode_iter
, inode_u
, inum
, BTREE_ITER_intent
);
206 inode_u
->bi_ctime
= now
;
207 ret
= bch2_inode_nlink_inc(inode_u
);
211 ret
= bch2_inode_peek(trans
, &dir_iter
, dir_u
, dir
, BTREE_ITER_intent
);
215 if (bch2_reinherit_attrs(inode_u
, dir_u
)) {
220 dir_u
->bi_mtime
= dir_u
->bi_ctime
= now
;
222 dir_hash
= bch2_hash_info_init(c
, dir_u
);
224 ret
= bch2_dirent_create(trans
, dir
, &dir_hash
,
225 mode_to_type(inode_u
->bi_mode
),
226 name
, inum
.inum
, &dir_offset
,
227 STR_HASH_must_create
);
231 inode_u
->bi_dir
= dir
.inum
;
232 inode_u
->bi_dir_offset
= dir_offset
;
234 ret
= bch2_inode_write(trans
, &dir_iter
, dir_u
) ?:
235 bch2_inode_write(trans
, &inode_iter
, inode_u
);
237 bch2_trans_iter_exit(trans
, &dir_iter
);
238 bch2_trans_iter_exit(trans
, &inode_iter
);
242 int bch2_unlink_trans(struct btree_trans
*trans
,
244 struct bch_inode_unpacked
*dir_u
,
245 struct bch_inode_unpacked
*inode_u
,
246 const struct qstr
*name
,
247 bool deleting_subvol
)
249 struct bch_fs
*c
= trans
->c
;
250 struct btree_iter dir_iter
= { NULL
};
251 struct btree_iter dirent_iter
= { NULL
};
252 struct btree_iter inode_iter
= { NULL
};
253 struct bch_hash_info dir_hash
;
255 u64 now
= bch2_current_time(c
);
259 ret
= bch2_inode_peek(trans
, &dir_iter
, dir_u
, dir
, BTREE_ITER_intent
);
263 dir_hash
= bch2_hash_info_init(c
, dir_u
);
265 ret
= bch2_dirent_lookup_trans(trans
, &dirent_iter
, dir
, &dir_hash
,
266 name
, &inum
, BTREE_ITER_intent
);
270 ret
= bch2_inode_peek(trans
, &inode_iter
, inode_u
, inum
,
275 if (!deleting_subvol
&& S_ISDIR(inode_u
->bi_mode
)) {
276 ret
= bch2_empty_dir_trans(trans
, inum
);
281 if (deleting_subvol
&& !inode_u
->bi_subvol
) {
282 ret
= -BCH_ERR_ENOENT_not_subvol
;
286 if (inode_u
->bi_subvol
) {
287 /* Recursive subvolume destroy not allowed (yet?) */
288 ret
= bch2_subvol_has_children(trans
, inode_u
->bi_subvol
);
293 if (deleting_subvol
|| inode_u
->bi_subvol
) {
294 ret
= bch2_subvolume_unlink(trans
, inode_u
->bi_subvol
);
298 k
= bch2_btree_iter_peek_slot(&dirent_iter
);
304 * If we're deleting a subvolume, we need to really delete the
305 * dirent, not just emit a whiteout in the current snapshot:
307 bch2_btree_iter_set_snapshot(&dirent_iter
, k
.k
->p
.snapshot
);
308 ret
= bch2_btree_iter_traverse(&dirent_iter
);
312 bch2_inode_nlink_dec(trans
, inode_u
);
315 if (inode_u
->bi_dir
== dirent_iter
.pos
.inode
&&
316 inode_u
->bi_dir_offset
== dirent_iter
.pos
.offset
) {
318 inode_u
->bi_dir_offset
= 0;
321 dir_u
->bi_mtime
= dir_u
->bi_ctime
= inode_u
->bi_ctime
= now
;
322 dir_u
->bi_nlink
-= is_subdir_for_nlink(inode_u
);
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
);
330 bch2_trans_iter_exit(trans
, &inode_iter
);
331 bch2_trans_iter_exit(trans
, &dirent_iter
);
332 bch2_trans_iter_exit(trans
, &dir_iter
);
336 bool bch2_reinherit_attrs(struct bch_inode_unpacked
*dst_u
,
337 struct bch_inode_unpacked
*src_u
)
343 for (id
= 0; id
< Inode_opt_nr
; id
++) {
344 /* Skip attributes that were explicitly set on this inode */
345 if (dst_u
->bi_fields_set
& (1 << id
))
348 src
= bch2_inode_opt_get(src_u
, id
);
349 dst
= bch2_inode_opt_get(dst_u
, id
);
354 bch2_inode_opt_set(dst_u
, id
, src
);
361 static int subvol_update_parent(struct btree_trans
*trans
, u32 subvol
, u32 new_parent
)
363 struct btree_iter iter
;
364 struct bkey_i_subvolume
*s
=
365 bch2_bkey_get_mut_typed(trans
, &iter
,
366 BTREE_ID_subvolumes
, POS(0, subvol
),
367 BTREE_ITER_cached
, subvolume
);
368 int ret
= PTR_ERR_OR_ZERO(s
);
372 s
->v
.fs_path_parent
= cpu_to_le32(new_parent
);
373 bch2_trans_iter_exit(trans
, &iter
);
377 int bch2_rename_trans(struct btree_trans
*trans
,
378 subvol_inum src_dir
, struct bch_inode_unpacked
*src_dir_u
,
379 subvol_inum dst_dir
, struct bch_inode_unpacked
*dst_dir_u
,
380 struct bch_inode_unpacked
*src_inode_u
,
381 struct bch_inode_unpacked
*dst_inode_u
,
382 const struct qstr
*src_name
,
383 const struct qstr
*dst_name
,
384 enum bch_rename_mode mode
)
386 struct bch_fs
*c
= trans
->c
;
387 struct btree_iter src_dir_iter
= { NULL
};
388 struct btree_iter dst_dir_iter
= { NULL
};
389 struct btree_iter src_inode_iter
= { NULL
};
390 struct btree_iter dst_inode_iter
= { NULL
};
391 struct bch_hash_info src_hash
, dst_hash
;
392 subvol_inum src_inum
, dst_inum
;
393 u64 src_offset
, dst_offset
;
394 u64 now
= bch2_current_time(c
);
397 ret
= bch2_inode_peek(trans
, &src_dir_iter
, src_dir_u
, src_dir
,
402 src_hash
= bch2_hash_info_init(c
, src_dir_u
);
404 if (dst_dir
.inum
!= src_dir
.inum
||
405 dst_dir
.subvol
!= src_dir
.subvol
) {
406 ret
= bch2_inode_peek(trans
, &dst_dir_iter
, dst_dir_u
, dst_dir
,
411 dst_hash
= bch2_hash_info_init(c
, dst_dir_u
);
413 dst_dir_u
= src_dir_u
;
417 ret
= bch2_dirent_rename(trans
,
420 src_name
, &src_inum
, &src_offset
,
421 dst_name
, &dst_inum
, &dst_offset
,
426 ret
= bch2_inode_peek(trans
, &src_inode_iter
, src_inode_u
, src_inum
,
432 ret
= bch2_inode_peek(trans
, &dst_inode_iter
, dst_inode_u
, dst_inum
,
438 if (src_inode_u
->bi_subvol
&&
439 dst_dir
.subvol
!= src_inode_u
->bi_parent_subvol
) {
440 ret
= subvol_update_parent(trans
, src_inode_u
->bi_subvol
, dst_dir
.subvol
);
445 if (mode
== BCH_RENAME_EXCHANGE
&&
446 dst_inode_u
->bi_subvol
&&
447 src_dir
.subvol
!= dst_inode_u
->bi_parent_subvol
) {
448 ret
= subvol_update_parent(trans
, dst_inode_u
->bi_subvol
, src_dir
.subvol
);
453 /* Can't move across subvolumes, unless it's a subvolume root: */
454 if (src_dir
.subvol
!= dst_dir
.subvol
&&
455 (!src_inode_u
->bi_subvol
||
456 (dst_inum
.inum
&& !dst_inode_u
->bi_subvol
))) {
461 if (src_inode_u
->bi_parent_subvol
)
462 src_inode_u
->bi_parent_subvol
= dst_dir
.subvol
;
464 if ((mode
== BCH_RENAME_EXCHANGE
) &&
465 dst_inode_u
->bi_parent_subvol
)
466 dst_inode_u
->bi_parent_subvol
= src_dir
.subvol
;
468 src_inode_u
->bi_dir
= dst_dir_u
->bi_inum
;
469 src_inode_u
->bi_dir_offset
= dst_offset
;
471 if (mode
== BCH_RENAME_EXCHANGE
) {
472 dst_inode_u
->bi_dir
= src_dir_u
->bi_inum
;
473 dst_inode_u
->bi_dir_offset
= src_offset
;
476 if (mode
== BCH_RENAME_OVERWRITE
&&
477 dst_inode_u
->bi_dir
== dst_dir_u
->bi_inum
&&
478 dst_inode_u
->bi_dir_offset
== src_offset
) {
479 dst_inode_u
->bi_dir
= 0;
480 dst_inode_u
->bi_dir_offset
= 0;
483 if (mode
== BCH_RENAME_OVERWRITE
) {
484 if (S_ISDIR(src_inode_u
->bi_mode
) !=
485 S_ISDIR(dst_inode_u
->bi_mode
)) {
490 if (S_ISDIR(dst_inode_u
->bi_mode
)) {
491 ret
= bch2_empty_dir_trans(trans
, dst_inum
);
497 if (bch2_reinherit_attrs(src_inode_u
, dst_dir_u
) &&
498 S_ISDIR(src_inode_u
->bi_mode
)) {
503 if (mode
== BCH_RENAME_EXCHANGE
&&
504 bch2_reinherit_attrs(dst_inode_u
, src_dir_u
) &&
505 S_ISDIR(dst_inode_u
->bi_mode
)) {
510 if (is_subdir_for_nlink(src_inode_u
)) {
511 src_dir_u
->bi_nlink
--;
512 dst_dir_u
->bi_nlink
++;
515 if (dst_inum
.inum
&& is_subdir_for_nlink(dst_inode_u
)) {
516 dst_dir_u
->bi_nlink
--;
517 src_dir_u
->bi_nlink
+= mode
== BCH_RENAME_EXCHANGE
;
520 if (mode
== BCH_RENAME_OVERWRITE
)
521 bch2_inode_nlink_dec(trans
, dst_inode_u
);
523 src_dir_u
->bi_mtime
= now
;
524 src_dir_u
->bi_ctime
= now
;
526 if (src_dir
.inum
!= dst_dir
.inum
) {
527 dst_dir_u
->bi_mtime
= now
;
528 dst_dir_u
->bi_ctime
= now
;
531 src_inode_u
->bi_ctime
= now
;
534 dst_inode_u
->bi_ctime
= now
;
536 ret
= bch2_inode_write(trans
, &src_dir_iter
, src_dir_u
) ?:
537 (src_dir
.inum
!= dst_dir
.inum
538 ? bch2_inode_write(trans
, &dst_dir_iter
, dst_dir_u
)
540 bch2_inode_write(trans
, &src_inode_iter
, src_inode_u
) ?:
542 ? bch2_inode_write(trans
, &dst_inode_iter
, dst_inode_u
)
545 bch2_trans_iter_exit(trans
, &dst_inode_iter
);
546 bch2_trans_iter_exit(trans
, &src_inode_iter
);
547 bch2_trans_iter_exit(trans
, &dst_dir_iter
);
548 bch2_trans_iter_exit(trans
, &src_dir_iter
);