Avoid taking global lock to destroy zfsdev state

We have exclusive access to our zfsdev state object in this section
until it is invalidated by setting zs_minor to -1, so we can destroy
the state without taking a lock if we do the invalidation last, after
a member to ensure correct ordering.

While here, strengthen the assertions that zs_minor is valid when we
enter.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Ryan Moeller <freqlabs@FreeBSD.org>
Closes #11751
This commit is contained in:
Ryan Moeller 2021-04-02 14:09:05 -04:00 committed by Tony Hutter
parent 87a520c4e7
commit 43efd5625b
2 changed files with 11 additions and 21 deletions

View File

@ -185,18 +185,14 @@ zfsdev_close(void *data)
zfsdev_state_t *zs = data;
ASSERT(zs != NULL);
ASSERT3S(zs->zs_minor, >, 0);
mutex_enter(&zfsdev_state_lock);
ASSERT(zs->zs_minor != 0);
zs->zs_minor = -1;
zfs_onexit_destroy(zs->zs_onexit);
zfs_zevent_destroy(zs->zs_zevent);
zs->zs_onexit = NULL;
zs->zs_zevent = NULL;
mutex_exit(&zfsdev_state_lock);
membar_producer();
zs->zs_minor = -1;
}
static int

View File

@ -136,22 +136,20 @@ zfsdev_state_init(struct file *filp)
return (0);
}
static int
static void
zfsdev_state_destroy(struct file *filp)
{
zfsdev_state_t *zs;
zfsdev_state_t *zs = filp->private_data;
ASSERT(MUTEX_HELD(&zfsdev_state_lock));
ASSERT(filp->private_data != NULL);
ASSERT(zs != NULL);
ASSERT3S(zs->zs_minor, >, 0);
zs = filp->private_data;
zs->zs_minor = -1;
zfs_onexit_destroy(zs->zs_onexit);
zfs_zevent_destroy(zs->zs_zevent);
zs->zs_onexit = NULL;
zs->zs_zevent = NULL;
return (0);
membar_producer();
zs->zs_minor = -1;
}
static int
@ -169,13 +167,9 @@ zfsdev_open(struct inode *ino, struct file *filp)
static int
zfsdev_release(struct inode *ino, struct file *filp)
{
int error;
zfsdev_state_destroy(filp);
mutex_enter(&zfsdev_state_lock);
error = zfsdev_state_destroy(filp);
mutex_exit(&zfsdev_state_lock);
return (-error);
return (0);
}
static long