xref: /linux/fs/bcachefs/fs-common.c (revision 8c3f6da9fc526e7ba0f6449efa1040084406e9ba)
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 "xattr.h"
10 
11 #include <linux/posix_acl.h>
12 
13 int bch2_create_trans(struct btree_trans *trans, u64 dir_inum,
14 		      struct bch_inode_unpacked *dir_u,
15 		      struct bch_inode_unpacked *new_inode,
16 		      const struct qstr *name,
17 		      uid_t uid, gid_t gid, umode_t mode, dev_t rdev,
18 		      struct posix_acl *default_acl,
19 		      struct posix_acl *acl)
20 {
21 	struct bch_fs *c = trans->c;
22 	struct btree_iter *dir_iter = NULL;
23 	struct btree_iter *inode_iter = NULL;
24 	struct bch_hash_info hash = bch2_hash_info_init(c, new_inode);
25 	u64 now = bch2_current_time(c);
26 	u64 cpu = raw_smp_processor_id();
27 	u64 dir_offset = 0;
28 	int ret;
29 
30 	dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT);
31 	ret = PTR_ERR_OR_ZERO(dir_iter);
32 	if (ret)
33 		goto err;
34 
35 	bch2_inode_init_late(new_inode, now, uid, gid, mode, rdev, dir_u);
36 
37 	if (!name)
38 		new_inode->bi_flags |= BCH_INODE_UNLINKED;
39 
40 	inode_iter = bch2_inode_create(trans, new_inode, U32_MAX, cpu);
41 	ret = PTR_ERR_OR_ZERO(inode_iter);
42 	if (ret)
43 		goto err;
44 
45 	if (default_acl) {
46 		ret = bch2_set_acl_trans(trans, new_inode, &hash,
47 					 default_acl, ACL_TYPE_DEFAULT);
48 		if (ret)
49 			goto err;
50 	}
51 
52 	if (acl) {
53 		ret = bch2_set_acl_trans(trans, new_inode, &hash,
54 					 acl, ACL_TYPE_ACCESS);
55 		if (ret)
56 			goto err;
57 	}
58 
59 	if (name) {
60 		struct bch_hash_info dir_hash = bch2_hash_info_init(c, dir_u);
61 		dir_u->bi_mtime = dir_u->bi_ctime = now;
62 
63 		if (S_ISDIR(new_inode->bi_mode))
64 			dir_u->bi_nlink++;
65 
66 		ret = bch2_inode_write(trans, dir_iter, dir_u);
67 		if (ret)
68 			goto err;
69 
70 		ret = bch2_dirent_create(trans, dir_inum, &dir_hash,
71 					 mode_to_type(new_inode->bi_mode),
72 					 name, new_inode->bi_inum,
73 					 &dir_offset,
74 					 BCH_HASH_SET_MUST_CREATE);
75 		if (ret)
76 			goto err;
77 	}
78 
79 	if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) {
80 		new_inode->bi_dir		= dir_u->bi_inum;
81 		new_inode->bi_dir_offset	= dir_offset;
82 	}
83 
84 	/* XXX use bch2_btree_iter_set_snapshot() */
85 	inode_iter->snapshot = U32_MAX;
86 	bch2_btree_iter_set_pos(inode_iter, SPOS(0, new_inode->bi_inum, U32_MAX));
87 
88 	ret   = bch2_btree_iter_traverse(inode_iter) ?:
89 		bch2_inode_write(trans, inode_iter, new_inode);
90 err:
91 	bch2_trans_iter_put(trans, inode_iter);
92 	bch2_trans_iter_put(trans, dir_iter);
93 	return ret;
94 }
95 
96 int bch2_link_trans(struct btree_trans *trans, u64 dir_inum,
97 		    u64 inum, struct bch_inode_unpacked *dir_u,
98 		    struct bch_inode_unpacked *inode_u, const struct qstr *name)
99 {
100 	struct bch_fs *c = trans->c;
101 	struct btree_iter *dir_iter = NULL, *inode_iter = NULL;
102 	struct bch_hash_info dir_hash;
103 	u64 now = bch2_current_time(c);
104 	u64 dir_offset = 0;
105 	int ret;
106 
107 	inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT);
108 	ret = PTR_ERR_OR_ZERO(inode_iter);
109 	if (ret)
110 		goto err;
111 
112 	inode_u->bi_ctime = now;
113 	bch2_inode_nlink_inc(inode_u);
114 
115 	dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, 0);
116 	ret = PTR_ERR_OR_ZERO(dir_iter);
117 	if (ret)
118 		goto err;
119 
120 	dir_u->bi_mtime = dir_u->bi_ctime = now;
121 
122 	dir_hash = bch2_hash_info_init(c, dir_u);
123 
124 	ret = bch2_dirent_create(trans, dir_inum, &dir_hash,
125 				 mode_to_type(inode_u->bi_mode),
126 				 name, inum, &dir_offset,
127 				 BCH_HASH_SET_MUST_CREATE);
128 	if (ret)
129 		goto err;
130 
131 	if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) {
132 		inode_u->bi_dir		= dir_inum;
133 		inode_u->bi_dir_offset	= dir_offset;
134 	}
135 
136 	ret =   bch2_inode_write(trans, dir_iter, dir_u) ?:
137 		bch2_inode_write(trans, inode_iter, inode_u);
138 err:
139 	bch2_trans_iter_put(trans, dir_iter);
140 	bch2_trans_iter_put(trans, inode_iter);
141 	return ret;
142 }
143 
144 int bch2_unlink_trans(struct btree_trans *trans,
145 		      u64 dir_inum, struct bch_inode_unpacked *dir_u,
146 		      struct bch_inode_unpacked *inode_u,
147 		      const struct qstr *name)
148 {
149 	struct bch_fs *c = trans->c;
150 	struct btree_iter *dir_iter = NULL, *dirent_iter = NULL,
151 			  *inode_iter = NULL;
152 	struct bch_hash_info dir_hash;
153 	u64 inum, now = bch2_current_time(c);
154 	struct bkey_s_c k;
155 	int ret;
156 
157 	dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT);
158 	ret = PTR_ERR_OR_ZERO(dir_iter);
159 	if (ret)
160 		goto err;
161 
162 	dir_hash = bch2_hash_info_init(c, dir_u);
163 
164 	dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum, &dir_hash,
165 						 name, BTREE_ITER_INTENT);
166 	ret = PTR_ERR_OR_ZERO(dirent_iter);
167 	if (ret)
168 		goto err;
169 
170 	k = bch2_btree_iter_peek_slot(dirent_iter);
171 	inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum);
172 
173 	inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT);
174 	ret = PTR_ERR_OR_ZERO(inode_iter);
175 	if (ret)
176 		goto err;
177 
178 	if (inode_u->bi_dir		== k.k->p.inode &&
179 	    inode_u->bi_dir_offset	== k.k->p.offset) {
180 		inode_u->bi_dir		= 0;
181 		inode_u->bi_dir_offset	= 0;
182 	}
183 
184 	dir_u->bi_mtime = dir_u->bi_ctime = inode_u->bi_ctime = now;
185 	dir_u->bi_nlink -= S_ISDIR(inode_u->bi_mode);
186 	bch2_inode_nlink_dec(inode_u);
187 
188 	ret =   (S_ISDIR(inode_u->bi_mode)
189 		 ? bch2_empty_dir_trans(trans, inum)
190 		 : 0) ?:
191 		bch2_dirent_delete_at(trans, &dir_hash, dirent_iter) ?:
192 		bch2_inode_write(trans, dir_iter, dir_u) ?:
193 		bch2_inode_write(trans, inode_iter, inode_u);
194 err:
195 	bch2_trans_iter_put(trans, inode_iter);
196 	bch2_trans_iter_put(trans, dirent_iter);
197 	bch2_trans_iter_put(trans, dir_iter);
198 	return ret;
199 }
200 
201 bool bch2_reinherit_attrs(struct bch_inode_unpacked *dst_u,
202 			  struct bch_inode_unpacked *src_u)
203 {
204 	u64 src, dst;
205 	unsigned id;
206 	bool ret = false;
207 
208 	for (id = 0; id < Inode_opt_nr; id++) {
209 		if (dst_u->bi_fields_set & (1 << id))
210 			continue;
211 
212 		src = bch2_inode_opt_get(src_u, id);
213 		dst = bch2_inode_opt_get(dst_u, id);
214 
215 		if (src == dst)
216 			continue;
217 
218 		bch2_inode_opt_set(dst_u, id, src);
219 		ret = true;
220 	}
221 
222 	return ret;
223 }
224 
225 int bch2_rename_trans(struct btree_trans *trans,
226 		      u64 src_dir, struct bch_inode_unpacked *src_dir_u,
227 		      u64 dst_dir, struct bch_inode_unpacked *dst_dir_u,
228 		      struct bch_inode_unpacked *src_inode_u,
229 		      struct bch_inode_unpacked *dst_inode_u,
230 		      const struct qstr *src_name,
231 		      const struct qstr *dst_name,
232 		      enum bch_rename_mode mode)
233 {
234 	struct bch_fs *c = trans->c;
235 	struct btree_iter *src_dir_iter = NULL, *dst_dir_iter = NULL;
236 	struct btree_iter *src_inode_iter = NULL, *dst_inode_iter = NULL;
237 	struct bch_hash_info src_hash, dst_hash;
238 	u64 src_inode, src_offset, dst_inode, dst_offset;
239 	u64 now = bch2_current_time(c);
240 	int ret;
241 
242 	src_dir_iter = bch2_inode_peek(trans, src_dir_u, src_dir,
243 				       BTREE_ITER_INTENT);
244 	ret = PTR_ERR_OR_ZERO(src_dir_iter);
245 	if (ret)
246 		goto err;
247 
248 	src_hash = bch2_hash_info_init(c, src_dir_u);
249 
250 	if (dst_dir != src_dir) {
251 		dst_dir_iter = bch2_inode_peek(trans, dst_dir_u, dst_dir,
252 					       BTREE_ITER_INTENT);
253 		ret = PTR_ERR_OR_ZERO(dst_dir_iter);
254 		if (ret)
255 			goto err;
256 
257 		dst_hash = bch2_hash_info_init(c, dst_dir_u);
258 	} else {
259 		dst_dir_u = src_dir_u;
260 		dst_hash = src_hash;
261 	}
262 
263 	ret = bch2_dirent_rename(trans,
264 				 src_dir, &src_hash,
265 				 dst_dir, &dst_hash,
266 				 src_name, &src_inode, &src_offset,
267 				 dst_name, &dst_inode, &dst_offset,
268 				 mode);
269 	if (ret)
270 		goto err;
271 
272 	src_inode_iter = bch2_inode_peek(trans, src_inode_u, src_inode,
273 					 BTREE_ITER_INTENT);
274 	ret = PTR_ERR_OR_ZERO(src_inode_iter);
275 	if (ret)
276 		goto err;
277 
278 	if (dst_inode) {
279 		dst_inode_iter = bch2_inode_peek(trans, dst_inode_u, dst_inode,
280 						 BTREE_ITER_INTENT);
281 		ret = PTR_ERR_OR_ZERO(dst_inode_iter);
282 		if (ret)
283 			goto err;
284 	}
285 
286 	if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) {
287 		src_inode_u->bi_dir		= dst_dir_u->bi_inum;
288 		src_inode_u->bi_dir_offset	= dst_offset;
289 
290 		if (mode == BCH_RENAME_EXCHANGE) {
291 			dst_inode_u->bi_dir		= src_dir_u->bi_inum;
292 			dst_inode_u->bi_dir_offset	= src_offset;
293 		}
294 
295 		if (mode == BCH_RENAME_OVERWRITE &&
296 		    dst_inode_u->bi_dir		== dst_dir_u->bi_inum &&
297 		    dst_inode_u->bi_dir_offset	== src_offset) {
298 			dst_inode_u->bi_dir		= 0;
299 			dst_inode_u->bi_dir_offset	= 0;
300 		}
301 	}
302 
303 	if (mode == BCH_RENAME_OVERWRITE) {
304 		if (S_ISDIR(src_inode_u->bi_mode) !=
305 		    S_ISDIR(dst_inode_u->bi_mode)) {
306 			ret = -ENOTDIR;
307 			goto err;
308 		}
309 
310 		if (S_ISDIR(dst_inode_u->bi_mode) &&
311 		    bch2_empty_dir_trans(trans, dst_inode)) {
312 			ret = -ENOTEMPTY;
313 			goto err;
314 		}
315 	}
316 
317 	if (bch2_reinherit_attrs(src_inode_u, dst_dir_u) &&
318 	    S_ISDIR(src_inode_u->bi_mode)) {
319 		ret = -EXDEV;
320 		goto err;
321 	}
322 
323 	if (mode == BCH_RENAME_EXCHANGE &&
324 	    bch2_reinherit_attrs(dst_inode_u, src_dir_u) &&
325 	    S_ISDIR(dst_inode_u->bi_mode)) {
326 		ret = -EXDEV;
327 		goto err;
328 	}
329 
330 	if (S_ISDIR(src_inode_u->bi_mode)) {
331 		src_dir_u->bi_nlink--;
332 		dst_dir_u->bi_nlink++;
333 	}
334 
335 	if (dst_inode && S_ISDIR(dst_inode_u->bi_mode)) {
336 		dst_dir_u->bi_nlink--;
337 		src_dir_u->bi_nlink += mode == BCH_RENAME_EXCHANGE;
338 	}
339 
340 	if (mode == BCH_RENAME_OVERWRITE)
341 		bch2_inode_nlink_dec(dst_inode_u);
342 
343 	src_dir_u->bi_mtime		= now;
344 	src_dir_u->bi_ctime		= now;
345 
346 	if (src_dir != dst_dir) {
347 		dst_dir_u->bi_mtime	= now;
348 		dst_dir_u->bi_ctime	= now;
349 	}
350 
351 	src_inode_u->bi_ctime		= now;
352 
353 	if (dst_inode)
354 		dst_inode_u->bi_ctime	= now;
355 
356 	ret =   bch2_inode_write(trans, src_dir_iter, src_dir_u) ?:
357 		(src_dir != dst_dir
358 		 ? bch2_inode_write(trans, dst_dir_iter, dst_dir_u)
359 		 : 0 ) ?:
360 		bch2_inode_write(trans, src_inode_iter, src_inode_u) ?:
361 		(dst_inode
362 		 ? bch2_inode_write(trans, dst_inode_iter, dst_inode_u)
363 		 : 0 );
364 err:
365 	bch2_trans_iter_put(trans, dst_inode_iter);
366 	bch2_trans_iter_put(trans, src_inode_iter);
367 	bch2_trans_iter_put(trans, dst_dir_iter);
368 	bch2_trans_iter_put(trans, src_dir_iter);
369 	return ret;
370 }
371