From d74862f1fc5a0c8d20ac50b6281d53c691a59f1e Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Thu, 12 Dec 2024 22:48:15 -0500 Subject: [PATCH] fs: set the correct nr_items to 0 in the ENOENT search case Commit 72c3bf8438830b65cae7bdaff126053e562280e5 ("fs: handle ENOENT within lib") was meant to prevent exceptions when a subvol is deleted. If the search ioctl fails, the kernel won't set nr_items in the ioctl output, which means `nr_items` still has the input value. When ENOENT is detected, `this->nr_items` is set to 0, then later `*this = ioctl_ptr->key` overwrites `this->nr_items` with the original requested number of items. This replaced the ENOENT exception with an exception triggered by interpreting garbage in the memory buffer. The number of exceptions was reduced because the memory buffers are frequently reused, but upper layers would then reject the data or ignore it because it didn't match the key range. Fix by setting `ioctl_ptr->key.nr_items`, which then overwrites `this->nr_items`, so the loop that extracts items from the ioctl data gets the right number of items (i.e. zero). Fixes: 72c3bf8438830b65cae7bdaff126053e562280e5 ("fs: handle ENOENT within lib") Signed-off-by: Zygo Blaxell --- lib/fs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fs.cc b/lib/fs.cc index dc9a2eb..3366d14 100644 --- a/lib/fs.cc +++ b/lib/fs.cc @@ -781,7 +781,7 @@ namespace crucible { ++s_calls; if (rv != 0 && errno == ENOENT) { // If we are searching a tree that is deleted or no longer exists, just return an empty list - nr_items = 0; + ioctl_ptr->key.nr_items = 0; break; } if (rv != 0 && errno != EOVERFLOW) {