[PATCH V7 2/3] fuse_kernel.h: add famfs DAX fmap protocol definitions

John Groves
2026-01-18T22:35:38Z

From: John Groves <john@groves.net>

Add FUSE protocol version 7.46 definitions for famfs DAX file mapping:

Capability flag:
- FUSE_DAX_FMAP (bit 43): kernel supports DAX fmap operations

New opcodes:
- FUSE_GET_FMAP (54): retrieve file extent map for DAX mapping
- FUSE_GET_DAXDEV (55): retrieve DAX device info by index

New structures for GET_FMAP reply:
- struct fuse_famfs_fmap_header: file map header with type and extent info
- struct fuse_famfs_simple_ext: simple extent (device, offset, length)
- struct fuse_famfs_iext: interleaved extent for striped allocations

New structures for GET_DAXDEV:
- struct fuse_get_daxdev_in: request DAX device by index
- struct fuse_daxdev_out: DAX device name response

Supporting definitions:
- enum fuse_famfs_file_type: regular, superblock, or log file
- enum famfs_ext_type: simple or interleaved extent type

Signed-off-by: John Groves <john@groves.net>
---
include/fuse_kernel.h | 88 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)

diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h
index c13e1f9..7fdfc30 100644
--- a/include/fuse_kernel.h
+++ b/include/fuse_kernel.h
@@ -240,6 +240,19 @@
* - add FUSE_COPY_FILE_RANGE_64
* - add struct fuse_copy_file_range_out
* - add FUSE_NOTIFY_PRUNE
+ *
+ * 7.46
+ * - Add FUSE_DAX_FMAP capability - ability to handle in-kernel fsdax maps
+ * - Add the following structures for the GET_FMAP message reply components:
+ * - struct fuse_famfs_simple_ext
+ * - struct fuse_famfs_iext
+ * - struct fuse_famfs_fmap_header
+ * - Add the following structs for the GET_DAXDEV message and reply
+ * - struct fuse_get_daxdev_in
+ * - struct fuse_get_daxdev_out
+ * - Add the following enumerated types
+ * - enum fuse_famfs_file_type
+ * - enum famfs_ext_type
*/

#ifndef _LINUX_FUSE_H
@@ -448,6 +461,7 @@ struct fuse_file_lock {
* FUSE_OVER_IO_URING: Indicate that client supports io-uring
* FUSE_REQUEST_TIMEOUT: kernel supports timing out requests.
* init_out.request_timeout contains the timeout (in secs)
+ * FUSE_DAX_FMAP: kernel supports dev_dax_iomap (aka famfs) fmaps
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
@@ -495,6 +509,7 @@ struct fuse_file_lock {
#define FUSE_ALLOW_IDMAP (1ULL << 40)
#define FUSE_OVER_IO_URING (1ULL << 41)
#define FUSE_REQUEST_TIMEOUT (1ULL << 42)
+#define FUSE_DAX_FMAP (1ULL << 43)

/**
* CUSE INIT request/reply flags
@@ -664,6 +679,10 @@ enum fuse_opcode {
FUSE_STATX = 52,
FUSE_COPY_FILE_RANGE_64 = 53,

+ /* Famfs / devdax opcodes */
+ FUSE_GET_FMAP = 54,
+ FUSE_GET_DAXDEV = 55,
+
/* CUSE specific operations */
CUSE_INIT = 4096,

@@ -1308,4 +1327,73 @@ struct fuse_uring_cmd_req {
uint8_t padding[6];
};

+/* Famfs fmap message components */
+
+#define FAMFS_FMAP_VERSION 1
+
+#define FAMFS_FMAP_MAX 32768 /* Largest supported fmap message */
+#define FUSE_FAMFS_MAX_EXTENTS 32
+#define FUSE_FAMFS_MAX_STRIPS 32
+
+enum fuse_famfs_file_type {
+ FUSE_FAMFS_FILE_REG,
+ FUSE_FAMFS_FILE_SUPERBLOCK,
+ FUSE_FAMFS_FILE_LOG,
+};
+
+enum famfs_ext_type {
+ FUSE_FAMFS_EXT_SIMPLE = 0,
+ FUSE_FAMFS_EXT_INTERLEAVE = 1,
+};
+
+struct fuse_famfs_simple_ext {
+ uint32_t se_devindex;
+ uint32_t reserved;
+ uint64_t se_offset;
+ uint64_t se_len;
+};
+
+struct fuse_famfs_iext { /* Interleaved extent */
+ uint32_t ie_nstrips;
+ uint32_t ie_chunk_size;
+ uint64_t ie_nbytes; /* Total bytes for this interleaved_ext;
+ * sum of strips may be more
+ */
+ uint64_t reserved;
+};
+
+struct fuse_famfs_fmap_header {
+ uint8_t file_type; /* enum famfs_file_type */
+ uint8_t reserved;
+ uint16_t fmap_version;
+ uint32_t ext_type; /* enum famfs_log_ext_type */
+ uint32_t nextents;
+ uint32_t reserved0;
+ uint64_t file_size;
+ uint64_t reserved1;
+};
+
+struct fuse_get_daxdev_in {
+ uint32_t daxdev_num;
+};
+
+#define DAXDEV_NAME_MAX 256
+
+/* fuse_daxdev_out has enough space for a uuid if we need it */
+struct fuse_daxdev_out {
+ uint16_t index;
+ uint16_t reserved;
+ uint32_t reserved2;
+ uint64_t reserved3;
+ uint64_t reserved4;
+ char name[DAXDEV_NAME_MAX];
+};
+
+static __inline__ int32_t fmap_msg_min_size(void)
+{
+ /* Smallest fmap message is a header plus one simple extent */
+ return (sizeof(struct fuse_famfs_fmap_header)
+ + sizeof(struct fuse_famfs_simple_ext));
+}
+
#endif /* _LINUX_FUSE_H */
--
2.52.0