mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Add mutex_enter_interruptible() for interruptible sleeping IOCTLs
Many long-running ZFS ioctls lock the spa_namespace_lock, forcing concurrent ioctls to sleep for the mutex. Previously, the only option is to call mutex_enter() which sleeps uninterruptibly. This is a usability issue for sysadmins, for example, if the admin runs `zpool status` while a slow `zpool import` is ongoing, the admin's shell will be locked in uninterruptible sleep for a long time. This patch resolves this admin usability issue by introducing mutex_enter_interruptible() which sleeps interruptibly while waiting to acquire a lock. It is implemented for both Linux and FreeBSD. The ZFS_IOC_POOL_CONFIGS ioctl, used by `zpool status`, is changed to use this new macro so that the command can be interrupted if it is issued during a concurrent `zpool import` (or other long-running operation). Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Thomas Bertschinger <bertschinger@lanl.gov> Closes #15360
This commit is contained in:
committed by
GitHub
parent
6a629f3234
commit
97a0b5be50
@@ -367,23 +367,24 @@ spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent,
|
||||
* So we have to invent the ZFS_IOC_CONFIG ioctl to grab the configuration
|
||||
* information for all pool visible within the zone.
|
||||
*/
|
||||
nvlist_t *
|
||||
spa_all_configs(uint64_t *generation)
|
||||
int
|
||||
spa_all_configs(uint64_t *generation, nvlist_t **pools)
|
||||
{
|
||||
nvlist_t *pools;
|
||||
spa_t *spa = NULL;
|
||||
|
||||
if (*generation == spa_config_generation)
|
||||
return (NULL);
|
||||
return (SET_ERROR(EEXIST));
|
||||
|
||||
pools = fnvlist_alloc();
|
||||
int error = mutex_enter_interruptible(&spa_namespace_lock);
|
||||
if (error)
|
||||
return (SET_ERROR(EINTR));
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
*pools = fnvlist_alloc();
|
||||
while ((spa = spa_next(spa)) != NULL) {
|
||||
if (INGLOBALZONE(curproc) ||
|
||||
zone_dataset_visible(spa_name(spa), NULL)) {
|
||||
mutex_enter(&spa->spa_props_lock);
|
||||
fnvlist_add_nvlist(pools, spa_name(spa),
|
||||
fnvlist_add_nvlist(*pools, spa_name(spa),
|
||||
spa->spa_config);
|
||||
mutex_exit(&spa->spa_props_lock);
|
||||
}
|
||||
@@ -391,7 +392,7 @@ spa_all_configs(uint64_t *generation)
|
||||
*generation = spa_config_generation;
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
|
||||
return (pools);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1582,8 +1582,9 @@ zfs_ioc_pool_configs(zfs_cmd_t *zc)
|
||||
nvlist_t *configs;
|
||||
int error;
|
||||
|
||||
if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
|
||||
return (SET_ERROR(EEXIST));
|
||||
error = spa_all_configs(&zc->zc_cookie, &configs);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = put_nvlist(zc, configs);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user