aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2024-01-12 12:35:29 -0800
committerBrian Behlendorf <[email protected]>2024-01-29 14:53:29 -0800
commit2006ac1f4a52419d08641324ba56ecc5d0bbaf6f (patch)
tree8a4920fb976370c79180d38613e6f0ec06d6c598
parent509526ad2103adddc18c1b6d7b514d0c36b682ef (diff)
Fix "out of memory" error
Drop the no_memory() call from zpool_in_use() when reading the label fails and instead return the error to the caller. This prevents a misleading "internal error: out of memory" error when the label can't be read. This will result in is_spare() returning B_FALSE instead of aborting, which is already safely handled. Furthermore, on Linux it's possible for EREMOTEIO to returned by an NVMe device if the device has been low-level formatted and not rescanned. In this case we want to fallback to the legacy scanning method and read any of the labels we can. Reviewed-by: Brian Atkinson <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #13538 Closes #15747
-rw-r--r--lib/libzfs/libzfs_import.c4
-rw-r--r--lib/libzutil/zutil_import.c15
2 files changed, 14 insertions, 5 deletions
diff --git a/lib/libzfs/libzfs_import.c b/lib/libzfs/libzfs_import.c
index 2a7c5a76a..e2d40a7b3 100644
--- a/lib/libzfs/libzfs_import.c
+++ b/lib/libzfs/libzfs_import.c
@@ -291,10 +291,8 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
*inuse = B_FALSE;
- if (zpool_read_label(fd, &config, NULL) != 0) {
- (void) no_memory(hdl);
+ if (zpool_read_label(fd, &config, NULL) != 0)
return (-1);
- }
if (config == NULL)
return (0);
diff --git a/lib/libzutil/zutil_import.c b/lib/libzutil/zutil_import.c
index 19d8a4742..bafe50e5f 100644
--- a/lib/libzutil/zutil_import.c
+++ b/lib/libzutil/zutil_import.c
@@ -1056,10 +1056,21 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels)
case EINVAL:
break;
case EINPROGRESS:
- // This shouldn't be possible to
- // encounter, die if we do.
+ /*
+ * This shouldn't be possible to
+ * encounter, die if we do.
+ */
ASSERT(B_FALSE);
zfs_fallthrough;
+ case EREMOTEIO:
+ /*
+ * May be returned by an NVMe device
+ * which is visible in /dev/ but due
+ * to a low-level format change, or
+ * other error, needs to be rescanned.
+ * Try the slow method.
+ */
+ zfs_fallthrough;
case EOPNOTSUPP:
case ENOSYS:
do_slow = B_TRUE;