All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] bcachefs: byte order swap bch_alloc_v4.fragmentation_lru field
@ 2023-10-09 12:20 Brian Foster
  2023-10-09 14:28 ` [PATCH 2/2] bcachefs: use swab40 for bch_backpointer.bucket_offset bitfield Brian Foster
  0 siblings, 1 reply; 2+ messages in thread
From: Brian Foster @ 2023-10-09 12:20 UTC (permalink / raw)
  To: linux-bcachefs

A simple test to populate a filesystem on one CPU architecture and
fsck on an arch of the opposite byte order produces errors related
to the fragmentation LRU. This occurs because the 64-bit
fragmentation_lru field is not byte-order swapped when reads detect
that the on-disk/bset key values were written in opposite byte-order
of the current CPU.

Update the bch2_alloc_v4 swab callback to handle fragmentation_lru
as is done for other multi-byte fields. This doesn't affect existing
filesystems when accessed by CPUs of the same endianness because the
->swab() callback is only called when the bset flags indicate an
endianness mismatch between the CPU and on-disk data.

Signed-off-by: Brian Foster <bfoster@redhat.com>
---

Pushed to my CI branch as well (on top of the writeback fix I sent a few
days or so ago...):

  https://evilpiepirate.org/~testdashboard/ci?branch=bfoster

Brian

 fs/bcachefs/alloc_background.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index d1c323fd3f0b..26b19ccad89b 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -324,6 +324,7 @@ void bch2_alloc_v4_swab(struct bkey_s k)
 	a->io_time[1]		= swab64(a->io_time[1]);
 	a->stripe		= swab32(a->stripe);
 	a->nr_external_backpointers = swab32(a->nr_external_backpointers);
+	a->fragmentation_lru	= swab64(a->fragmentation_lru);
 
 	bps = alloc_v4_backpointers(a);
 	for (bp = bps; bp < bps + BCH_ALLOC_V4_NR_BACKPOINTERS(a); bp++) {
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] bcachefs: use swab40 for bch_backpointer.bucket_offset bitfield
  2023-10-09 12:20 [PATCH] bcachefs: byte order swap bch_alloc_v4.fragmentation_lru field Brian Foster
@ 2023-10-09 14:28 ` Brian Foster
  0 siblings, 0 replies; 2+ messages in thread
From: Brian Foster @ 2023-10-09 14:28 UTC (permalink / raw)
  To: linux-bcachefs

The bucket_offset field of bch_backpointer is a 40-bit bitfield, but the
bch2_backpointer_swab() helper uses swab32. This leads to inconsistency
when an on-disk fs is accessed from an opposite endian machine.

As it turns out, we already have an internal swab40() helper that is
used from the bch_alloc_v4 swab callback. Lift it into the backpointers
header file and use it consistently in both places.

Signed-off-by: Brian Foster <bfoster@redhat.com>
---

Here's another one I just tacked on that seems to address the
backpointer related problems when switching CPU byte order...

Brian

 fs/bcachefs/alloc_background.c | 9 ---------
 fs/bcachefs/backpointers.c     | 2 +-
 fs/bcachefs/backpointers.h     | 9 +++++++++
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index 26b19ccad89b..6380de7cd90f 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -302,15 +302,6 @@ int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k,
 	return 0;
 }
 
-static inline u64 swab40(u64 x)
-{
-	return (((x & 0x00000000ffULL) << 32)|
-		((x & 0x000000ff00ULL) << 16)|
-		((x & 0x0000ff0000ULL) >>  0)|
-		((x & 0x00ff000000ULL) >> 16)|
-		((x & 0xff00000000ULL) >> 32));
-}
-
 void bch2_alloc_v4_swab(struct bkey_s k)
 {
 	struct bch_alloc_v4 *a = bkey_s_to_alloc_v4(k).v;
diff --git a/fs/bcachefs/backpointers.c b/fs/bcachefs/backpointers.c
index cc856150a948..b9955f937657 100644
--- a/fs/bcachefs/backpointers.c
+++ b/fs/bcachefs/backpointers.c
@@ -76,7 +76,7 @@ void bch2_backpointer_swab(struct bkey_s k)
 {
 	struct bkey_s_backpointer bp = bkey_s_to_backpointer(k);
 
-	bp.v->bucket_offset	= swab32(bp.v->bucket_offset);
+	bp.v->bucket_offset	= swab40(bp.v->bucket_offset);
 	bp.v->bucket_len	= swab32(bp.v->bucket_len);
 	bch2_bpos_swab(&bp.v->pos);
 }
diff --git a/fs/bcachefs/backpointers.h b/fs/bcachefs/backpointers.h
index 547e0617602a..b0006e656f3a 100644
--- a/fs/bcachefs/backpointers.h
+++ b/fs/bcachefs/backpointers.h
@@ -7,6 +7,15 @@
 #include "buckets.h"
 #include "super.h"
 
+static inline u64 swab40(u64 x)
+{
+	return (((x & 0x00000000ffULL) << 32)|
+		((x & 0x000000ff00ULL) << 16)|
+		((x & 0x0000ff0000ULL) >>  0)|
+		((x & 0x00ff000000ULL) >> 16)|
+		((x & 0xff00000000ULL) >> 32));
+}
+
 int bch2_backpointer_invalid(const struct bch_fs *, struct bkey_s_c k,
 			     enum bkey_invalid_flags, struct printbuf *);
 void bch2_backpointer_to_text(struct printbuf *, const struct bch_backpointer *);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-10-09 14:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-09 12:20 [PATCH] bcachefs: byte order swap bch_alloc_v4.fragmentation_lru field Brian Foster
2023-10-09 14:28 ` [PATCH 2/2] bcachefs: use swab40 for bch_backpointer.bucket_offset bitfield Brian Foster

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.