cube(2): CUBE_OP_PUT takes a class mask

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.
This commit is contained in:
surface-camera-build
2026-09-22 00:37:09 -04:00
parent 71552fc157
commit 9586e114e7
3 changed files with 25 additions and 4 deletions
+3 -2
View File
@@ -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: {
+8 -2
View File
@@ -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() {