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;
}
Exemple #3
0
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__
}