cube(2): CUBE_OP_FLAG_SCAN takes a scope — one space, or every space

"Every error anywhere" and "every error here" are different questions, and
a space is a hard partition, so the scope is a field rather than a widening.
It is not a reserved space id because there is no such id to reserve: every
32-byte value is a legitimate space, root 0x00 and edge 0xFF…FF among them,
so a sentinel would be a space somebody could name. The field occupies what
was padding, which keeps sizeof unchanged — and that matters, because size is
what says which argument block arrived and cube_args is exactly eight bytes
wider.

An every-space answer carries each frame's space, and that is not decoration:
a walk's frame omits the space on the grounds that the caller named it, and
this caller named none. A coordinate is meaningless without its space, so an
answer that left it out would be unusable rather than merely terse. The space
leads because the (space, key) pair it forms is the order records are stored
in and returned in — so an every-space scan answers in exactly the order a
checkpoint writes.

The walk visits the space table's order and puts a space only the log writes
into in its place in that same order, which is the one thing a plain walk of
the table would miss entirely. A scope or mode this build does not know is
refused rather than defaulted: silently answering a narrower question than the
one asked is as quiet a way to be wrong as answering a wider one.
This commit is contained in:
surface-camera-build
2026-09-22 00:31:56 -04:00
parent 41e437c07a
commit 71552fc157
3 changed files with 406 additions and 145 deletions
+5 -3
View File
@@ -62,7 +62,7 @@ int cubelinux_kernel_range(const __u8 *space,
* what lets a new vocabulary attach without a format change.
*/
int cubelinux_kernel_flag_scan(const __u8 *space, __u16 mask, __u16 mode,
__u64 cursor, void *buf, size_t cap,
__u32 every_space, __u64 cursor, void *buf, size_t cap,
__u64 *out_len, __u64 *out_cursor);
/* The store device path, resolved from the `cube_store=` boot parameter at boot. */
@@ -393,6 +393,8 @@ static long cube_flag_scan_op(void __user *uargs)
return -EINVAL;
if (f.mode != CUBE_FLAG_ANY && f.mode != CUBE_FLAG_ALL)
return -EINVAL;
if (f.every_space != CUBE_SPACE_ONE && f.every_space != CUBE_SPACE_EVERY)
return -EINVAL;
if (f.len > CUBE_MAX_WALK)
return -E2BIG;
@@ -402,8 +404,8 @@ static long cube_flag_scan_op(void __user *uargs)
return -ENOMEM;
}
ret = cubelinux_kernel_flag_scan(f.space, f.mask, f.mode, f.cursor,
buf, f.len, &out_len, &out_cursor);
ret = cubelinux_kernel_flag_scan(f.space, f.mask, f.mode, f.every_space,
f.cursor, buf, f.len, &out_len, &out_cursor);
if (ret == 0) {
if (out_len > 0 && copy_to_user((void __user *)f.value, buf, out_len))
ret = -EFAULT;