diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-06-28 03:02:27 +0200 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-01-06 05:24:19 +0100 |
commit | 6b00de06f51c5388f1a7eddd4ad7df8e3b8863b5 (patch) | |
tree | e80ec5da1fcaac8664c2b8e8788a0d76c172597c | |
parent | bcachefs: Fix nochanges/read_only interaction (diff) | |
download | linux-6b00de06f51c5388f1a7eddd4ad7df8e3b8863b5.tar.xz linux-6b00de06f51c5388f1a7eddd4ad7df8e3b8863b5.zip |
bcachefs: bch_member->seq
Add new fields for split brain detection:
- bch_member->seq, which tracks the sequence number of the last superblock
write that happened to each member device
- bch_sb->write_time, which tracks the time of the last superblock write,
to allow detection of when two members have diverged but had the same
number of superblock writes.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/bcachefs_format.h | 8 | ||||
-rw-r--r-- | fs/bcachefs/sb-members.c | 5 | ||||
-rw-r--r-- | fs/bcachefs/super-io.c | 11 |
3 files changed, 22 insertions, 2 deletions
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h index 2c09b40a15b9..eb2df422ae5a 100644 --- a/fs/bcachefs/bcachefs_format.h +++ b/fs/bcachefs/bcachefs_format.h @@ -1303,6 +1303,7 @@ struct bch_member { __le64 errors[BCH_MEMBER_ERROR_NR]; __le64 errors_at_reset[BCH_MEMBER_ERROR_NR]; __le64 errors_reset_time; + __le64 seq; }; #define BCH_MEMBER_V1_BYTES 56 @@ -1729,7 +1730,9 @@ struct bch_sb_field_downgrade { x(deleted_inodes, BCH_VERSION(1, 2), \ BIT_ULL(BCH_RECOVERY_PASS_check_inodes)) \ x(rebalance_work, BCH_VERSION(1, 3), \ - BIT_ULL(BCH_RECOVERY_PASS_set_fs_needs_rebalance)) + BIT_ULL(BCH_RECOVERY_PASS_set_fs_needs_rebalance)) \ + x(member_seq, BCH_VERSION(1, 4), \ + 0) enum bcachefs_metadata_version { bcachefs_metadata_version_min = 9, @@ -1795,7 +1798,8 @@ struct bch_sb { __le32 time_base_hi; __le32 time_precision; - __le64 flags[8]; + __le64 flags[7]; + __le64 write_time; __le64 features[2]; __le64 compat[2]; diff --git a/fs/bcachefs/sb-members.c b/fs/bcachefs/sb-members.c index 7c5db669a467..4c19a8096c1d 100644 --- a/fs/bcachefs/sb-members.c +++ b/fs/bcachefs/sb-members.c @@ -235,6 +235,11 @@ static void member_to_text(struct printbuf *out, prt_printf(out, "(never)"); prt_newline(out); + prt_printf(out, "Last superblock write:"); + prt_tab(out); + prt_u64(out, le64_to_cpu(m.seq)); + prt_newline(out); + prt_printf(out, "State:"); prt_tab(out); prt_printf(out, "%s", diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index 89d2d2a86eb0..aee3c634f4af 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -564,6 +564,7 @@ static int __copy_super(struct bch_sb_handle *dst_handle, struct bch_sb *src) dst->time_base_lo = src->time_base_lo; dst->time_base_hi = src->time_base_hi; dst->time_precision = src->time_precision; + dst->write_time = src->write_time; memcpy(dst->flags, src->flags, sizeof(dst->flags)); memcpy(dst->features, src->features, sizeof(dst->features)); @@ -942,6 +943,11 @@ int bch2_write_super(struct bch_fs *c) le64_add_cpu(&c->disk_sb.sb->seq, 1); + struct bch_sb_field_members_v2 *mi = bch2_sb_field_get(c->disk_sb.sb, members_v2); + for_each_online_member(c, ca) + __bch2_members_v2_get_mut(mi, ca->dev_idx)->seq = c->disk_sb.sb->seq; + c->disk_sb.sb->write_time = cpu_to_le64(ktime_get_real_seconds()); + if (test_bit(BCH_FS_error, &c->flags)) SET_BCH_SB_HAS_ERRORS(c->disk_sb.sb, 1); if (test_bit(BCH_FS_topology_error, &c->flags)) @@ -1304,6 +1310,11 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb, prt_printf(out, "%llu", le64_to_cpu(sb->seq)); prt_newline(out); + prt_printf(out, "Time of last write:"); + prt_tab(out); + bch2_prt_datetime(out, le64_to_cpu(sb->write_time)); + prt_newline(out); + prt_printf(out, "Superblock size:"); prt_tab(out); prt_printf(out, "%zu", vstruct_bytes(sb)); |