From 9586e114e74a50cc836b460d86ecb571435e43fd Mon Sep 17 00:00:00 2001 From: surface-camera-build Date: Tue, 22 Sep 2026 00:37:09 -0400 Subject: [PATCH] cube(2): CUBE_OP_PUT takes a class mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mask is the writer's and is stamped once, at the moment the record's class is known for certain; every later reader is spared re-deriving it. It means nothing to this side — which bits are which class is a vocabulary's business, and a kernel that interpreted one would be inventing a vocabulary. 0 is "no class", which is what every record written before the field existed reads as, so a caller that does not classify is not writing a special value. A store whose image is the legacy packed layout has no field to put a mask in and drops it: that layout cannot carry a class, and saying otherwise would be a lie about the bytes on disk. The field is appended, so sizeof(cube_args) grows from 80 to 88 — still distinct from the other three argument blocks, which is what the size-first dispatch depends on. --- drivers/cube/cube_syscall.c | 5 +++-- drivers/cube/cubelinux_store.rs | 10 ++++++++-- include/uapi/linux/cube.h | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/cube/cube_syscall.c b/drivers/cube/cube_syscall.c index 335cfe413..1601bfc6c 100644 --- a/drivers/cube/cube_syscall.c +++ b/drivers/cube/cube_syscall.c @@ -30,7 +30,7 @@ * encoding, which must produce exactly the key a userspace reader decodes. */ int cubelinux_kernel_put(const __u8 *space, __u64 x, __u64 y, __u64 z, - const void *value, size_t len); + const void *value, size_t len, __u16 flags); ssize_t cubelinux_kernel_get(const __u8 *space, __u64 x, __u64 y, __u64 z, void *buf, size_t len); int cubelinux_kernel_del(const __u8 *space, __u64 x, __u64 y, __u64 z); @@ -188,7 +188,8 @@ static long cube_args_op(unsigned int op, void __user *uargs) break; } ret = cubelinux_kernel_put(args.coord.space, args.coord.x, - args.coord.y, args.coord.z, buf, args.len); + args.coord.y, args.coord.z, buf, args.len, + args.flags); break; case CUBE_OP_GET: { diff --git a/drivers/cube/cubelinux_store.rs b/drivers/cube/cubelinux_store.rs index 491146c46..88507b528 100644 --- a/drivers/cube/cubelinux_store.rs +++ b/drivers/cube/cubelinux_store.rs @@ -1696,7 +1696,12 @@ fn ensure_boot_record() { } } -/// `CUBE_OP_PUT`: store bytes at a coordinate. +/// `CUBE_OP_PUT`: store bytes at a coordinate, under a class mask. +/// +/// The mask is the writer's and is stamped here, once — this is the moment the record's class is +/// known for certain, and every later reader is spared re-deriving it. It means nothing to this +/// side: which bits are which class is a vocabulary's business, and a kernel that interpreted one +/// would be inventing a vocabulary. /// /// # Safety /// `space` must point to 32 readable bytes; `value` to `len` readable bytes when `len` is @@ -1709,6 +1714,7 @@ pub unsafe extern "C" fn cubelinux_kernel_put( z: u64, value: *const u8, len: usize, + flags: u16, ) -> i32 { ensure_boot_record(); let (sp, key) = unsafe { coord_key(space, x, y, z) }; @@ -1725,7 +1731,7 @@ pub unsafe extern "C" fn cubelinux_kernel_put( let mutation = Mutation { space: sp, key, - flags: 0, + flags, value: bytes, }; let (device, layout) = match device_and_layout() { diff --git a/include/uapi/linux/cube.h b/include/uapi/linux/cube.h index 58fa9698a..44d3cb44c 100644 --- a/include/uapi/linux/cube.h +++ b/include/uapi/linux/cube.h @@ -34,6 +34,20 @@ struct cube_args { * out: on -ERANGE, the bytes that would be needed; * on success for CUBE_OP_GET, the bytes read. */ + __u16 flags; /* in: CUBE_OP_PUT only — the class mask to stamp on the + * record. The mask is written where the record is written, + * which is the moment its class is known for certain; a + * reader never has to re-derive it. 0 is "no class", which + * is what every record written before the field existed + * reads as, so a caller that does not classify is not + * writing a special value. + * + * A store whose image is the legacy packed layout has no + * field to put a mask in, and drops it: that layout cannot + * carry a class and saying otherwise would be a lie about + * the bytes on disk. + */ + __u16 reserved; /* must be 0 */ }; #define CUBE_OP_PUT 1 /* store bytes at a coordinate */