xref: /linux/fs/bcachefs/fs-common.c (revision 16ac8c9523a2744545bb773b41433a5007deeacb)
196385742SKent Overstreet // SPDX-License-Identifier: GPL-2.0
296385742SKent Overstreet 
396385742SKent Overstreet #include "bcachefs.h"
496385742SKent Overstreet #include "acl.h"
596385742SKent Overstreet #include "btree_update.h"
696385742SKent Overstreet #include "dirent.h"
796385742SKent Overstreet #include "fs-common.h"
896385742SKent Overstreet #include "inode.h"
996385742SKent Overstreet #include "xattr.h"
1096385742SKent Overstreet 
1196385742SKent Overstreet #include <linux/posix_acl.h>
1296385742SKent Overstreet 
1396385742SKent Overstreet int bch2_create_trans(struct btree_trans *trans, u64 dir_inum,
1496385742SKent Overstreet 		      struct bch_inode_unpacked *dir_u,
1596385742SKent Overstreet 		      struct bch_inode_unpacked *new_inode,
1696385742SKent Overstreet 		      const struct qstr *name,
1796385742SKent Overstreet 		      uid_t uid, gid_t gid, umode_t mode, dev_t rdev,
1896385742SKent Overstreet 		      struct posix_acl *default_acl,
1996385742SKent Overstreet 		      struct posix_acl *acl)
2096385742SKent Overstreet {
2196385742SKent Overstreet 	struct bch_fs *c = trans->c;
228b53852dSKent Overstreet 	struct btree_iter *dir_iter = NULL;
23ab2a29ccSKent Overstreet 	struct btree_iter *inode_iter = NULL;
2496385742SKent Overstreet 	struct bch_hash_info hash = bch2_hash_info_init(c, new_inode);
25ab2a29ccSKent Overstreet 	u64 now = bch2_current_time(c);
26ab2a29ccSKent Overstreet 	u64 dir_offset = 0;
2796385742SKent Overstreet 	int ret;
2896385742SKent Overstreet 
2963fbf458SKent Overstreet 	dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT);
308b53852dSKent Overstreet 	ret = PTR_ERR_OR_ZERO(dir_iter);
318b53852dSKent Overstreet 	if (ret)
328b53852dSKent Overstreet 		goto err;
3396385742SKent Overstreet 
3496385742SKent Overstreet 	bch2_inode_init_late(new_inode, now, uid, gid, mode, rdev, dir_u);
3596385742SKent Overstreet 
3696385742SKent Overstreet 	if (!name)
3796385742SKent Overstreet 		new_inode->bi_flags |= BCH_INODE_UNLINKED;
3896385742SKent Overstreet 
39e6ae2727SKent Overstreet 	inode_iter = bch2_inode_create(trans, new_inode, U32_MAX);
40ab2a29ccSKent Overstreet 	ret = PTR_ERR_OR_ZERO(inode_iter);
4196385742SKent Overstreet 	if (ret)
428b53852dSKent Overstreet 		goto err;
4396385742SKent Overstreet 
4496385742SKent Overstreet 	if (default_acl) {
4596385742SKent Overstreet 		ret = bch2_set_acl_trans(trans, new_inode, &hash,
4696385742SKent Overstreet 					 default_acl, ACL_TYPE_DEFAULT);
4796385742SKent Overstreet 		if (ret)
488b53852dSKent Overstreet 			goto err;
4996385742SKent Overstreet 	}
5096385742SKent Overstreet 
5196385742SKent Overstreet 	if (acl) {
5296385742SKent Overstreet 		ret = bch2_set_acl_trans(trans, new_inode, &hash,
5396385742SKent Overstreet 					 acl, ACL_TYPE_ACCESS);
5496385742SKent Overstreet 		if (ret)
558b53852dSKent Overstreet 			goto err;
5696385742SKent Overstreet 	}
5796385742SKent Overstreet 
5896385742SKent Overstreet 	if (name) {
5996385742SKent Overstreet 		struct bch_hash_info dir_hash = bch2_hash_info_init(c, dir_u);
6096385742SKent Overstreet 		dir_u->bi_mtime = dir_u->bi_ctime = now;
6196385742SKent Overstreet 
6296385742SKent Overstreet 		if (S_ISDIR(new_inode->bi_mode))
6396385742SKent Overstreet 			dir_u->bi_nlink++;
6496385742SKent Overstreet 
6596385742SKent Overstreet 		ret = bch2_inode_write(trans, dir_iter, dir_u);
6696385742SKent Overstreet 		if (ret)
678b53852dSKent Overstreet 			goto err;
6896385742SKent Overstreet 
6996385742SKent Overstreet 		ret = bch2_dirent_create(trans, dir_inum, &dir_hash,
7096385742SKent Overstreet 					 mode_to_type(new_inode->bi_mode),
7196385742SKent Overstreet 					 name, new_inode->bi_inum,
72ab2a29ccSKent Overstreet 					 &dir_offset,
7396385742SKent Overstreet 					 BCH_HASH_SET_MUST_CREATE);
7496385742SKent Overstreet 		if (ret)
758b53852dSKent Overstreet 			goto err;
7696385742SKent Overstreet 	}
77ab2a29ccSKent Overstreet 
78ab2a29ccSKent Overstreet 	if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) {
79ab2a29ccSKent Overstreet 		new_inode->bi_dir		= dir_u->bi_inum;
80ab2a29ccSKent Overstreet 		new_inode->bi_dir_offset	= dir_offset;
81ab2a29ccSKent Overstreet 	}
82ab2a29ccSKent Overstreet 
83e6ae2727SKent Overstreet 	/* XXX use bch2_btree_iter_set_snapshot() */
84e6ae2727SKent Overstreet 	inode_iter->snapshot = U32_MAX;
85e6ae2727SKent Overstreet 	bch2_btree_iter_set_pos(inode_iter, SPOS(0, new_inode->bi_inum, U32_MAX));
86e6ae2727SKent Overstreet 
87ab2a29ccSKent Overstreet 	ret = bch2_inode_write(trans, inode_iter, new_inode);
888b53852dSKent Overstreet err:
89ab2a29ccSKent Overstreet 	bch2_trans_iter_put(trans, inode_iter);
908b53852dSKent Overstreet 	bch2_trans_iter_put(trans, dir_iter);
918b53852dSKent Overstreet 	return ret;
9296385742SKent Overstreet }
9396385742SKent Overstreet 
9463fbf458SKent Overstreet int bch2_link_trans(struct btree_trans *trans, u64 dir_inum,
95184b1dc1SJustin Husted 		    u64 inum, struct bch_inode_unpacked *dir_u,
96184b1dc1SJustin Husted 		    struct bch_inode_unpacked *inode_u, const struct qstr *name)
9796385742SKent Overstreet {
98ab2a29ccSKent Overstreet 	struct bch_fs *c = trans->c;
998b53852dSKent Overstreet 	struct btree_iter *dir_iter = NULL, *inode_iter = NULL;
10096385742SKent Overstreet 	struct bch_hash_info dir_hash;
101ab2a29ccSKent Overstreet 	u64 now = bch2_current_time(c);
102ab2a29ccSKent Overstreet 	u64 dir_offset = 0;
1038b53852dSKent Overstreet 	int ret;
10496385742SKent Overstreet 
10596385742SKent Overstreet 	inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT);
1068b53852dSKent Overstreet 	ret = PTR_ERR_OR_ZERO(inode_iter);
1078b53852dSKent Overstreet 	if (ret)
1088b53852dSKent Overstreet 		goto err;
10996385742SKent Overstreet 
11096385742SKent Overstreet 	inode_u->bi_ctime = now;
11196385742SKent Overstreet 	bch2_inode_nlink_inc(inode_u);
11296385742SKent Overstreet 
113184b1dc1SJustin Husted 	dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, 0);
1148b53852dSKent Overstreet 	ret = PTR_ERR_OR_ZERO(dir_iter);
1158b53852dSKent Overstreet 	if (ret)
1168b53852dSKent Overstreet 		goto err;
11763fbf458SKent Overstreet 
118184b1dc1SJustin Husted 	dir_u->bi_mtime = dir_u->bi_ctime = now;
11963fbf458SKent Overstreet 
120ab2a29ccSKent Overstreet 	dir_hash = bch2_hash_info_init(c, dir_u);
12163fbf458SKent Overstreet 
1228b53852dSKent Overstreet 	ret = bch2_dirent_create(trans, dir_inum, &dir_hash,
12396385742SKent Overstreet 				 mode_to_type(inode_u->bi_mode),
124ab2a29ccSKent Overstreet 				 name, inum, &dir_offset,
125ab2a29ccSKent Overstreet 				 BCH_HASH_SET_MUST_CREATE);
126ab2a29ccSKent Overstreet 	if (ret)
127ab2a29ccSKent Overstreet 		goto err;
128ab2a29ccSKent Overstreet 
129ab2a29ccSKent Overstreet 	if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) {
130ab2a29ccSKent Overstreet 		inode_u->bi_dir		= dir_inum;
131ab2a29ccSKent Overstreet 		inode_u->bi_dir_offset	= dir_offset;
132ab2a29ccSKent Overstreet 	}
133ab2a29ccSKent Overstreet 
134ab2a29ccSKent Overstreet 	ret =   bch2_inode_write(trans, dir_iter, dir_u) ?:
13596385742SKent Overstreet 		bch2_inode_write(trans, inode_iter, inode_u);
1368b53852dSKent Overstreet err:
1378b53852dSKent Overstreet 	bch2_trans_iter_put(trans, dir_iter);
1388b53852dSKent Overstreet 	bch2_trans_iter_put(trans, inode_iter);
1398b53852dSKent Overstreet 	return ret;
14096385742SKent Overstreet }
14196385742SKent Overstreet 
14296385742SKent Overstreet int bch2_unlink_trans(struct btree_trans *trans,
14396385742SKent Overstreet 		      u64 dir_inum, struct bch_inode_unpacked *dir_u,
14496385742SKent Overstreet 		      struct bch_inode_unpacked *inode_u,
14596385742SKent Overstreet 		      const struct qstr *name)
14696385742SKent Overstreet {
147ab2a29ccSKent Overstreet 	struct bch_fs *c = trans->c;
1488b53852dSKent Overstreet 	struct btree_iter *dir_iter = NULL, *dirent_iter = NULL,
1498b53852dSKent Overstreet 			  *inode_iter = NULL;
15096385742SKent Overstreet 	struct bch_hash_info dir_hash;
151ab2a29ccSKent Overstreet 	u64 inum, now = bch2_current_time(c);
15296385742SKent Overstreet 	struct bkey_s_c k;
1538b53852dSKent Overstreet 	int ret;
15496385742SKent Overstreet 
15596385742SKent Overstreet 	dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT);
1568b53852dSKent Overstreet 	ret = PTR_ERR_OR_ZERO(dir_iter);
1578b53852dSKent Overstreet 	if (ret)
1588b53852dSKent Overstreet 		goto err;
15996385742SKent Overstreet 
160ab2a29ccSKent Overstreet 	dir_hash = bch2_hash_info_init(c, dir_u);
16196385742SKent Overstreet 
16263fbf458SKent Overstreet 	dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum, &dir_hash,
16363fbf458SKent Overstreet 						 name, BTREE_ITER_INTENT);
1648b53852dSKent Overstreet 	ret = PTR_ERR_OR_ZERO(dirent_iter);
1658b53852dSKent Overstreet 	if (ret)
1668b53852dSKent Overstreet 		goto err;
16796385742SKent Overstreet 
16896385742SKent Overstreet 	k = bch2_btree_iter_peek_slot(dirent_iter);
16996385742SKent Overstreet 	inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum);
17096385742SKent Overstreet 
17196385742SKent Overstreet 	inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT);
1728b53852dSKent Overstreet 	ret = PTR_ERR_OR_ZERO(inode_iter);
1738b53852dSKent Overstreet 	if (ret)
1748b53852dSKent Overstreet 		goto err;
17596385742SKent Overstreet 
176d3ff7fecSKent Overstreet 	if (inode_u->bi_dir		== k.k->p.inode &&
177d3ff7fecSKent Overstreet 	    inode_u->bi_dir_offset	== k.k->p.offset) {
178d3ff7fecSKent Overstreet 		inode_u->bi_dir		= 0;
179d3ff7fecSKent Overstreet 		inode_u->bi_dir_offset	= 0;
180d3ff7fecSKent Overstreet 	}
181d3ff7fecSKent Overstreet 
18296385742SKent Overstreet 	dir_u->bi_mtime = dir_u->bi_ctime = inode_u->bi_ctime = now;
18396385742SKent Overstreet 	dir_u->bi_nlink -= S_ISDIR(inode_u->bi_mode);
18496385742SKent Overstreet 	bch2_inode_nlink_dec(inode_u);
18596385742SKent Overstreet 
1868b53852dSKent Overstreet 	ret =   (S_ISDIR(inode_u->bi_mode)
18796385742SKent Overstreet 		 ? bch2_empty_dir_trans(trans, inum)
18896385742SKent Overstreet 		 : 0) ?:
18996385742SKent Overstreet 		bch2_dirent_delete_at(trans, &dir_hash, dirent_iter) ?:
19096385742SKent Overstreet 		bch2_inode_write(trans, dir_iter, dir_u) ?:
19196385742SKent Overstreet 		bch2_inode_write(trans, inode_iter, inode_u);
1928b53852dSKent Overstreet err:
1938b53852dSKent Overstreet 	bch2_trans_iter_put(trans, inode_iter);
1948b53852dSKent Overstreet 	bch2_trans_iter_put(trans, dirent_iter);
1958b53852dSKent Overstreet 	bch2_trans_iter_put(trans, dir_iter);
1968b53852dSKent Overstreet 	return ret;
19796385742SKent Overstreet }
19896385742SKent Overstreet 
19996385742SKent Overstreet bool bch2_reinherit_attrs(struct bch_inode_unpacked *dst_u,
20096385742SKent Overstreet 			  struct bch_inode_unpacked *src_u)
20196385742SKent Overstreet {
20296385742SKent Overstreet 	u64 src, dst;
20396385742SKent Overstreet 	unsigned id;
20496385742SKent Overstreet 	bool ret = false;
20596385742SKent Overstreet 
20696385742SKent Overstreet 	for (id = 0; id < Inode_opt_nr; id++) {
20796385742SKent Overstreet 		if (dst_u->bi_fields_set & (1 << id))
20896385742SKent Overstreet 			continue;
20996385742SKent Overstreet 
21096385742SKent Overstreet 		src = bch2_inode_opt_get(src_u, id);
21196385742SKent Overstreet 		dst = bch2_inode_opt_get(dst_u, id);
21296385742SKent Overstreet 
21396385742SKent Overstreet 		if (src == dst)
21496385742SKent Overstreet 			continue;
21596385742SKent Overstreet 
21696385742SKent Overstreet 		bch2_inode_opt_set(dst_u, id, src);
21796385742SKent Overstreet 		ret = true;
21896385742SKent Overstreet 	}
21996385742SKent Overstreet 
22096385742SKent Overstreet 	return ret;
22196385742SKent Overstreet }
22296385742SKent Overstreet 
22396385742SKent Overstreet int bch2_rename_trans(struct btree_trans *trans,
22496385742SKent Overstreet 		      u64 src_dir, struct bch_inode_unpacked *src_dir_u,
22596385742SKent Overstreet 		      u64 dst_dir, struct bch_inode_unpacked *dst_dir_u,
22696385742SKent Overstreet 		      struct bch_inode_unpacked *src_inode_u,
22796385742SKent Overstreet 		      struct bch_inode_unpacked *dst_inode_u,
22896385742SKent Overstreet 		      const struct qstr *src_name,
22996385742SKent Overstreet 		      const struct qstr *dst_name,
23096385742SKent Overstreet 		      enum bch_rename_mode mode)
23196385742SKent Overstreet {
232ab2a29ccSKent Overstreet 	struct bch_fs *c = trans->c;
2338b53852dSKent Overstreet 	struct btree_iter *src_dir_iter = NULL, *dst_dir_iter = NULL;
2348b53852dSKent Overstreet 	struct btree_iter *src_inode_iter = NULL, *dst_inode_iter = NULL;
23596385742SKent Overstreet 	struct bch_hash_info src_hash, dst_hash;
236ab2a29ccSKent Overstreet 	u64 src_inode, src_offset, dst_inode, dst_offset;
237ab2a29ccSKent Overstreet 	u64 now = bch2_current_time(c);
23896385742SKent Overstreet 	int ret;
23996385742SKent Overstreet 
24096385742SKent Overstreet 	src_dir_iter = bch2_inode_peek(trans, src_dir_u, src_dir,
24196385742SKent Overstreet 				       BTREE_ITER_INTENT);
2428b53852dSKent Overstreet 	ret = PTR_ERR_OR_ZERO(src_dir_iter);
2438b53852dSKent Overstreet 	if (ret)
2448b53852dSKent Overstreet 		goto err;
24596385742SKent Overstreet 
246ab2a29ccSKent Overstreet 	src_hash = bch2_hash_info_init(c, src_dir_u);
24796385742SKent Overstreet 
24896385742SKent Overstreet 	if (dst_dir != src_dir) {
24996385742SKent Overstreet 		dst_dir_iter = bch2_inode_peek(trans, dst_dir_u, dst_dir,
25096385742SKent Overstreet 					       BTREE_ITER_INTENT);
2518b53852dSKent Overstreet 		ret = PTR_ERR_OR_ZERO(dst_dir_iter);
2528b53852dSKent Overstreet 		if (ret)
2538b53852dSKent Overstreet 			goto err;
25496385742SKent Overstreet 
255ab2a29ccSKent Overstreet 		dst_hash = bch2_hash_info_init(c, dst_dir_u);
25696385742SKent Overstreet 	} else {
25796385742SKent Overstreet 		dst_dir_u = src_dir_u;
25896385742SKent Overstreet 		dst_hash = src_hash;
25996385742SKent Overstreet 	}
26096385742SKent Overstreet 
26196385742SKent Overstreet 	ret = bch2_dirent_rename(trans,
26296385742SKent Overstreet 				 src_dir, &src_hash,
26396385742SKent Overstreet 				 dst_dir, &dst_hash,
264ab2a29ccSKent Overstreet 				 src_name, &src_inode, &src_offset,
265ab2a29ccSKent Overstreet 				 dst_name, &dst_inode, &dst_offset,
26696385742SKent Overstreet 				 mode);
26796385742SKent Overstreet 	if (ret)
2688b53852dSKent Overstreet 		goto err;
26996385742SKent Overstreet 
27096385742SKent Overstreet 	src_inode_iter = bch2_inode_peek(trans, src_inode_u, src_inode,
27196385742SKent Overstreet 					 BTREE_ITER_INTENT);
2728b53852dSKent Overstreet 	ret = PTR_ERR_OR_ZERO(src_inode_iter);
2738b53852dSKent Overstreet 	if (ret)
2748b53852dSKent Overstreet 		goto err;
27596385742SKent Overstreet 
27696385742SKent Overstreet 	if (dst_inode) {
27796385742SKent Overstreet 		dst_inode_iter = bch2_inode_peek(trans, dst_inode_u, dst_inode,
27896385742SKent Overstreet 						 BTREE_ITER_INTENT);
2798b53852dSKent Overstreet 		ret = PTR_ERR_OR_ZERO(dst_inode_iter);
2808b53852dSKent Overstreet 		if (ret)
2818b53852dSKent Overstreet 			goto err;
28296385742SKent Overstreet 	}
28396385742SKent Overstreet 
284ab2a29ccSKent Overstreet 	if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) {
285ab2a29ccSKent Overstreet 		src_inode_u->bi_dir		= dst_dir_u->bi_inum;
286ab2a29ccSKent Overstreet 		src_inode_u->bi_dir_offset	= dst_offset;
287ab2a29ccSKent Overstreet 
288ab2a29ccSKent Overstreet 		if (mode == BCH_RENAME_EXCHANGE) {
289ab2a29ccSKent Overstreet 			dst_inode_u->bi_dir		= src_dir_u->bi_inum;
290ab2a29ccSKent Overstreet 			dst_inode_u->bi_dir_offset	= src_offset;
291ab2a29ccSKent Overstreet 		}
292*16ac8c95SKent Overstreet 
293*16ac8c95SKent Overstreet 		if (mode == BCH_RENAME_OVERWRITE &&
294*16ac8c95SKent Overstreet 		    dst_inode_u->bi_dir		== dst_dir_u->bi_inum &&
295*16ac8c95SKent Overstreet 		    dst_inode_u->bi_dir_offset	== src_offset) {
296*16ac8c95SKent Overstreet 			dst_inode_u->bi_dir		= 0;
297*16ac8c95SKent Overstreet 			dst_inode_u->bi_dir_offset	= 0;
298*16ac8c95SKent Overstreet 		}
299ab2a29ccSKent Overstreet 	}
300ab2a29ccSKent Overstreet 
30196385742SKent Overstreet 	if (mode == BCH_RENAME_OVERWRITE) {
30296385742SKent Overstreet 		if (S_ISDIR(src_inode_u->bi_mode) !=
3038b53852dSKent Overstreet 		    S_ISDIR(dst_inode_u->bi_mode)) {
3048b53852dSKent Overstreet 			ret = -ENOTDIR;
3058b53852dSKent Overstreet 			goto err;
3068b53852dSKent Overstreet 		}
30796385742SKent Overstreet 
30896385742SKent Overstreet 		if (S_ISDIR(dst_inode_u->bi_mode) &&
3098b53852dSKent Overstreet 		    bch2_empty_dir_trans(trans, dst_inode)) {
3108b53852dSKent Overstreet 			ret = -ENOTEMPTY;
3118b53852dSKent Overstreet 			goto err;
3128b53852dSKent Overstreet 		}
31396385742SKent Overstreet 	}
31496385742SKent Overstreet 
31596385742SKent Overstreet 	if (bch2_reinherit_attrs(src_inode_u, dst_dir_u) &&
3168b53852dSKent Overstreet 	    S_ISDIR(src_inode_u->bi_mode)) {
3178b53852dSKent Overstreet 		ret = -EXDEV;
3188b53852dSKent Overstreet 		goto err;
3198b53852dSKent Overstreet 	}
32096385742SKent Overstreet 
32196385742SKent Overstreet 	if (mode == BCH_RENAME_EXCHANGE &&
32296385742SKent Overstreet 	    bch2_reinherit_attrs(dst_inode_u, src_dir_u) &&
3238b53852dSKent Overstreet 	    S_ISDIR(dst_inode_u->bi_mode)) {
3248b53852dSKent Overstreet 		ret = -EXDEV;
3258b53852dSKent Overstreet 		goto err;
3268b53852dSKent Overstreet 	}
32796385742SKent Overstreet 
32896385742SKent Overstreet 	if (S_ISDIR(src_inode_u->bi_mode)) {
32996385742SKent Overstreet 		src_dir_u->bi_nlink--;
33096385742SKent Overstreet 		dst_dir_u->bi_nlink++;
33196385742SKent Overstreet 	}
33296385742SKent Overstreet 
33396385742SKent Overstreet 	if (dst_inode && S_ISDIR(dst_inode_u->bi_mode)) {
33496385742SKent Overstreet 		dst_dir_u->bi_nlink--;
33596385742SKent Overstreet 		src_dir_u->bi_nlink += mode == BCH_RENAME_EXCHANGE;
33696385742SKent Overstreet 	}
33796385742SKent Overstreet 
33896385742SKent Overstreet 	if (mode == BCH_RENAME_OVERWRITE)
33996385742SKent Overstreet 		bch2_inode_nlink_dec(dst_inode_u);
34096385742SKent Overstreet 
34196385742SKent Overstreet 	src_dir_u->bi_mtime		= now;
34296385742SKent Overstreet 	src_dir_u->bi_ctime		= now;
34396385742SKent Overstreet 
34496385742SKent Overstreet 	if (src_dir != dst_dir) {
34596385742SKent Overstreet 		dst_dir_u->bi_mtime	= now;
34696385742SKent Overstreet 		dst_dir_u->bi_ctime	= now;
34796385742SKent Overstreet 	}
34896385742SKent Overstreet 
34996385742SKent Overstreet 	src_inode_u->bi_ctime		= now;
35096385742SKent Overstreet 
35196385742SKent Overstreet 	if (dst_inode)
35296385742SKent Overstreet 		dst_inode_u->bi_ctime	= now;
35396385742SKent Overstreet 
3548b53852dSKent Overstreet 	ret =   bch2_inode_write(trans, src_dir_iter, src_dir_u) ?:
35596385742SKent Overstreet 		(src_dir != dst_dir
35696385742SKent Overstreet 		 ? bch2_inode_write(trans, dst_dir_iter, dst_dir_u)
35796385742SKent Overstreet 		 : 0 ) ?:
35896385742SKent Overstreet 		bch2_inode_write(trans, src_inode_iter, src_inode_u) ?:
35996385742SKent Overstreet 		(dst_inode
36096385742SKent Overstreet 		 ? bch2_inode_write(trans, dst_inode_iter, dst_inode_u)
36196385742SKent Overstreet 		 : 0 );
3628b53852dSKent Overstreet err:
3638b53852dSKent Overstreet 	bch2_trans_iter_put(trans, dst_inode_iter);
3648b53852dSKent Overstreet 	bch2_trans_iter_put(trans, src_inode_iter);
3658b53852dSKent Overstreet 	bch2_trans_iter_put(trans, dst_dir_iter);
3668b53852dSKent Overstreet 	bch2_trans_iter_put(trans, src_dir_iter);
3678b53852dSKent Overstreet 	return ret;
36896385742SKent Overstreet }
369