Skip to content

Commit 6fed42b

Browse files
koverstreetKent Overstreet
authored andcommitted
bcachefs: Plumb through subvolume id
To implement snapshots, we need every filesystem btree operation (every btree operation without a subvolume) to start by looking up the subvolume and getting the current snapshot ID, with bch2_subvolume_get_snapshot() - then, that snapshot ID is used for doing btree lookups in BTREE_ITER_FILTER_SNAPSHOTS mode. This patch adds those bch2_subvolume_get_snapshot() calls, and also switches to passing around a subvol_inum instead of just an inode number. Signed-off-by: Kent Overstreet <[email protected]>
1 parent c075ff7 commit 6fed42b

23 files changed

+526
-256
lines changed

fs/bcachefs/acl.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ struct posix_acl *bch2_get_acl(struct mnt_idmap *idmap,
230230
bch2_trans_begin(&trans);
231231

232232
ret = bch2_hash_lookup(&trans, &iter, bch2_xattr_hash_desc,
233-
&hash, inode->v.i_ino,
233+
&hash, inode_inum(inode),
234234
&X_SEARCH(acl_to_xattr_type(type), "", 0),
235235
0);
236236
if (ret) {
@@ -260,11 +260,11 @@ struct posix_acl *bch2_get_acl(struct mnt_idmap *idmap,
260260
return acl;
261261
}
262262

263-
int bch2_set_acl_trans(struct btree_trans *trans,
263+
int bch2_set_acl_trans(struct btree_trans *trans, subvol_inum inum,
264264
struct bch_inode_unpacked *inode_u,
265-
const struct bch_hash_info *hash_info,
266265
struct posix_acl *acl, int type)
267266
{
267+
struct bch_hash_info hash_info = bch2_hash_info_init(trans->c, inode_u);
268268
int ret;
269269

270270
if (type == ACL_TYPE_DEFAULT &&
@@ -277,14 +277,14 @@ int bch2_set_acl_trans(struct btree_trans *trans,
277277
if (IS_ERR(xattr))
278278
return PTR_ERR(xattr);
279279

280-
ret = bch2_hash_set(trans, bch2_xattr_hash_desc, hash_info,
281-
inode_u->bi_inum, &xattr->k_i, 0);
280+
ret = bch2_hash_set(trans, bch2_xattr_hash_desc, &hash_info,
281+
inum, &xattr->k_i, 0);
282282
} else {
283283
struct xattr_search_key search =
284284
X_SEARCH(acl_to_xattr_type(type), "", 0);
285285

286-
ret = bch2_hash_delete(trans, bch2_xattr_hash_desc, hash_info,
287-
inode_u->bi_inum, &search);
286+
ret = bch2_hash_delete(trans, bch2_xattr_hash_desc, &hash_info,
287+
inum, &search);
288288
}
289289

290290
return ret == -ENOENT ? 0 : ret;
@@ -299,7 +299,6 @@ int bch2_set_acl(struct mnt_idmap *idmap,
299299
struct btree_trans trans;
300300
struct btree_iter inode_iter = { NULL };
301301
struct bch_inode_unpacked inode_u;
302-
struct bch_hash_info hash_info;
303302
struct posix_acl *acl;
304303
umode_t mode;
305304
int ret;
@@ -310,7 +309,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
310309
bch2_trans_begin(&trans);
311310
acl = _acl;
312311

313-
ret = bch2_inode_peek(&trans, &inode_iter, &inode_u, inode->v.i_ino,
312+
ret = bch2_inode_peek(&trans, &inode_iter, &inode_u, inode_inum(inode),
314313
BTREE_ITER_INTENT);
315314
if (ret)
316315
goto btree_err;
@@ -323,9 +322,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
323322
goto btree_err;
324323
}
325324

326-
hash_info = bch2_hash_info_init(c, &inode_u);
327-
328-
ret = bch2_set_acl_trans(&trans, &inode_u, &hash_info, acl, type);
325+
ret = bch2_set_acl_trans(&trans, inode_inum(inode), &inode_u, acl, type);
329326
if (ret)
330327
goto btree_err;
331328

@@ -354,7 +351,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
354351
return ret;
355352
}
356353

357-
int bch2_acl_chmod(struct btree_trans *trans,
354+
int bch2_acl_chmod(struct btree_trans *trans, subvol_inum inum,
358355
struct bch_inode_unpacked *inode,
359356
umode_t mode,
360357
struct posix_acl **new_acl)
@@ -368,7 +365,7 @@ int bch2_acl_chmod(struct btree_trans *trans,
368365
int ret;
369366

370367
ret = bch2_hash_lookup(trans, &iter, bch2_xattr_hash_desc,
371-
&hash_info, inode->bi_inum,
368+
&hash_info, inum,
372369
&X_SEARCH(KEY_TYPE_XATTR_INDEX_POSIX_ACL_ACCESS, "", 0),
373370
BTREE_ITER_INTENT);
374371
if (ret)

fs/bcachefs/acl.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,24 @@ typedef struct {
2828

2929
struct posix_acl *bch2_get_acl(struct mnt_idmap *, struct dentry *, int);
3030

31-
int bch2_set_acl_trans(struct btree_trans *,
31+
int bch2_set_acl_trans(struct btree_trans *, subvol_inum,
3232
struct bch_inode_unpacked *,
33-
const struct bch_hash_info *,
3433
struct posix_acl *, int);
3534
int bch2_set_acl(struct mnt_idmap *, struct dentry *, struct posix_acl *, int);
36-
int bch2_acl_chmod(struct btree_trans *, struct bch_inode_unpacked *,
35+
int bch2_acl_chmod(struct btree_trans *, subvol_inum,
36+
struct bch_inode_unpacked *,
3737
umode_t, struct posix_acl **);
3838

3939
#else
4040

41-
static inline int bch2_set_acl_trans(struct btree_trans *trans,
41+
static inline int bch2_set_acl_trans(struct btree_trans *trans, subvol_inum inum,
4242
struct bch_inode_unpacked *inode_u,
43-
const struct bch_hash_info *hash_info,
4443
struct posix_acl *acl, int type)
4544
{
4645
return 0;
4746
}
4847

49-
static inline int bch2_acl_chmod(struct btree_trans *trans,
48+
static inline int bch2_acl_chmod(struct btree_trans *trans, subvol_inum inum,
5049
struct bch_inode_unpacked *inode,
5150
umode_t mode,
5251
struct posix_acl **new_acl)

fs/bcachefs/dirent.c

Lines changed: 72 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "fs.h"
99
#include "keylist.h"
1010
#include "str_hash.h"
11+
#include "subvolume.h"
1112

1213
#include <linux/dcache.h>
1314

@@ -150,8 +151,8 @@ static struct bkey_i_dirent *dirent_create_key(struct btree_trans *trans,
150151
return dirent;
151152
}
152153

153-
int bch2_dirent_create(struct btree_trans *trans,
154-
u64 dir_inum, const struct bch_hash_info *hash_info,
154+
int bch2_dirent_create(struct btree_trans *trans, subvol_inum dir,
155+
const struct bch_hash_info *hash_info,
155156
u8 type, const struct qstr *name, u64 dst_inum,
156157
u64 *dir_offset, int flags)
157158
{
@@ -164,7 +165,7 @@ int bch2_dirent_create(struct btree_trans *trans,
164165
return ret;
165166

166167
ret = bch2_hash_set(trans, bch2_dirent_hash_desc, hash_info,
167-
dir_inum, &dirent->k_i, flags);
168+
dir, &dirent->k_i, flags);
168169
*dir_offset = dirent->k.p.offset;
169170

170171
return ret;
@@ -223,31 +224,40 @@ int __bch2_dirent_read_target(struct btree_trans *trans,
223224
return ret;
224225
}
225226

226-
int bch2_dirent_read_target(struct btree_trans *trans,
227-
struct bkey_s_c_dirent d, u64 *target)
227+
static int bch2_dirent_read_target(struct btree_trans *trans, subvol_inum dir,
228+
struct bkey_s_c_dirent d, subvol_inum *target)
228229
{
229-
u32 subvol, snapshot;
230+
u32 snapshot;
231+
int ret = 0;
230232

231-
return __bch2_dirent_read_target(trans, d, &subvol,
232-
&snapshot, target, false);
233+
ret = __bch2_dirent_read_target(trans, d, &target->subvol, &snapshot,
234+
&target->inum, false);
235+
if (!target->subvol)
236+
target->subvol = dir.subvol;
237+
238+
return ret;
233239
}
234240

235241
int bch2_dirent_rename(struct btree_trans *trans,
236-
u64 src_dir, struct bch_hash_info *src_hash,
237-
u64 dst_dir, struct bch_hash_info *dst_hash,
238-
const struct qstr *src_name, u64 *src_inum, u64 *src_offset,
239-
const struct qstr *dst_name, u64 *dst_inum, u64 *dst_offset,
240-
enum bch_rename_mode mode)
242+
subvol_inum src_dir, struct bch_hash_info *src_hash,
243+
subvol_inum dst_dir, struct bch_hash_info *dst_hash,
244+
const struct qstr *src_name, subvol_inum *src_inum, u64 *src_offset,
245+
const struct qstr *dst_name, subvol_inum *dst_inum, u64 *dst_offset,
246+
enum bch_rename_mode mode)
241247
{
242248
struct btree_iter src_iter = { NULL };
243249
struct btree_iter dst_iter = { NULL };
244250
struct bkey_s_c old_src, old_dst;
245251
struct bkey_i_dirent *new_src = NULL, *new_dst = NULL;
246252
struct bpos dst_pos =
247-
POS(dst_dir, bch2_dirent_hash(dst_hash, dst_name));
253+
POS(dst_dir.inum, bch2_dirent_hash(dst_hash, dst_name));
248254
int ret = 0;
249255

250-
*src_inum = *dst_inum = 0;
256+
if (src_dir.subvol != dst_dir.subvol)
257+
return -EXDEV;
258+
259+
memset(src_inum, 0, sizeof(*src_inum));
260+
memset(dst_inum, 0, sizeof(*dst_inum));
251261

252262
/*
253263
* Lookup dst:
@@ -270,8 +280,12 @@ int bch2_dirent_rename(struct btree_trans *trans,
270280
if (ret)
271281
goto out;
272282

273-
if (mode != BCH_RENAME)
274-
*dst_inum = le64_to_cpu(bkey_s_c_to_dirent(old_dst).v->d_inum);
283+
if (mode != BCH_RENAME) {
284+
ret = bch2_dirent_read_target(trans, dst_dir,
285+
bkey_s_c_to_dirent(old_dst), dst_inum);
286+
if (ret)
287+
goto out;
288+
}
275289
if (mode != BCH_RENAME_EXCHANGE)
276290
*src_offset = dst_iter.pos.offset;
277291

@@ -287,7 +301,10 @@ int bch2_dirent_rename(struct btree_trans *trans,
287301
if (ret)
288302
goto out;
289303

290-
*src_inum = le64_to_cpu(bkey_s_c_to_dirent(old_src).v->d_inum);
304+
ret = bch2_dirent_read_target(trans, src_dir,
305+
bkey_s_c_to_dirent(old_src), src_inum);
306+
if (ret)
307+
goto out;
291308

292309
/* Create new dst key: */
293310
new_dst = dirent_create_key(trans, 0, dst_name, 0);
@@ -376,17 +393,22 @@ int bch2_dirent_delete_at(struct btree_trans *trans,
376393

377394
int __bch2_dirent_lookup_trans(struct btree_trans *trans,
378395
struct btree_iter *iter,
379-
u64 dir_inum,
396+
subvol_inum dir,
380397
const struct bch_hash_info *hash_info,
381-
const struct qstr *name, u64 *inum,
398+
const struct qstr *name, subvol_inum *inum,
382399
unsigned flags)
383400
{
384401
struct bkey_s_c k;
385402
struct bkey_s_c_dirent d;
403+
u32 snapshot;
386404
int ret;
387405

406+
ret = bch2_subvolume_get_snapshot(trans, dir.subvol, &snapshot);
407+
if (ret)
408+
return ret;
409+
388410
ret = bch2_hash_lookup(trans, iter, bch2_dirent_hash_desc,
389-
hash_info, dir_inum, name, flags);
411+
hash_info, dir, name, flags);
390412
if (ret)
391413
return ret;
392414

@@ -399,44 +421,49 @@ int __bch2_dirent_lookup_trans(struct btree_trans *trans,
399421

400422
d = bkey_s_c_to_dirent(k);
401423

402-
ret = bch2_dirent_read_target(trans, d, inum);
424+
ret = bch2_dirent_read_target(trans, dir, d, inum);
403425
if (ret)
404426
bch2_trans_iter_exit(trans, iter);
405427

406428
return ret;
407429
}
408430

409-
u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
431+
u64 bch2_dirent_lookup(struct bch_fs *c, subvol_inum dir,
410432
const struct bch_hash_info *hash_info,
411-
const struct qstr *name)
433+
const struct qstr *name, subvol_inum *inum)
412434
{
413435
struct btree_trans trans;
414436
struct btree_iter iter;
415-
u64 inum = 0;
416-
int ret = 0;
437+
int ret;
417438

418439
bch2_trans_init(&trans, c, 0, 0);
419440
retry:
420441
bch2_trans_begin(&trans);
421-
ret = __bch2_dirent_lookup_trans(&trans, &iter, dir_inum, hash_info,
422-
name, &inum, 0);
442+
443+
ret = __bch2_dirent_lookup_trans(&trans, &iter, dir, hash_info,
444+
name, inum, 0);
423445

424446
bch2_trans_iter_exit(&trans, &iter);
425447
if (ret == -EINTR)
426448
goto retry;
427449
bch2_trans_exit(&trans);
428-
return inum;
450+
return ret;
429451
}
430452

431-
int bch2_empty_dir_trans(struct btree_trans *trans, u64 dir_inum)
453+
int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
432454
{
433455
struct btree_iter iter;
434456
struct bkey_s_c k;
457+
u32 snapshot;
435458
int ret;
436459

460+
ret = bch2_subvolume_get_snapshot(trans, dir.subvol, &snapshot);
461+
if (ret)
462+
return ret;
463+
437464
for_each_btree_key(trans, iter, BTREE_ID_dirents,
438-
POS(dir_inum, 0), 0, k, ret) {
439-
if (k.k->p.inode > dir_inum)
465+
SPOS(dir.inum, 0, snapshot), 0, k, ret) {
466+
if (k.k->p.inode > dir.inum)
440467
break;
441468

442469
if (k.k->type == KEY_TYPE_dirent) {
@@ -449,19 +476,26 @@ int bch2_empty_dir_trans(struct btree_trans *trans, u64 dir_inum)
449476
return ret;
450477
}
451478

452-
int bch2_readdir(struct bch_fs *c, u64 inum, struct dir_context *ctx)
479+
int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
453480
{
454481
struct btree_trans trans;
455482
struct btree_iter iter;
456483
struct bkey_s_c k;
457484
struct bkey_s_c_dirent dirent;
485+
u32 snapshot;
458486
int ret;
459487

460488
bch2_trans_init(&trans, c, 0, 0);
489+
retry:
490+
bch2_trans_begin(&trans);
491+
492+
ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
493+
if (ret)
494+
goto err;
461495

462496
for_each_btree_key(&trans, iter, BTREE_ID_dirents,
463-
POS(inum, ctx->pos), 0, k, ret) {
464-
if (k.k->p.inode > inum)
497+
SPOS(inum.inum, ctx->pos, snapshot), 0, k, ret) {
498+
if (k.k->p.inode > inum.inum)
465499
break;
466500

467501
if (k.k->type != KEY_TYPE_dirent)
@@ -482,6 +516,9 @@ int bch2_readdir(struct bch_fs *c, u64 inum, struct dir_context *ctx)
482516
ctx->pos = dirent.k->p.offset + 1;
483517
}
484518
bch2_trans_iter_exit(&trans, &iter);
519+
err:
520+
if (ret == -EINTR)
521+
goto retry;
485522

486523
ret = bch2_trans_exit(&trans) ?: ret;
487524

0 commit comments

Comments
 (0)