Move zfs_cmd_t copyin/copyout to platform code
FreeBSD needs to cope with multiple version of the zfs_cmd_t structure. Allowing the platform code to pre and post process the cmd structure makes it possible to work with legacy tooling. Reviewed-by: Jorgen Lundman <lundman@lundman.net> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Matt Macy <mmacy@FreeBSD.org> Closes #9624
This commit is contained in:
parent
42a826eed3
commit
5142032106
|
@ -84,7 +84,7 @@ void zfs_ioctl_init_os(void);
|
||||||
|
|
||||||
int zfs_vfs_ref(zfsvfs_t **);
|
int zfs_vfs_ref(zfsvfs_t **);
|
||||||
|
|
||||||
long zfsdev_ioctl_common(uint_t, unsigned long);
|
long zfsdev_ioctl_common(uint_t, zfs_cmd_t *);
|
||||||
int zfsdev_attach(void);
|
int zfsdev_attach(void);
|
||||||
void zfsdev_detach(void);
|
void zfsdev_detach(void);
|
||||||
int zfs_kmod_init(void);
|
int zfs_kmod_init(void);
|
||||||
|
|
|
@ -168,9 +168,25 @@ static long
|
||||||
zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
|
zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
uint_t vecnum;
|
uint_t vecnum;
|
||||||
|
zfs_cmd_t *zc;
|
||||||
|
int error, rc;
|
||||||
|
|
||||||
vecnum = cmd - ZFS_IOC_FIRST;
|
vecnum = cmd - ZFS_IOC_FIRST;
|
||||||
return (zfsdev_ioctl_common(vecnum, arg));
|
|
||||||
|
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
|
||||||
|
|
||||||
|
if (ddi_copyin((void *)(uintptr_t)arg, zc, sizeof (zfs_cmd_t), 0)) {
|
||||||
|
error = -SET_ERROR(EFAULT);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
error = -zfsdev_ioctl_common(vecnum, zc);
|
||||||
|
rc = ddi_copyout(zc, (void *)(uintptr_t)arg, sizeof (zfs_cmd_t), 0);
|
||||||
|
if (error == 0 && rc != 0)
|
||||||
|
error = -SET_ERROR(EFAULT);
|
||||||
|
out:
|
||||||
|
kmem_free(zc, sizeof (zfs_cmd_t));
|
||||||
|
return (error);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -7215,18 +7215,19 @@ zfsdev_minor_alloc(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
long
|
long
|
||||||
zfsdev_ioctl_common(uint_t vecnum, unsigned long arg)
|
zfsdev_ioctl_common(uint_t vecnum, zfs_cmd_t *zc)
|
||||||
{
|
{
|
||||||
zfs_cmd_t *zc;
|
int error, cmd, flag = 0;
|
||||||
int error, cmd, rc, flag = 0;
|
|
||||||
const zfs_ioc_vec_t *vec;
|
const zfs_ioc_vec_t *vec;
|
||||||
char *saved_poolname = NULL;
|
char *saved_poolname = NULL;
|
||||||
nvlist_t *innvl = NULL;
|
nvlist_t *innvl = NULL;
|
||||||
fstrans_cookie_t cookie;
|
fstrans_cookie_t cookie;
|
||||||
|
|
||||||
cmd = vecnum;
|
cmd = vecnum;
|
||||||
|
error = 0;
|
||||||
if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
|
if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
|
||||||
return (-SET_ERROR(ZFS_ERR_IOC_CMD_UNAVAIL));
|
return (SET_ERROR(ZFS_ERR_IOC_CMD_UNAVAIL));
|
||||||
|
|
||||||
vec = &zfs_ioc_vec[vecnum];
|
vec = &zfs_ioc_vec[vecnum];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7234,16 +7235,7 @@ zfsdev_ioctl_common(uint_t vecnum, unsigned long arg)
|
||||||
* a normal or legacy handler are registered.
|
* a normal or legacy handler are registered.
|
||||||
*/
|
*/
|
||||||
if (vec->zvec_func == NULL && vec->zvec_legacy_func == NULL)
|
if (vec->zvec_func == NULL && vec->zvec_legacy_func == NULL)
|
||||||
return (-SET_ERROR(ZFS_ERR_IOC_CMD_UNAVAIL));
|
return (SET_ERROR(ZFS_ERR_IOC_CMD_UNAVAIL));
|
||||||
|
|
||||||
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
|
|
||||||
|
|
||||||
error = ddi_copyin((void *)(uintptr_t)arg, zc, sizeof (zfs_cmd_t),
|
|
||||||
flag);
|
|
||||||
if (error != 0) {
|
|
||||||
error = SET_ERROR(EFAULT);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
zc->zc_iflags = flag & FKIOCTL;
|
zc->zc_iflags = flag & FKIOCTL;
|
||||||
if (zc->zc_nvlist_src_size > MAX_NVLIST_SRC_SIZE) {
|
if (zc->zc_nvlist_src_size > MAX_NVLIST_SRC_SIZE) {
|
||||||
|
@ -7406,9 +7398,6 @@ zfsdev_ioctl_common(uint_t vecnum, unsigned long arg)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
nvlist_free(innvl);
|
nvlist_free(innvl);
|
||||||
rc = ddi_copyout(zc, (void *)(uintptr_t)arg, sizeof (zfs_cmd_t), flag);
|
|
||||||
if (error == 0 && rc != 0)
|
|
||||||
error = SET_ERROR(EFAULT);
|
|
||||||
if (error == 0 && vec->zvec_allow_log) {
|
if (error == 0 && vec->zvec_allow_log) {
|
||||||
char *s = tsd_get(zfs_allow_log_key);
|
char *s = tsd_get(zfs_allow_log_key);
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
|
@ -7418,9 +7407,7 @@ out:
|
||||||
if (saved_poolname != NULL)
|
if (saved_poolname != NULL)
|
||||||
kmem_strfree(saved_poolname);
|
kmem_strfree(saved_poolname);
|
||||||
}
|
}
|
||||||
|
return (error);
|
||||||
kmem_free(zc, sizeof (zfs_cmd_t));
|
|
||||||
return (-error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue