mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Add zpool_events_seek() functionality
The ZFS_IOC_EVENTS_SEEK ioctl was added to allow user space callers to seek around the zevent file descriptor by EID. When a specific EID is passed and it exists the cursor will be positioned there. If the EID is no longer cached by the kernel ENOENT is returned. The caller may also pass ZEVENT_SEEK_START or ZEVENT_SEEK_END to seek to those respective locations. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Chris Dunlap <cdunlap@llnl.gov> Issue #2
This commit is contained in:
@@ -664,6 +664,67 @@ out:
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller may seek to a specific EID by passing that EID. If the EID
|
||||
* is still available in the posted list of events the cursor is positioned
|
||||
* there. Otherwise ENOENT is returned and the cursor is not moved.
|
||||
*
|
||||
* There are two reserved EIDs which may be passed and will never fail.
|
||||
* ZEVENT_SEEK_START positions the cursor at the start of the list, and
|
||||
* ZEVENT_SEEK_END positions the cursor at the end of the list.
|
||||
*/
|
||||
int
|
||||
zfs_zevent_seek(zfs_zevent_t *ze, uint64_t eid)
|
||||
{
|
||||
zevent_t *ev;
|
||||
int error = 0;
|
||||
|
||||
mutex_enter(&zevent_lock);
|
||||
|
||||
if (eid == ZEVENT_SEEK_START) {
|
||||
if (ze->ze_zevent)
|
||||
list_remove(&ze->ze_zevent->ev_ze_list, ze);
|
||||
|
||||
ze->ze_zevent = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (eid == ZEVENT_SEEK_END) {
|
||||
if (ze->ze_zevent)
|
||||
list_remove(&ze->ze_zevent->ev_ze_list, ze);
|
||||
|
||||
ev = list_head(&zevent_list);
|
||||
if (ev) {
|
||||
ze->ze_zevent = ev;
|
||||
list_insert_head(&ev->ev_ze_list, ze);
|
||||
} else {
|
||||
ze->ze_zevent = NULL;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (ev = list_tail(&zevent_list); ev != NULL;
|
||||
ev = list_prev(&zevent_list, ev)) {
|
||||
if (ev->ev_eid == eid) {
|
||||
if (ze->ze_zevent)
|
||||
list_remove(&ze->ze_zevent->ev_ze_list, ze);
|
||||
|
||||
ze->ze_zevent = ev;
|
||||
list_insert_head(&ev->ev_ze_list, ze);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev == NULL)
|
||||
error = ENOENT;
|
||||
|
||||
out:
|
||||
mutex_exit(&zevent_lock);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
zfs_zevent_init(zfs_zevent_t **zep)
|
||||
{
|
||||
|
||||
@@ -4919,6 +4919,28 @@ zfs_ioc_events_clear(zfs_cmd_t *zc)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* inputs:
|
||||
* zc_guid eid | ZEVENT_SEEK_START | ZEVENT_SEEK_END
|
||||
* zc_cleanup zevent file descriptor
|
||||
*/
|
||||
static int
|
||||
zfs_ioc_events_seek(zfs_cmd_t *zc)
|
||||
{
|
||||
zfs_zevent_t *ze;
|
||||
minor_t minor;
|
||||
int error;
|
||||
|
||||
error = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = zfs_zevent_seek(ze, zc->zc_guid);
|
||||
zfs_zevent_fd_rele(zc->zc_cleanup_fd);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* inputs:
|
||||
* zc_name name of new filesystem or snapshot
|
||||
@@ -5393,6 +5415,8 @@ zfs_ioctl_init(void)
|
||||
zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
|
||||
zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_CLEAR, zfs_ioc_events_clear,
|
||||
zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
|
||||
zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_SEEK, zfs_ioc_events_seek,
|
||||
zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user