int fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio) { int err = 0; struct fuse_data *data = tick->tk_data; struct fuse_init_out *fiio; if ((err = tick->tk_aw_ohead.error)) { goto out; } if ((err = fticket_pull(tick, uio))) { goto out; } fiio = fticket_resp(tick)->base; /* XXX: Do we want to check anything further besides this? */ if (fiio->major < 7) { debug_printf("userpace version too low\n"); err = EPROTONOSUPPORT; goto out; } data->fuse_libabi_major = fiio->major; data->fuse_libabi_minor = fiio->minor; if (fuse_libabi_geq(data, 7, 5)) { if (fticket_resp(tick)->len == sizeof(struct fuse_init_out)) { data->max_write = fiio->max_write; } else { err = EINVAL; } } else { /* Old fix values */ data->max_write = 4096; } out: if (err) { fdata_set_dead(data); } FUSE_LOCK(); data->dataflags |= FSESS_INITED; wakeup(&data->ticketer); FUSE_UNLOCK(); return 0; }
static __inline__ int fticket_aw_pull_uio(struct fuse_ticket *ftick, struct uio *uio) { int err = 0; size_t len = uio_resid(uio); debug_printf("ftick=%p, uio=%p\n", ftick, uio); if (len) { switch (ftick->tk_aw_type) { case FT_A_FIOV: fiov_adjust(fticket_resp(ftick), len); err = uiomove(fticket_resp(ftick)->base, len, uio); if (err) { debug_printf("FUSE: FT_A_FIOV: error is %d" " (%p, %zd, %p)\n", err, fticket_resp(ftick)->base, len, uio); } break; case FT_A_BUF: ftick->tk_aw_bufsize = len; err = uiomove(ftick->tk_aw_bufdata, len, uio); if (err) { debug_printf("FUSE: FT_A_BUF: error is %d" " (%p, %zd, %p)\n", err, ftick->tk_aw_bufdata, len, uio); } break; default: panic("FUSE: unknown answer type for ticket %p", ftick); } } return err; }
int fdisp_wait_answ(struct fuse_dispatcher *fdip) { int err = 0; fdip->answ_stat = 0; fuse_insert_callback(fdip->tick, fuse_standard_handler); fuse_insert_message(fdip->tick); if ((err = fticket_wait_answer(fdip->tick))) { debug_printf("IPC: interrupted, err = %d\n", err); fuse_lck_mtx_lock(fdip->tick->tk_aw_mtx); if (fticket_answered(fdip->tick)) { /* * Just between noticing the interrupt and getting here, * the standard handler has completed his job. * So we drop the ticket and exit as usual. */ debug_printf("IPC: already answered\n"); fuse_lck_mtx_unlock(fdip->tick->tk_aw_mtx); goto out; } else { /* * So we were faster than the standard handler. * Then by setting the answered flag we get *him* * to drop the ticket. */ debug_printf("IPC: setting to answered\n"); fticket_set_answered(fdip->tick); fuse_lck_mtx_unlock(fdip->tick->tk_aw_mtx); return err; } } debug_printf("IPC: not interrupted, err = %d\n", err); if (fdip->tick->tk_aw_errno) { debug_printf("IPC: explicit EIO-ing, tk_aw_errno = %d\n", fdip->tick->tk_aw_errno); err = EIO; goto out; } if ((err = fdip->tick->tk_aw_ohead.error)) { debug_printf("IPC: setting status to %d\n", fdip->tick->tk_aw_ohead.error); /* * This means a "proper" fuse syscall error. * We record this value so the caller will * be able to know it's not a boring messaging * failure, if she wishes so (and if not, she can * just simply propagate the return value of this routine). * [XXX Maybe a bitflag would do the job too, * if other flags needed, this will be converted thusly.] */ fdip->answ_stat = err; goto out; } fdip->answ = fticket_resp(fdip->tick)->base; fdip->iosize = fticket_resp(fdip->tick)->len; debug_printf("IPC: all is well\n"); return 0; out: debug_printf("IPC: dropping ticket, err = %d\n", err); return err; }
__private_extern__ int fuse_internal_init_synchronous(struct fuse_ticket *ftick) { int err = 0; struct fuse_init_out *fiio; struct fuse_data *data = ftick->tk_data; if ((err = ftick->tk_aw_ohead.error)) { goto out; } fiio = fticket_resp(ftick)->base; if ((fiio->major < MACFUSE_MIN_USER_VERSION_MAJOR) || (fiio->minor < MACFUSE_MIN_USER_VERSION_MINOR)){ IOLog("MacFUSE: user-space library has too low a version\n"); err = EPROTONOSUPPORT; goto out; } data->fuse_libabi_major = fiio->major; data->fuse_libabi_minor = fiio->minor; if (fuse_libabi_geq(data, MACFUSE_MIN_USER_VERSION_MAJOR, MACFUSE_MIN_USER_VERSION_MINOR)) { if (fticket_resp(ftick)->len == sizeof(struct fuse_init_out)) { data->max_write = fiio->max_write; } else { err = EINVAL; } } else { /* Old fix values */ data->max_write = 4096; } if (fiio->flags & FUSE_CASE_INSENSITIVE) { data->dataflags |= FSESS_CASE_INSENSITIVE; } if (fiio->flags & FUSE_VOL_RENAME) { data->dataflags |= FSESS_VOL_RENAME; } if (fiio->flags & FUSE_XTIMES) { data->dataflags |= FSESS_XTIMES; } out: fuse_ticket_drop(ftick); if (err) { fdata_set_dead(data); } fuse_lck_mtx_lock(data->ticket_mtx); data->dataflags |= FSESS_INITED; fuse_wakeup(&data->ticketer); fuse_lck_mtx_unlock(data->ticket_mtx); return 0; }