xref: /linux/fs/bcachefs/fs-common.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
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,
46 			      BTREE_ITER_intent|BTREE_ITER_with_updates);
47 	if (ret)
48 		goto err;
49 
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);
53 
54 		if (flags & BCH_CREATE_TMPFILE)
55 			new_inode->bi_flags |= BCH_INODE_unlinked;
56 
57 		ret = bch2_inode_create(trans, &inode_iter, new_inode, snapshot, cpu);
58 		if (ret)
59 			goto err;
60 
61 		snapshot_src = (subvol_inum) { 0 };
62 	} else {
63 		/*
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):
67 		 */
68 
69 		if (!snapshot_src.inum) {
70 			/* Inode wasn't specified, just snapshot: */
71 			struct bch_subvolume s;
72 
73 			ret = bch2_subvolume_get(trans, snapshot_src.subvol, true,
74 						 BTREE_ITER_cached, &s);
75 			if (ret)
76 				goto err;
77 
78 			snapshot_src.inum = le64_to_cpu(s.inode);
79 		}
80 
81 		ret = bch2_inode_peek(trans, &inode_iter, new_inode, snapshot_src,
82 				      BTREE_ITER_intent);
83 		if (ret)
84 			goto err;
85 
86 		if (new_inode->bi_subvol != snapshot_src.subvol) {
87 			/* Not a subvolume root: */
88 			ret = -EINVAL;
89 			goto err;
90 		}
91 
92 		/*
93 		 * If we're not root, we have to own the subvolume being
94 		 * snapshotted:
95 		 */
96 		if (uid && new_inode->bi_uid != uid) {
97 			ret = -EPERM;
98 			goto err;
99 		}
100 
101 		flags |= BCH_CREATE_SUBVOL;
102 	}
103 
104 	new_inum.inum	= new_inode->bi_inum;
105 	dir_target	= new_inode->bi_inum;
106 
107 	if (flags & BCH_CREATE_SUBVOL) {
108 		u32 new_subvol, dir_snapshot;
109 
110 		ret = bch2_subvolume_create(trans, new_inode->bi_inum,
111 					    dir.subvol,
112 					    snapshot_src.subvol,
113 					    &new_subvol, &snapshot,
114 					    (flags & BCH_CREATE_SNAPSHOT_RO) != 0);
115 		if (ret)
116 			goto err;
117 
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;
123 
124 		ret = bch2_subvolume_get_snapshot(trans, dir.subvol, &dir_snapshot);
125 		if (ret)
126 			goto err;
127 
128 		bch2_btree_iter_set_snapshot(&dir_iter, dir_snapshot);
129 		ret = bch2_btree_iter_traverse(&dir_iter);
130 		if (ret)
131 			goto err;
132 	}
133 
134 	if (!(flags & BCH_CREATE_SNAPSHOT)) {
135 		if (default_acl) {
136 			ret = bch2_set_acl_trans(trans, new_inum, new_inode,
137 						 default_acl, ACL_TYPE_DEFAULT);
138 			if (ret)
139 				goto err;
140 		}
141 
142 		if (acl) {
143 			ret = bch2_set_acl_trans(trans, new_inum, new_inode,
144 						 acl, ACL_TYPE_ACCESS);
145 			if (ret)
146 				goto err;
147 		}
148 	}
149 
150 	if (!(flags & BCH_CREATE_TMPFILE)) {
151 		struct bch_hash_info dir_hash = bch2_hash_info_init(c, dir_u);
152 		u64 dir_offset;
153 
154 		if (is_subdir_for_nlink(new_inode))
155 			dir_u->bi_nlink++;
156 		dir_u->bi_mtime = dir_u->bi_ctime = now;
157 
158 		ret = bch2_inode_write(trans, &dir_iter, dir_u);
159 		if (ret)
160 			goto err;
161 
162 		ret = bch2_dirent_create(trans, dir, &dir_hash,
163 					 dir_type,
164 					 name,
165 					 dir_target,
166 					 &dir_offset,
167 					 STR_HASH_must_create|BTREE_ITER_with_updates);
168 		if (ret)
169 			goto err;
170 
171 		new_inode->bi_dir		= dir_u->bi_inum;
172 		new_inode->bi_dir_offset	= dir_offset;
173 	}
174 
175 	inode_iter.flags &= ~BTREE_ITER_all_snapshots;
176 	bch2_btree_iter_set_snapshot(&inode_iter, snapshot);
177 
178 	ret   = bch2_btree_iter_traverse(&inode_iter) ?:
179 		bch2_inode_write(trans, &inode_iter, new_inode);
180 err:
181 	bch2_trans_iter_exit(trans, &inode_iter);
182 	bch2_trans_iter_exit(trans, &dir_iter);
183 	return ret;
184 }
185 
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)
190 {
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);
196 	u64 dir_offset = 0;
197 	int ret;
198 
199 	if (dir.subvol != inum.subvol)
200 		return -EXDEV;
201 
202 	ret = bch2_inode_peek(trans, &inode_iter, inode_u, inum, BTREE_ITER_intent);
203 	if (ret)
204 		return ret;
205 
206 	inode_u->bi_ctime = now;
207 	ret = bch2_inode_nlink_inc(inode_u);
208 	if (ret)
209 		goto err;
210 
211 	ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_intent);
212 	if (ret)
213 		goto err;
214 
215 	if (bch2_reinherit_attrs(inode_u, dir_u)) {
216 		ret = -EXDEV;
217 		goto err;
218 	}
219 
220 	dir_u->bi_mtime = dir_u->bi_ctime = now;
221 
222 	dir_hash = bch2_hash_info_init(c, dir_u);
223 
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);
228 	if (ret)
229 		goto err;
230 
231 	inode_u->bi_dir		= dir.inum;
232 	inode_u->bi_dir_offset	= dir_offset;
233 
234 	ret =   bch2_inode_write(trans, &dir_iter, dir_u) ?:
235 		bch2_inode_write(trans, &inode_iter, inode_u);
236 err:
237 	bch2_trans_iter_exit(trans, &dir_iter);
238 	bch2_trans_iter_exit(trans, &inode_iter);
239 	return ret;
240 }
241 
242 int bch2_unlink_trans(struct btree_trans *trans,
243 		      subvol_inum dir,
244 		      struct bch_inode_unpacked *dir_u,
245 		      struct bch_inode_unpacked *inode_u,
246 		      const struct qstr *name,
247 		      bool deleting_subvol)
248 {
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;
254 	subvol_inum inum;
255 	u64 now = bch2_current_time(c);
256 	struct bkey_s_c k;
257 	int ret;
258 
259 	ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_intent);
260 	if (ret)
261 		goto err;
262 
263 	dir_hash = bch2_hash_info_init(c, dir_u);
264 
265 	ret = bch2_dirent_lookup_trans(trans, &dirent_iter, dir, &dir_hash,
266 				       name, &inum, BTREE_ITER_intent);
267 	if (ret)
268 		goto err;
269 
270 	ret = bch2_inode_peek(trans, &inode_iter, inode_u, inum,
271 			      BTREE_ITER_intent);
272 	if (ret)
273 		goto err;
274 
275 	if (!deleting_subvol && S_ISDIR(inode_u->bi_mode)) {
276 		ret = bch2_empty_dir_trans(trans, inum);
277 		if (ret)
278 			goto err;
279 	}
280 
281 	if (deleting_subvol && !inode_u->bi_subvol) {
282 		ret = -BCH_ERR_ENOENT_not_subvol;
283 		goto err;
284 	}
285 
286 	if (inode_u->bi_subvol) {
287 		/* Recursive subvolume destroy not allowed (yet?) */
288 		ret = bch2_subvol_has_children(trans, inode_u->bi_subvol);
289 		if (ret)
290 			goto err;
291 	}
292 
293 	if (deleting_subvol || inode_u->bi_subvol) {
294 		ret = bch2_subvolume_unlink(trans, inode_u->bi_subvol);
295 		if (ret)
296 			goto err;
297 
298 		k = bch2_btree_iter_peek_slot(&dirent_iter);
299 		ret = bkey_err(k);
300 		if (ret)
301 			goto err;
302 
303 		/*
304 		 * If we're deleting a subvolume, we need to really delete the
305 		 * dirent, not just emit a whiteout in the current snapshot:
306 		 */
307 		bch2_btree_iter_set_snapshot(&dirent_iter, k.k->p.snapshot);
308 		ret = bch2_btree_iter_traverse(&dirent_iter);
309 		if (ret)
310 			goto err;
311 	} else {
312 		bch2_inode_nlink_dec(trans, inode_u);
313 	}
314 
315 	if (inode_u->bi_dir		== dirent_iter.pos.inode &&
316 	    inode_u->bi_dir_offset	== dirent_iter.pos.offset) {
317 		inode_u->bi_dir		= 0;
318 		inode_u->bi_dir_offset	= 0;
319 	}
320 
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);
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 		/* Skip attributes that were explicitly set on this inode */
345 		if (dst_u->bi_fields_set & (1 << id))
346 			continue;
347 
348 		src = bch2_inode_opt_get(src_u, id);
349 		dst = bch2_inode_opt_get(dst_u, id);
350 
351 		if (src == dst)
352 			continue;
353 
354 		bch2_inode_opt_set(dst_u, id, src);
355 		ret = true;
356 	}
357 
358 	return ret;
359 }
360 
361 static int subvol_update_parent(struct btree_trans *trans, u32 subvol, u32 new_parent)
362 {
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);
369 	if (ret)
370 		return ret;
371 
372 	s->v.fs_path_parent = cpu_to_le32(new_parent);
373 	bch2_trans_iter_exit(trans, &iter);
374 	return 0;
375 }
376 
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)
385 {
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);
395 	int ret;
396 
397 	ret = bch2_inode_peek(trans, &src_dir_iter, src_dir_u, src_dir,
398 			      BTREE_ITER_intent);
399 	if (ret)
400 		goto err;
401 
402 	src_hash = bch2_hash_info_init(c, src_dir_u);
403 
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,
407 				      BTREE_ITER_intent);
408 		if (ret)
409 			goto err;
410 
411 		dst_hash = bch2_hash_info_init(c, dst_dir_u);
412 	} else {
413 		dst_dir_u = src_dir_u;
414 		dst_hash = src_hash;
415 	}
416 
417 	ret = bch2_dirent_rename(trans,
418 				 src_dir, &src_hash,
419 				 dst_dir, &dst_hash,
420 				 src_name, &src_inum, &src_offset,
421 				 dst_name, &dst_inum, &dst_offset,
422 				 mode);
423 	if (ret)
424 		goto err;
425 
426 	ret = bch2_inode_peek(trans, &src_inode_iter, src_inode_u, src_inum,
427 			      BTREE_ITER_intent);
428 	if (ret)
429 		goto err;
430 
431 	if (dst_inum.inum) {
432 		ret = bch2_inode_peek(trans, &dst_inode_iter, dst_inode_u, dst_inum,
433 				      BTREE_ITER_intent);
434 		if (ret)
435 			goto err;
436 	}
437 
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);
441 		if (ret)
442 			goto err;
443 	}
444 
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);
449 		if (ret)
450 			goto err;
451 	}
452 
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))) {
457 		ret = -EXDEV;
458 		goto err;
459 	}
460 
461 	if (src_inode_u->bi_parent_subvol)
462 		src_inode_u->bi_parent_subvol = dst_dir.subvol;
463 
464 	if ((mode == BCH_RENAME_EXCHANGE) &&
465 	    dst_inode_u->bi_parent_subvol)
466 		dst_inode_u->bi_parent_subvol = src_dir.subvol;
467 
468 	src_inode_u->bi_dir		= dst_dir_u->bi_inum;
469 	src_inode_u->bi_dir_offset	= dst_offset;
470 
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;
474 	}
475 
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;
481 	}
482 
483 	if (mode == BCH_RENAME_OVERWRITE) {
484 		if (S_ISDIR(src_inode_u->bi_mode) !=
485 		    S_ISDIR(dst_inode_u->bi_mode)) {
486 			ret = -ENOTDIR;
487 			goto err;
488 		}
489 
490 		if (S_ISDIR(dst_inode_u->bi_mode)) {
491 			ret = bch2_empty_dir_trans(trans, dst_inum);
492 			if (ret)
493 				goto err;
494 		}
495 	}
496 
497 	if (bch2_reinherit_attrs(src_inode_u, dst_dir_u) &&
498 	    S_ISDIR(src_inode_u->bi_mode)) {
499 		ret = -EXDEV;
500 		goto err;
501 	}
502 
503 	if (mode == BCH_RENAME_EXCHANGE &&
504 	    bch2_reinherit_attrs(dst_inode_u, src_dir_u) &&
505 	    S_ISDIR(dst_inode_u->bi_mode)) {
506 		ret = -EXDEV;
507 		goto err;
508 	}
509 
510 	if (is_subdir_for_nlink(src_inode_u)) {
511 		src_dir_u->bi_nlink--;
512 		dst_dir_u->bi_nlink++;
513 	}
514 
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;
518 	}
519 
520 	if (mode == BCH_RENAME_OVERWRITE)
521 		bch2_inode_nlink_dec(trans, dst_inode_u);
522 
523 	src_dir_u->bi_mtime		= now;
524 	src_dir_u->bi_ctime		= now;
525 
526 	if (src_dir.inum != dst_dir.inum) {
527 		dst_dir_u->bi_mtime	= now;
528 		dst_dir_u->bi_ctime	= now;
529 	}
530 
531 	src_inode_u->bi_ctime		= now;
532 
533 	if (dst_inum.inum)
534 		dst_inode_u->bi_ctime	= now;
535 
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)
539 		 : 0) ?:
540 		bch2_inode_write(trans, &src_inode_iter, src_inode_u) ?:
541 		(dst_inum.inum
542 		 ? bch2_inode_write(trans, &dst_inode_iter, dst_inode_u)
543 		 : 0);
544 err:
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);
549 	return ret;
550 }
551