]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
block/rnbd-proto: Handle PREFLUSH flag properly for IOs
authorMd Haris Iqbal <haris.iqbal@ionos.com>
Fri, 5 Dec 2025 12:47:28 +0000 (13:47 +0100)
committerJens Axboe <axboe@kernel.dk>
Tue, 6 Jan 2026 12:28:10 +0000 (05:28 -0700)
In RNBD client, for a WRITE request of size 0, with only the REQ_PREFLUSH
bit set, while converting from bio_opf to rnbd_opf, we do REQ_OP_WRITE to
RNBD_OP_WRITE, and then check if the rq is flush through function
op_is_flush. That function checks both REQ_PREFLUSH and REQ_FUA flag, and
if any of them is set, the RNBD_F_FUA is set.
On the RNBD server side, while converting the RNBD flags to req flags, if
the RNBD_F_FUA flag is set, we just set the REQ_FUA flag. This means we
have lost the PREFLUSH flag, and added the REQ_FUA flag in its place.

This commits adds a new RNBD_F_PREFLUSH flag, and also adds separate
handling for REQ_PREFLUSH flag. On the server side, if the RNBD_F_PREFLUSH
is present, the REQ_PREFLUSH is added to the bio.

Since it is a change in the wire protocol, bump the minor version of
protocol.
The change is backwards compatible, and does not change the functionality
if either the client or the server is running older/newer versions.
If the client side is running the older version, both REQ_PREFLUSH and
REQ_FUA is converted to RNBD_F_FUA. The server running newer one would
still add only the REQ_FUA flag which is what happens when both client and
server is running the older version.
If the client side is running the newer version, just like before a
RNBD_F_FUA is added, but now a RNBD_F_PREFLUSH is also added to the
rnbd_opf. In case the server is running the older version the
RNBD_F_PREFLUSH is ignored, and only the RNBD_F_FUA is processed.

Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
Reviewed-by: Florian-Ewald Mueller <florian-ewald.mueller@ionos.com>
Signed-off-by: Grzegorz Prajsner <grzegorz.prajsner@ionos.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/rnbd/rnbd-proto.h

index 77360c2a6069ce7374453e4d8f28ca3ffbdc1f9c..5e74ae86169b0edf5a7a99b5716f4ca82e03ec45 100644 (file)
@@ -18,7 +18,7 @@
 #include <rdma/ib.h>
 
 #define RNBD_PROTO_VER_MAJOR 2
-#define RNBD_PROTO_VER_MINOR 0
+#define RNBD_PROTO_VER_MINOR 1
 
 /* The default port number the RTRS server is listening on. */
 #define RTRS_PORT 1234
@@ -197,6 +197,7 @@ struct rnbd_msg_io {
  *
  * @RNBD_F_SYNC:            request is sync (sync write or read)
  * @RNBD_F_FUA:             forced unit access
+ * @RNBD_F_PREFLUSH:       request for cache flush
  */
 enum rnbd_io_flags {
 
@@ -211,6 +212,7 @@ enum rnbd_io_flags {
        /* Flags */
        RNBD_F_SYNC  = 1<<(RNBD_OP_BITS + 0),
        RNBD_F_FUA   = 1<<(RNBD_OP_BITS + 1),
+       RNBD_F_PREFLUSH = 1<<(RNBD_OP_BITS + 2)
 };
 
 static inline u32 rnbd_op(u32 flags)
@@ -258,6 +260,9 @@ static inline blk_opf_t rnbd_to_bio_flags(u32 rnbd_opf)
        if (rnbd_opf & RNBD_F_FUA)
                bio_opf |= REQ_FUA;
 
+       if (rnbd_opf & RNBD_F_PREFLUSH)
+               bio_opf |= REQ_PREFLUSH;
+
        return bio_opf;
 }
 
@@ -297,6 +302,9 @@ static inline u32 rq_to_rnbd_flags(struct request *rq)
        if (op_is_flush(rq->cmd_flags))
                rnbd_opf |= RNBD_F_FUA;
 
+       if (rq->cmd_flags & REQ_PREFLUSH)
+               rnbd_opf |= RNBD_F_PREFLUSH;
+
        return rnbd_opf;
 }