[Concept,01/14] linux: ext4l: Fix REQ_OP and BH_OwnsData bit positions

Message ID 20251230205157.3383926-2-sjg@u-boot.org
State New
Headers
Series ext4l: Linux adaptation patches for ext4 write support |

Commit Message

Simon Glass Dec. 30, 2025, 8:51 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

The REQ_OP flags (REQ_SYNC, REQ_FUA) use bits 0-1, which collide
with REQ_OP_WRITE (value 1). Move the flags to bits 8+ and add
REQ_OP_MASK to properly separate operation from flags.

Move BH_OwnsData from buffer_head.h to ext4_uboot.h to keep
Linux headers unmodified. Define it as BH_JBDPrivateStart to
avoid conflicts with JBD2 state bits (17-25).

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 fs/ext4l/ext4_uboot.h       | 17 +++++++++++++----
 fs/ext4l/support.c          |  2 +-
 include/linux/buffer_head.h |  2 --
 3 files changed, 14 insertions(+), 7 deletions(-)
  

Patch

diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h
index a90289c8fa5..39bade68654 100644
--- a/fs/ext4l/ext4_uboot.h
+++ b/fs/ext4l/ext4_uboot.h
@@ -515,8 +515,14 @@  struct sb_writers {
 
 /* Buffer head - from linux/buffer_head.h */
 #include <linux/buffer_head.h>
+#include <linux/jbd2.h>
 
-/* BH_JBDPrivateStart is defined in jbd2.h as an enum value */
+/*
+ * U-Boot: marks buffer owns b_data and should free it.
+ * Use BH_JBDPrivateStart to avoid conflicts with JBD2 state bits.
+ */
+#define BH_OwnsData		BH_JBDPrivateStart
+BUFFER_FNS(OwnsData, ownsdata)
 
 /* Forward declare for get_block_t */
 struct inode;
@@ -2153,10 +2159,13 @@  struct fs_parse_result {
 #define BLK_OPEN_WRITE			(1 << 1)
 #define BLK_OPEN_RESTRICT_WRITES	(1 << 2)
 
-/* Request flags */
+/* Request operation (bits 0-7) and flags (bits 8+) */
 #define REQ_OP_WRITE			1
-#define REQ_SYNC			(1 << 0)
-#define REQ_FUA				(1 << 1)
+#define REQ_OP_MASK			0xff
+
+/* ensure these values are outside the operations mask */
+#define REQ_SYNC			(1 << 8)
+#define REQ_FUA				(1 << 9)
 
 /* blk_holder_ops for block device */
 struct blk_holder_ops {
diff --git a/fs/ext4l/support.c b/fs/ext4l/support.c
index 05efa8d067c..a046654ca54 100644
--- a/fs/ext4l/support.c
+++ b/fs/ext4l/support.c
@@ -565,7 +565,7 @@  struct buffer_head *__bread(struct block_device *bdev, sector_t block,
 int submit_bh(int op, struct buffer_head *bh)
 {
 	int ret;
-	int op_type = op & 0xff;  /* Mask out flags, keep operation type */
+	int op_type = op & REQ_OP_MASK;  /* Mask out flags, keep operation type */
 
 	if (op_type == REQ_OP_READ) {
 		ret = ext4l_read_block(bh->b_blocknr, bh->b_size, bh->b_data);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 5fbcc757c80..b22df564119 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -37,8 +37,6 @@  enum bh_state_bits {
 	BH_PrivateStart,/* not a state bit, but the first bit available
 			 * for private allocation by other entities
 			 */
-	/* U-Boot specific: marks buffer owns b_data and should free it */
-	BH_OwnsData = BH_PrivateStart,
 };
 
 #define MAX_BUF_PER_PAGE (PAGE_SIZE / 512)