int zfsfuse_ioctl(int fd, int32_t request, void *arg) { printf("zfsfuse_ioctl => gonna crash sooner or later !!!\n"); abort(); zfsfuse_cmd_t cmd; int ret; cmd.cmd_type = IOCTL_REQ; cmd.cmd_u.ioctl_req.cmd = request; cmd.cmd_u.ioctl_req.arg = (uint64_t)(uintptr_t) arg; cmd.uid = getuid(); cmd.gid = getgid(); if((ret=write(fd, &cmd, sizeof(zfsfuse_cmd_t)) != sizeof(zfsfuse_cmd_t))) return -1; for(;;) { if(zfsfuse_ioctl_read_loop(fd, &cmd, sizeof(zfsfuse_cmd_t)) != 0) return -1; switch(cmd.cmd_type) { case IOCTL_ANS: errno = cmd.cmd_u.ioctl_ans_ret; return errno; case COPYIN_REQ: if((ret=write(fd, (void *)(uintptr_t) cmd.cmd_u.copy_req.ptr, cmd.cmd_u.copy_req.size) != cmd.cmd_u.copy_req.size)) return -1; break; case COPYINSTR_REQ: ; zfsfuse_cmd_t ans = { 0 }; ans.cmd_type = COPYINSTR_ANS; size_t length = strlen((char *)(uintptr_t) cmd.cmd_u.copy_req.ptr); if(length >= cmd.cmd_u.copy_req.size) { ans.cmd_u.copy_ans.ret = ENAMETOOLONG; ans.cmd_u.copy_ans.lencopied = cmd.cmd_u.copy_req.size - 1; } else ans.cmd_u.copy_ans.lencopied = length; if(((ret=write(fd, &ans, sizeof(zfsfuse_cmd_t))) != sizeof(zfsfuse_cmd_t))) return -1; if((ret=write(fd, (void *)(uintptr_t) cmd.cmd_u.copy_req.ptr, ans.cmd_u.copy_ans.lencopied)) != ans.cmd_u.copy_ans.lencopied) return -1; break; case COPYOUT_REQ: if(zfsfuse_ioctl_read_loop(fd, (void *)(uintptr_t) cmd.cmd_u.copy_req.ptr, cmd.cmd_u.copy_req.size) != 0) return -1; break; case GETF_REQ: if(zfsfuse_sendfd(fd, cmd.cmd_u.getf_req_fd) != 0) return -1; break; default: abort(); break; } } }
/* If you change this, check _sol_mount in lib/libsolcompat/include/sys/mount.h */ int zfsfuse_mount(libzfs_handle_t *hdl, const char *spec, const char *dir, int mflag, char *fstype, char *dataptr, int datalen, char *optptr, int optlen) { assert(dataptr == NULL); assert(datalen == 0); assert(mflag == 0); assert(strcmp(fstype, MNTTYPE_ZFS) == 0); zfsfuse_cmd_t cmd; uint32_t speclen = strlen(spec); uint32_t dirlen = strlen(dir); int ret; cmd.cmd_type = MOUNT_REQ; cmd.cmd_u.mount_req.speclen = speclen; cmd.cmd_u.mount_req.dirlen = dirlen; cmd.cmd_u.mount_req.mflag = mflag; cmd.cmd_u.mount_req.optlen = optlen; if((ret=write(hdl->libzfs_fd, &cmd, sizeof(zfsfuse_cmd_t))) != sizeof(zfsfuse_cmd_t)) return -1; if((ret=write(hdl->libzfs_fd, spec, speclen)) != speclen) return -1; if((ret=write(hdl->libzfs_fd, dir, dirlen)) != dirlen) return -1; if((ret=write(hdl->libzfs_fd, optptr, optlen)) != optlen) return -1; uint32_t error; if(zfsfuse_ioctl_read_loop(hdl->libzfs_fd, &error, sizeof(uint32_t)) != 0) return -1; if(error == 0) return error; errno = error; return -1; }
int zfsfuse_ioctl(int fd, int32_t request, void *arg) { zfsfuse_cmd_t cmd; cmd.cmd_type = IOCTL_REQ; cmd.cmd_u.ioctl_req.cmd = request; cmd.cmd_u.ioctl_req.arg = (uint64_t)(uintptr_t) arg; #ifdef __native_client__ if ( request == ZFS_IOC_POOL_CREATE ){ int ioctl_ret = zfsdev_ioctl(NULL, request, (uintptr_t) cmd.cmd_u.ioctl_req.arg, 0, NULL, NULL); ASSERT(!ioctl_ret); } #else if(write(fd, &cmd, sizeof(zfsfuse_cmd_t)) != sizeof(zfsfuse_cmd_t)) return -1; for(;;) { if(zfsfuse_ioctl_read_loop(fd, &cmd, sizeof(zfsfuse_cmd_t)) != 0) return -1; switch(cmd.cmd_type) { case IOCTL_ANS: errno = cmd.cmd_u.ioctl_ans_ret; return errno; case COPYIN_REQ: if(write(fd, (void *)(uintptr_t) cmd.cmd_u.copy_req.ptr, cmd.cmd_u.copy_req.size) != cmd.cmd_u.copy_req.size) return -1; break; case COPYINSTR_REQ: ; zfsfuse_cmd_t ans = { 0 }; ans.cmd_type = COPYINSTR_ANS; size_t length = strlen((char *)(uintptr_t) cmd.cmd_u.copy_req.ptr); if(length >= cmd.cmd_u.copy_req.size) { ans.cmd_u.copy_ans.ret = ENAMETOOLONG; ans.cmd_u.copy_ans.lencopied = cmd.cmd_u.copy_req.size - 1; } else ans.cmd_u.copy_ans.lencopied = length; if(write(fd, &ans, sizeof(zfsfuse_cmd_t)) != sizeof(zfsfuse_cmd_t)) return -1; if(write(fd, (void *)(uintptr_t) cmd.cmd_u.copy_req.ptr, ans.cmd_u.copy_ans.lencopied) != ans.cmd_u.copy_ans.lencopied) return -1; break; case COPYOUT_REQ: if(zfsfuse_ioctl_read_loop(fd, (void *)(uintptr_t) cmd.cmd_u.copy_req.ptr, cmd.cmd_u.copy_req.size) != 0) return -1; break; case GETF_REQ: if(zfsfuse_sendfd(fd, cmd.cmd_u.getf_req_fd) != 0) return -1; break; default: abort(); break; } } #endif //__native_client__ }