summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-02-10 21:06:20 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2024-02-10 21:06:20 -0500
commit9866af841efddf6a8e56a5993fedc00cb65a0500 (patch)
tree64d0346e49c1d28238ad659749f36943c96e4898
parent7a716b76b5963dc2d158883f4497bab221932412 (diff)
Update bcachefs sources to 39a84c99af2d bcachefs: Clamp replicas_required to replicas
-rw-r--r--.bcachefs_revision2
-rw-r--r--libbcachefs/bcachefs.h12
-rw-r--r--libbcachefs/bcachefs_format.h15
-rw-r--r--libbcachefs/btree_types.h11
-rw-r--r--libbcachefs/btree_update.c3
-rw-r--r--libbcachefs/btree_update_interior.c3
-rw-r--r--libbcachefs/fs-common.c31
-rw-r--r--libbcachefs/fs.c2
-rw-r--r--libbcachefs/fsck.c8
-rw-r--r--libbcachefs/io_write.c1
-rw-r--r--libbcachefs/journal_io.c4
-rw-r--r--libbcachefs/journal_reclaim.c2
-rw-r--r--libbcachefs/sb-members.c2
-rw-r--r--libbcachefs/super-io.c2
-rw-r--r--libbcachefs/super.c4
15 files changed, 82 insertions, 20 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision
index 1aa1789b..e94031fa 100644
--- a/.bcachefs_revision
+++ b/.bcachefs_revision
@@ -1 +1 @@
-bee7b5a4fa2135c9ec9d1c9424018ee494500bb5
+39a84c99af2dbbd797eb2f0d1bed04111f04f245
diff --git a/libbcachefs/bcachefs.h b/libbcachefs/bcachefs.h
index b53b321b..3b48c5e1 100644
--- a/libbcachefs/bcachefs.h
+++ b/libbcachefs/bcachefs.h
@@ -1249,6 +1249,18 @@ static inline struct stdio_redirect *bch2_fs_stdio_redirect(struct bch_fs *c)
return stdio;
}
+static inline unsigned metadata_replicas_required(struct bch_fs *c)
+{
+ return min(c->opts.metadata_replicas,
+ c->opts.metadata_replicas_required);
+}
+
+static inline unsigned data_replicas_required(struct bch_fs *c)
+{
+ return min(c->opts.data_replicas,
+ c->opts.data_replicas_required);
+}
+
#define BKEY_PADDED_ONSTACK(key, pad) \
struct { struct bkey_i key; __u64 key ## _pad[pad]; }
diff --git a/libbcachefs/bcachefs_format.h b/libbcachefs/bcachefs_format.h
index 1bb24aa7..20604e27 100644
--- a/libbcachefs/bcachefs_format.h
+++ b/libbcachefs/bcachefs_format.h
@@ -1426,14 +1426,17 @@ LE32_BITMASK(JSET_NO_FLUSH, struct jset, flags, 5, 6);
/* Btree: */
enum btree_id_flags {
- BTREE_ID_EXTENTS = BIT(0),
- BTREE_ID_SNAPSHOTS = BIT(1),
- BTREE_ID_SNAPSHOT_FIELD = BIT(2),
- BTREE_ID_DATA = BIT(3),
+ /* key size field is nonzero, btree iterators handle as ranges */
+ BTREE_ID_EXTENTS = BIT(0),
+ BTREE_ID_SNAPSHOTS = BIT(1),
+ BTREE_ID_SNAPSHOT_FIELD = BIT(2),
+ BTREE_ID_SNAPSHOTS_UNREFFED = BIT(3),
+ BTREE_ID_DATA = BIT(3),
};
#define BCH_BTREE_IDS() \
- x(extents, 0, BTREE_ID_EXTENTS|BTREE_ID_SNAPSHOTS|BTREE_ID_DATA,\
+ x(extents, 0, BTREE_ID_EXTENTS|BTREE_ID_SNAPSHOTS| \
+ BTREE_ID_SNAPSHOTS_UNREFFED|BTREE_ID_DATA,\
BIT_ULL(KEY_TYPE_whiteout)| \
BIT_ULL(KEY_TYPE_error)| \
BIT_ULL(KEY_TYPE_cookie)| \
@@ -1451,7 +1454,7 @@ enum btree_id_flags {
BIT_ULL(KEY_TYPE_whiteout)| \
BIT_ULL(KEY_TYPE_hash_whiteout)| \
BIT_ULL(KEY_TYPE_dirent)) \
- x(xattrs, 3, BTREE_ID_SNAPSHOTS, \
+ x(xattrs, 3, BTREE_ID_SNAPSHOTS|BTREE_ID_SNAPSHOTS_UNREFFED,\
BIT_ULL(KEY_TYPE_whiteout)| \
BIT_ULL(KEY_TYPE_cookie)| \
BIT_ULL(KEY_TYPE_hash_whiteout)| \
diff --git a/libbcachefs/btree_types.h b/libbcachefs/btree_types.h
index b2ebf143..0791531b 100644
--- a/libbcachefs/btree_types.h
+++ b/libbcachefs/btree_types.h
@@ -705,6 +705,17 @@ static inline bool btree_type_has_snapshots(enum btree_id id)
return (1U << id) & mask;
}
+static inline bool btree_type_snapshots_unreffed(enum btree_id id)
+{
+ const unsigned mask = 0
+#define x(name, nr, flags, ...) |((!!((flags) & BTREE_ID_SNAPSHOTS_UNREFFED)) << nr)
+ BCH_BTREE_IDS()
+#undef x
+ ;
+
+ return (1U << id) & mask;
+}
+
static inline bool btree_type_has_snapshot_field(enum btree_id id)
{
const unsigned mask = 0
diff --git a/libbcachefs/btree_update.c b/libbcachefs/btree_update.c
index d3d625d4..ac852310 100644
--- a/libbcachefs/btree_update.c
+++ b/libbcachefs/btree_update.c
@@ -217,7 +217,8 @@ overwrite_interior_snapshot_key(struct btree_trans *trans,
return ret;
if (!bkey_deleted(old.k)) {
- if (old.k->p.snapshot != k->k.p.snapshot) {
+ if (btree_type_snapshots_unreffed(iter->btree_id) &&
+ old.k->p.snapshot != k->k.p.snapshot) {
/*
* We're overwriting a key in a different snapshot:
* check if it's also been overwritten in siblings
diff --git a/libbcachefs/btree_update_interior.c b/libbcachefs/btree_update_interior.c
index 5fbea33f..70da4fa2 100644
--- a/libbcachefs/btree_update_interior.c
+++ b/libbcachefs/btree_update_interior.c
@@ -280,7 +280,8 @@ retry:
writepoint_ptr(&c->btree_write_point),
&devs_have,
res->nr_replicas,
- c->opts.metadata_replicas_required,
+ min(res->nr_replicas,
+ c->opts.metadata_replicas_required),
watermark, 0, cl, &wp);
if (unlikely(ret))
return ERR_PTR(ret);
diff --git a/libbcachefs/fs-common.c b/libbcachefs/fs-common.c
index 3d43c036..255857ca 100644
--- a/libbcachefs/fs-common.c
+++ b/libbcachefs/fs-common.c
@@ -357,6 +357,22 @@ bool bch2_reinherit_attrs(struct bch_inode_unpacked *dst_u,
return ret;
}
+static int subvol_update_parent(struct btree_trans *trans, u32 subvol, u32 new_parent)
+{
+ struct btree_iter iter;
+ struct bkey_i_subvolume *s =
+ bch2_bkey_get_mut_typed(trans, &iter,
+ BTREE_ID_subvolumes, POS(0, subvol),
+ BTREE_ITER_CACHED, subvolume);
+ int ret = PTR_ERR_OR_ZERO(s);
+ if (ret)
+ return ret;
+
+ s->v.fs_path_parent = cpu_to_le32(new_parent);
+ bch2_trans_iter_exit(trans, &iter);
+ return 0;
+}
+
int bch2_rename_trans(struct btree_trans *trans,
subvol_inum src_dir, struct bch_inode_unpacked *src_dir_u,
subvol_inum dst_dir, struct bch_inode_unpacked *dst_dir_u,
@@ -418,6 +434,21 @@ int bch2_rename_trans(struct btree_trans *trans,
goto err;
}
+ if (src_inode_u->bi_subvol &&
+ dst_dir.subvol != src_inode_u->bi_parent_subvol) {
+ ret = subvol_update_parent(trans, src_inode_u->bi_subvol, dst_dir.subvol);
+ if (ret)
+ goto err;
+ }
+
+ if (mode == BCH_RENAME_EXCHANGE &&
+ dst_inode_u->bi_subvol &&
+ src_dir.subvol != dst_inode_u->bi_parent_subvol) {
+ ret = subvol_update_parent(trans, dst_inode_u->bi_subvol, src_dir.subvol);
+ if (ret)
+ goto err;
+ }
+
/* Can't move across subvolumes, unless it's a subvolume root: */
if (src_dir.subvol != dst_dir.subvol &&
(!src_inode_u->bi_subvol ||
diff --git a/libbcachefs/fs.c b/libbcachefs/fs.c
index 4445fa2f..093f5404 100644
--- a/libbcachefs/fs.c
+++ b/libbcachefs/fs.c
@@ -710,7 +710,7 @@ err:
src_inode,
dst_inode);
- return ret;
+ return bch2_err_class(ret);
}
static void bch2_setattr_copy(struct mnt_idmap *idmap,
diff --git a/libbcachefs/fsck.c b/libbcachefs/fsck.c
index dfd54708..3f74b676 100644
--- a/libbcachefs/fsck.c
+++ b/libbcachefs/fsck.c
@@ -1699,10 +1699,10 @@ static int check_dirent_target(struct btree_trans *trans,
bkey_reassemble(&n->k_i, d.s_c);
n->v.d_type = inode_d_type(target);
if (n->v.d_type == DT_SUBVOL) {
- n->v.d_parent_subvol = target->bi_parent_subvol;
- n->v.d_child_subvol = target->bi_subvol;
+ n->v.d_parent_subvol = cpu_to_le32(target->bi_parent_subvol);
+ n->v.d_child_subvol = cpu_to_le32(target->bi_subvol);
} else {
- n->v.d_inum = target->bi_inum;
+ n->v.d_inum = cpu_to_le64(target->bi_inum);
}
ret = bch2_trans_update(trans, iter, &n->k_i, 0);
@@ -1809,7 +1809,7 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter *
if (ret)
goto err;
- n->v.fs_path_parent = le32_to_cpu(parent_subvol);
+ n->v.fs_path_parent = cpu_to_le32(parent_subvol);
}
u64 target_inum = le64_to_cpu(s.v->inode);
diff --git a/libbcachefs/io_write.c b/libbcachefs/io_write.c
index 13b3514d..3fa2cb1d 100644
--- a/libbcachefs/io_write.c
+++ b/libbcachefs/io_write.c
@@ -1564,6 +1564,7 @@ CLOSURE_CALLBACK(bch2_write)
BUG_ON(!op->write_point.v);
BUG_ON(bkey_eq(op->pos, POS_MAX));
+ op->nr_replicas_required = min_t(unsigned, op->nr_replicas_required, op->nr_replicas);
op->start_time = local_clock();
bch2_keylist_init(&op->insert_keys, op->inline_keys);
wbio_init(bio)->put_bio = false;
diff --git a/libbcachefs/journal_io.c b/libbcachefs/journal_io.c
index e31e215f..057e7c61 100644
--- a/libbcachefs/journal_io.c
+++ b/libbcachefs/journal_io.c
@@ -1506,6 +1506,8 @@ static int journal_write_alloc(struct journal *j, struct journal_buf *w)
c->opts.foreground_target;
unsigned i, replicas = 0, replicas_want =
READ_ONCE(c->opts.metadata_replicas);
+ unsigned replicas_need = min(replicas_want,
+ READ_ONCE(c->opts.metadata_replicas_required));
rcu_read_lock();
retry:
@@ -1554,7 +1556,7 @@ done:
BUG_ON(bkey_val_u64s(&w->key.k) > BCH_REPLICAS_MAX);
- return replicas >= c->opts.metadata_replicas_required ? 0 : -EROFS;
+ return replicas >= replicas_need ? 0 : -EROFS;
}
static void journal_buf_realloc(struct journal *j, struct journal_buf *buf)
diff --git a/libbcachefs/journal_reclaim.c b/libbcachefs/journal_reclaim.c
index f29fd397..a7155081 100644
--- a/libbcachefs/journal_reclaim.c
+++ b/libbcachefs/journal_reclaim.c
@@ -202,7 +202,7 @@ void bch2_journal_space_available(struct journal *j)
j->can_discard = can_discard;
- if (nr_online < c->opts.metadata_replicas_required) {
+ if (nr_online < metadata_replicas_required(c)) {
ret = JOURNAL_ERR_insufficient_devices;
goto out;
}
diff --git a/libbcachefs/sb-members.c b/libbcachefs/sb-members.c
index a45354d2..eff5ce18 100644
--- a/libbcachefs/sb-members.c
+++ b/libbcachefs/sb-members.c
@@ -421,7 +421,7 @@ void bch2_dev_errors_reset(struct bch_dev *ca)
m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
for (unsigned i = 0; i < ARRAY_SIZE(m->errors_at_reset); i++)
m->errors_at_reset[i] = cpu_to_le64(atomic64_read(&ca->errors[i]));
- m->errors_reset_time = ktime_get_real_seconds();
+ m->errors_reset_time = cpu_to_le64(ktime_get_real_seconds());
bch2_write_super(c);
mutex_unlock(&c->sb_lock);
diff --git a/libbcachefs/super-io.c b/libbcachefs/super-io.c
index d60c7d27..36988add 100644
--- a/libbcachefs/super-io.c
+++ b/libbcachefs/super-io.c
@@ -717,7 +717,7 @@ retry:
if (IS_ERR(sb->bdev_handle)) {
ret = PTR_ERR(sb->bdev_handle);
- goto out;
+ goto err;
}
sb->bdev = sb->bdev_handle->bdev;
diff --git a/libbcachefs/super.c b/libbcachefs/super.c
index 68704a86..8c6caebf 100644
--- a/libbcachefs/super.c
+++ b/libbcachefs/super.c
@@ -1423,10 +1423,10 @@ bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca,
required = max(!(flags & BCH_FORCE_IF_METADATA_DEGRADED)
? c->opts.metadata_replicas
- : c->opts.metadata_replicas_required,
+ : metadata_replicas_required(c),
!(flags & BCH_FORCE_IF_DATA_DEGRADED)
? c->opts.data_replicas
- : c->opts.data_replicas_required);
+ : data_replicas_required(c));
return nr_rw >= required;
case BCH_MEMBER_STATE_failed: