FreeBSD/sys/fs/fuse/fuse_device.c
/*
 * fuse_device_write first reads the header sent by the daemon.
 * If that's OK, looks up ticket/callback node by the unique id seen in header.
 * If the callback node contains a handler function, the uio is passed over
 * that.
 */
fuse_device_write first reads the header sent by the daemon.
If that's OK, looks up ticket/callback node by the unique id seen in header.
If the callback node contains a handler function, the uio is passed over
that.
fuse_device_write first reads the header sent by the daemon . If that ' s OK looks up ticket / callback node by the unique id seen in header . If the callback node contains a handler function the uio is passed over that .
static int
fuse_device_write(struct cdev *dev, struct uio *uio, int ioflag)
{
	struct fuse_out_header ohead;
	int err = 0;
	struct fuse_data *data;
	struct fuse_ticket *tick, *x_tick;
	int found = 0;
	FS_DEBUG("resid: %zd, iovcnt: %d, thread: %d\n",
	    uio->uio_resid, uio->uio_iovcnt, uio->uio_td->td_tid);
	err = devfs_get_cdevpriv((void **)&data);
	if (err != 0)
		return (err);
	if (uio->uio_resid < sizeof(struct fuse_out_header)) {
		FS_DEBUG("got less than a header!\n");
		fdata_set_dead(data);
		return (EINVAL);
	}
	if ((err = uiomove(&ohead, sizeof(struct fuse_out_header), uio)) != 0)
		return (err);
	if ((err = fuse_ohead_audit(&ohead, uio))) {
		fdata_set_dead(data);
		return (err);
	}
	fuse_lck_mtx_lock(data->aw_mtx);
	TAILQ_FOREACH_SAFE(tick, &data->aw_head, tk_aw_link,
	    x_tick) {
		FS_DEBUG("bumped into callback #%llu\n",
		    (unsigned long long)tick->tk_unique);
		if (tick->tk_unique == ohead.unique) {
			found = 1;
			fuse_aw_remove(tick);
			break;
		}
	}
	fuse_lck_mtx_unlock(data->aw_mtx);
	if (found) {
		if (tick->tk_aw_handler) {
			FS_DEBUG("pass ticket to a callback\n");
			memcpy(&tick->tk_aw_ohead, &ohead, sizeof(ohead));
			err = tick->tk_aw_handler(tick, uio);
		} else {
			FS_DEBUG("stuff devalidated, so we drop it\n");
		}
		fuse_ticket_drop(tick);
	} else {
		FS_DEBUG("erhm, no handler for this response\n");
		err = EINVAL;
	}
	return (err);
}
static int fuse_device_write ( struct cdev * dev , struct uio * uio , int ioflag ) { struct fuse_out_header ohead ; int err = 0 ; struct fuse_data * data ; struct fuse_ticket * tick , * x_tick ; int found = 0 ; FS_DEBUG ( " \n " , uio -> uio_resid , uio -> uio_iovcnt , uio -> uio_td -> td_tid ) ; err = devfs_get_cdevpriv ( ( void * * ) & data ) ; if ( err != 0 ) return ( err ) ; if ( uio -> uio_resid < sizeof ( struct fuse_out_header ) ) { FS_DEBUG ( " \n " ) ; fdata_set_dead ( data ) ; return ( EINVAL ) ; } if ( ( err = uiomove ( & ohead , sizeof ( struct fuse_out_header ) , uio ) ) != 0 ) return ( err ) ; if ( ( err = fuse_ohead_audit ( & ohead , uio ) ) ) { fdata_set_dead ( data ) ; return ( err ) ; } fuse_lck_mtx_lock ( data -> aw_mtx ) ; TAILQ_FOREACH_SAFE ( tick , & data -> aw_head , tk_aw_link , x_tick ) { FS_DEBUG ( " \n " , ( unsigned long long ) tick -> tk_unique ) ; if ( tick -> tk_unique == ohead . unique ) { found = 1 ; fuse_aw_remove ( tick ) ; break ; } } fuse_lck_mtx_unlock ( data -> aw_mtx ) ; if ( found ) { if ( tick -> tk_aw_handler ) { FS_DEBUG ( " \n " ) ; memcpy ( & tick -> tk_aw_ohead , & ohead , sizeof ( ohead ) ) ; err = tick -> tk_aw_handler ( tick , uio ) ; } else { FS_DEBUG ( " \n " ) ; } fuse_ticket_drop ( tick ) ; } else { FS_DEBUG ( " \n " ) ; err = EINVAL ; } return ( err ) ; }
fuse_device_write first reads the header sent by the daemon.
fuse_device_write first reads the header sent by the daemon .
/*
	 * We check header information (which is redundant) and compare it
	 * with what we see. If we see some inconsistency we discard the
	 * whole answer and proceed on as if it had never existed. In
	 * particular, no pretender will be woken up, regardless the
	 * "unique" value in the header.
	 */ /* Pass stuff over to callback if there is one installed */ /* Looking for ticket with the unique id of header */ /*
			 * We found a callback with proper handler. In this
			 * case the out header will be 0wnd by the callback,
			 * so the fun of freeing that is left for her.
			 * (Then, by all chance, she'll just get that's done
			 * via ticket_drop(), so no manual mucking
			 * around...)
			 */ /* pretender doesn't wanna do anything with answer */ /*
		 * As aw_mtx was not held during the callback execution the
		 * ticket may have been inserted again.  However, this is safe
		 * because fuse_ticket_drop() will deal with refcount anyway.
		 */ /* no callback at all! */