Date: Sun, 11 Sep 2005 17:16:25 GMT From: soc-chenk <soc-chenk@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 83409 for review Message-ID: <200509111716.j8BHGP6P060683@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=83409 Change 83409 by soc-chenk@soc-chenk_leavemealone on 2005/09/11 17:16:20 Many bugfixes Sanitized look User-friendly mounting Tons of docs Submitted by: soc-chenk Affected files ... .. //depot/projects/soc2005/fuse4bsd2/Changelog#2 edit .. //depot/projects/soc2005/fuse4bsd2/IMPLEMENTATION_NOTES#1 add .. //depot/projects/soc2005/fuse4bsd2/README#3 delete .. //depot/projects/soc2005/fuse4bsd2/README.html#1 add .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fmaster.c#2 edit .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.c#3 edit .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.h#2 edit .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse_subr.c#2 edit .. //depot/projects/soc2005/fuse4bsd2/fuselib/fuselib-2.4.0-pre1.diff#1 add .. //depot/projects/soc2005/fuse4bsd2/fuselib/fusermount.c#2 delete .. //depot/projects/soc2005/fuse4bsd2/mount_fusefs/Makefile#2 edit .. //depot/projects/soc2005/fuse4bsd2/mount_fusefs/mount_fusefs.c#3 edit Differences ... ==== //depot/projects/soc2005/fuse4bsd2/Changelog#2 (text+ko) ==== @@ -1,11 +1,147 @@ -2005 09 02 - Release 0.01.1 - - Fix of a small but showstopper error in installation instructions. - Added a missing file. - Added Changelog. +Sun Sep 11 18:45:52 CEST 2005 at node: creo.hu, nick: csaba + * Sanitized fuse.c's look + +Sun Sep 11 14:22:17 CEST 2005 at node: creo.hu, nick: csaba + * Documentation updated + +Sun Sep 11 13:31:47 CEST 2005 at node: creo.hu, nick: csaba + * Module subroutines polished, some bugs were fixed + + * An internal version of strategy was introduced, which takes a filehandle parameter + (so filehandle can be passed on to strategy directly upon buffered I/O). + + * bug causing blocksize of root vnode being zero was corrected + + * mode mismatch of FUSE_OPENs sent by get_filehandle corrected + + * directories open mode is always FREAD (and no other flag) + + * cross-device hardlink requests refused + + +Sun Sep 11 13:27:50 CEST 2005 at node: creo.hu, nick: csaba + * Library patch polished and integrated into repo + + The use of fusermount was eliminated, we open devices directly instead + (in a way which is compatible with mount_fusefs) + +Sun Sep 11 13:20:48 CEST 2005 at node: creo.hu, nick: csaba + * mount_fusefs improved + + mount_fusefs can spawn the daemon by itself + a reduced version, mount_fusefs_safe were added which can't do this + + +Fri Sep 2 18:48:17 CEST 2005 at node: creo.hu, nick: csaba + * added metafiles and fuse_subr.c + +Fri Sep 2 07:15:47 CEST 2005 at node: creo.hu, nick: csaba + * added mount options, fixed access and open mode problems + +Wed Aug 31 22:23:47 CEST 2005 at node: creo.hu, nick: csaba + * refactored filehandle handling + bio write done + + This means "by and large complete" + + +Tue Aug 30 23:21:00 CEST 2005 at node: creo.hu, nick: csaba + * implemented read-only buffered io/mmap stuff + +Sat Aug 27 08:42:52 CEST 2005 at node: creo.hu, nick: csaba + * fixed zero-read bug and fix of zero-write bug, and handling of open flags + +Fri Aug 26 19:50:09 CEST 2005 at node: creo.hu, nick: csaba + * Fixed zero-write bug and compilations errors with no DEBUG + +Fri Aug 26 17:13:54 CEST 2005 at node: creo.hu, nick: csaba + * lookup bug fixed + +Fri Aug 26 12:17:50 CEST 2005 at node: creo.hu, nick: csaba + * Filesystem is USeablE + +Tue Aug 23 20:13:38 CEST 2005 at node: creo.hu, nick: csaba + * readlink implemented, bugs with open and lookup fixed + +Tue Aug 23 00:11:02 CEST 2005 at node: creo.hu, nick: csaba + * read, readdir implemented + +Sat Aug 20 22:05:04 CEST 2005 at node: creo.hu, nick: csaba + * vget/lookup code refactored, minor code cleanups + +Fri Aug 19 05:50:52 CEST 2005 at node: creo.hu, nick: csaba + * implemented lookup + +Tue Aug 16 05:30:21 CEST 2005 at node: creo.hu, nick: csaba + * a trivial mutex-left-locked bugfix + +Tue Aug 16 03:57:52 CEST 2005 at node: creo.hu, nick: csaba + * Makefile bugfix and kicking made more strict + +Tue Aug 16 00:03:13 CEST 2005 at node: creo.hu, nick: csaba + * changed occurrences of fusedummy to fuse + +Mon Aug 15 23:54:23 CEST 2005 at node: creo.hu, nick: csaba + * VFS ops and getattr implemented + + You can now mount the filesystem! + +Wed Aug 10 04:25:16 CEST 2005 at node: creo.hu, nick: csaba + * converted genopnames script from ruby to awk + +Tue Aug 9 09:23:00 CEST 2005 at node: creo.hu, nick: csaba + * smaller changes in genopnames.rb + +Tue Aug 9 00:40:46 CEST 2005 at node: creo.hu, nick: csaba + * Distribution cleanups + + - A more comprehensive Makefile was put together + - Removed fuselib/fuselib.diff as it's not the appropriate place to keep in + sync with Fuse + - Added a concise README + + +Tue Aug 9 00:39:31 CEST 2005 at node: creo.hu, nick: csaba + * Fixed the bug which led to panic when multithreaded daemons were killed + +Sun Aug 7 16:42:37 CEST 2005 at node: creo.hu, nick: csaba + * source tree cleaned up, other bits of were incorporated into this repo + +Sun Aug 7 12:38:23 CEST 2005 at node: creo.hu, nick: csaba + * code cleanup and bugfixes -2005 09 02 - Release 0.01 + Fixed bugs: + - ticket was not cleaned upon dropping, stale info infected its later usage + - it was impossible to know fuse_dev_writer's returned error value for + pretenders using fuse_standard_handler (a dedicated field was added to + fuse_callback_node) + - prettyprintring routine wanted to print body as buffer for bodyless answers + +Sat Aug 6 22:06:57 CEST 2005 at node: creo.hu, nick: csaba + * Full messaging implemented + +Wed Aug 3 18:45:01 CEST 2005 at node: creo.hu, nick: csaba + * fuse_kernel.h is produced from original linux version by a patch + +Tue Aug 2 14:46:50 CEST 2005 at node: creo.hu, nick: csaba + * fat requests (tickets) implemented, stronger oo approach + +Mon Aug 1 21:58:31 CEST 2005 at node: creo.hu, nick: csaba + * just a (non-working) snapshot before ripping data and &a->b's + +Sun Jul 31 16:39:11 CEST 2005 at node: creo.hu, nick: csaba + * minor changes before implementing fat requests + +Sat Jul 30 18:17:39 CEST 2005 at node: creo.hu, nick: csaba + * Communication infrastructure implemented + +Thu Jul 28 22:51:19 CEST 2005 at node: creo.hu, nick: csaba + * code has been broken up to separate files + +Thu Jul 28 15:52:46 CEST 2005 at node: creo.hu, nick: csaba + * Indentation sanitized + +Thu Jul 28 14:45:45 CEST 2005 at node: creo.hu, nick: csaba + * make it able to communicate with real fuse daemons - Initial release. +Tue Jul 26 12:30:13 CEST 2005 at node: creo.hu, nick: csaba + * first working version based on echodev ==== //depot/projects/soc2005/fuse4bsd2/fuse_module/fmaster.c#2 (text+ko) ==== @@ -43,7 +43,6 @@ extern struct fuse_data *fusedev_get_data(struct cdev *fdev); extern int fdisp_wait_answ(struct fuse_dispatcher *fdi); -static void prettyprint(struct fuse_iov *fiov, size_t dlen); static void pp_fuse_entry_out(struct fuse_entry_out *stru); static void pp_fuse_open_out(struct fuse_open_out *stru); static void pp_fuse_write_out(struct fuse_write_out *stru); @@ -290,20 +289,6 @@ ******************************/ static void -prettyprint(struct fuse_iov *fiov, size_t dlen) -{ - static char *pptable[] = { "\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\a", "\\010", "\\t", "\\n", "\\v", "\\f", "\\r", "\\016", "\\017", "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027", "\\030", "\\031", "\\032", "\\e", "\\034", "\\035", "\\036", "\\037", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "\\177", "\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207", "\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217", "\\220", "\\221", "\\222", "\\223", "\\224", "\\225", "\\ 226", "\\227", "\\230", "\\231", "\\232", "\\233", "\\234", "\\235", "\\236", "\\237", "\\240", "\\241", "\\242", "\\243", "\\244", "\\245", "\\246", "\\247", "\\250", "\\251", "\\252", "\\253", "\\254", "\\255", "\\256", "\\257", "\\260", "\\261", "\\262", "\\263", "\\264", "\\265", "\\266", "\\267", "\\270", "\\271", "\\272", "\\273", "\\274", "\\275", "\\276", "\\277", "\\300", "\\301", "\\302", "\\303", "\\304", "\\305", "\\306", "\\307", "\\310", "\\311", "\\312", "\\313", "\\314", "\\315", "\\316", "\\317", "\\320", "\\321", "\\322", "\\323", "\\324", "\\325", "\\326", "\\327", "\\330", "\\331", "\\332", "\\333", "\\334", "\\335", "\\336", "\\337", "\\340", "\\341", "\\342", "\\343", "\\344", "\\345", "\\346", "\\347", "\\350", "\\351", "\\352", "\\353", "\\354", "\\355", "\\356", "\\357", "\\360", "\\361", "\\362", "\\363", "\\364", "\\365", "\\366", "\\367", "\\370", "\\371", "\\372", "\\373", "\\374", "\\375", "\\376", "\\377" }; - int i; - - uprintf("\""); - for (i=0; i < MIN(fiov->len, dlen); i++) { - uprintf("%s",pptable[((uint8_t *)fiov->base)[i]]); - } - uprintf("\""); - uprintf("%s\n", dlen < fiov->len ? "..." : ""); -} - -static void pp_fuse_entry_out(struct fuse_entry_out *stru) { fuprintf("fuse_entry_out -- nodeid: %llu, generation: %llu, entry_valid: %llu, attr_valid: %llu, entry_valid_nsec: %i, attr_valid_nsec: %i, struct attr...\n", @@ -360,7 +345,7 @@ pp_buf(struct fuse_iov *fiov) { fuprintf("buffer -- "); - prettyprint(fiov, 80); + fprettyprint(fiov, 80); } static void ==== //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.c#3 (text+ko) ==== @@ -47,7 +47,8 @@ #define __static static #endif -MALLOC_DEFINE(M_FUSEMSG, "fuse messaging", "buffer for fuse messaging related things"); +MALLOC_DEFINE(M_FUSEMSG, "fuse messaging", + "buffer for fuse messaging related things"); static uint32_t fuse_useco = 0; static struct mtx fuse_useco_mtx; @@ -70,11 +71,6 @@ .d_read = fusedev_read, .d_write = fusedev_write, .d_version = D_VERSION, -/* .d_flags = D_PSEUDO | D_NEEDGIANT, - */ - /* XXX do we need Giant? - * However, it pretty much seems like we don't need D_PSEUDO - */ }; @@ -97,7 +93,6 @@ #if FMASTER __static int fuse_callbn_wait_answer(struct fuse_callback_node *caliban); #endif -__static __inline size_t fuse_response_body_len(struct uio *uio); __static __inline int fuse_callbn_pull_uio(struct fuse_callback_node *caliban, struct uio *uio); __static __inline int fuse_callbn_get_opcode(struct fuse_callback_node *caliban); @@ -248,12 +243,14 @@ fuse_callbn_teardown(struct fuse_callback_node *caliban) { - /* It is important to use NFREE for freeing - pointer elements of a fuse_callback_node - when they are in use (and being dropped), - so that when the end of its lifecycle comes, - we can know whether those elements should be - freed */ + /* + * It is important to use NFREE for freeing + * pointer elements of a fuse_callback_node + * when they are in use (and being dropped), + * so that when the end of its lifecycle comes, + * we can know whether those elements should be + * freed + */ fuse_iov_teardown(&caliban->params); mtx_destroy(&caliban->answer_mtx); @@ -314,36 +311,22 @@ out: mtx_unlock(&caliban->answer_mtx); - KASSERT(err || fuse_callbn_answered(caliban), ("fuse requester was woken up but still no answer")); + KASSERT(err || fuse_callbn_answered(caliban), + ("fuse requester was woken up but still no answer")); return (err); } -__static __inline size_t -fuse_response_body_len(struct uio *uio) -{ - - /* It seems that this just boils down to reading the uio_resid field. - * XXX this function is just line noise. Should be eliminated sooner or later. - */ - - return (uio->uio_resid); -} - __static __inline int fuse_callbn_pull_uio(struct fuse_callback_node *caliban, struct uio *uio) { int err = 0; size_t len; - //DEBUG("getting at next uio item\n"); - len = fuse_response_body_len(uio); - //DEBUG("response len: %d\n", len); + len = uio->uio_resid; if (len) { - //DEBUG("adjusting resp\n"); if (caliban->resp_bufdata) { - //KASSERT(caliban->resp_bufsize >= len, ("inconsistency between response body len and size of target buffer chunk")); caliban->resp_bufsize = len; err = uiomove(caliban->resp_bufdata, len, uio); } else { @@ -458,16 +441,19 @@ { struct fuse_data *data; - MALLOC(data, struct fuse_data *, sizeof(struct fuse_data), M_FUSEMSG, M_WAITOK | M_ZERO); + MALLOC(data, struct fuse_data *, sizeof(struct fuse_data), M_FUSEMSG, + M_WAITOK | M_ZERO); /* Setting up fields of mine */ mtx_init(&data->msg_mtx, "mutex for fuse message list", NULL, MTX_DEF); cv_init(&data->msg_cv, "cv to wake up fusedev_read"); STAILQ_INIT(&data->fmsg_head); - mtx_init(&data->ticket_mtx, "mutex for the fuse ticketer", NULL, MTX_DEF); + mtx_init(&data->ticket_mtx, "mutex for the fuse ticketer", NULL, + MTX_DEF); STAILQ_INIT(&data->freetickets_head); TAILQ_INIT(&data->busytickets_head); - mtx_init(&data->callback_mtx, "mutex for the fuse callback list", NULL, MTX_DEF); + mtx_init(&data->callback_mtx, "mutex for the fuse callback list", NULL, + MTX_DEF); TAILQ_INIT(&data->fcallb_head); data->ticketer = 0; data->freeticket_counter = 0; @@ -517,26 +503,30 @@ /* fuse_ticket methods ==> */ -/* Tickets are carriers of communication with a fuse daemon. +/* + * Tickets are carriers of communication with a fuse daemon. * Tickets have a unique id, which should be kept unique * among synchronously used tickets. The everyday routine: * + Syscall handler gets one by ticket_fetch() * (then, behind the scenes, either a fresh one is allocated * or a cached old one is put into use again) - * + Sets up data to be passed to the daemon (there is a message node attached to the ticket) + * + Sets up data to be passed to the daemon + * (there is a message node attached to the ticket) * + If she knows that answer will come, sets up the callback node * attached to the ticket, and enqueues it to the callback nodes' list * + enqueues the message and kicks fusedev_read() * + if daemon gives a proper answer, it will contain the unique id, by which * fusedev_write() can pick the pre-prepared callback node and run it. - * There is the standard callback handler which just awakes the syscall handler - * who then waits for the response, deal with it by herself. - * Another option is to write a full-fledged callback handler which does all data processing - * within fusedev_write()'s thread. Or, if the answer is uninteresting, a NULL handler can be used. - * + After answer has been consumed, the handler or anyone to whom the control has been passed supposed to - * call ticket_drop() - * (then, behind the scenes, either the ticket is destroyed, or put into cache) -*/ + * There is the standard callback handler which just awakes the syscall + * handler who then waits for the response, deal with it by herself. + * Another option is to write a full-fledged callback handler which does all + * data processing within fusedev_write()'s thread (although we never do + * this). Or, if the answer is uninteresting, a NULL handler can be used. + * + After answer has been consumed, the handler or anyone to whom the control + * has been passed supposed to call ticket_drop() + * (then, behind the scenes, either the ticket is destroyed, or put into + * cache) + */ static struct fuse_ticket * @@ -544,7 +534,8 @@ { struct fuse_ticket *tick; - MALLOC(tick, struct fuse_ticket *, sizeof(*tick), M_FUSEMSG, M_WAITOK | M_ZERO); + MALLOC(tick, struct fuse_ticket *, sizeof(*tick), M_FUSEMSG, + M_WAITOK | M_ZERO); tick->unique = data->ticketer++; tick->data = data; @@ -576,8 +567,12 @@ { int die = 0; - /* XXX limit below should be tunable by a sysctl */ - if (FUSE_MAX_STORED_FREE_TICKETS && FUSE_MAX_STORED_FREE_TICKETS <= tick->data->freeticket_counter) { + /* + * Limit below should be tunable by a sysctl? + * Probably not worth for the effort. + */ + if (FUSE_MAX_STORED_FREE_TICKETS && + FUSE_MAX_STORED_FREE_TICKETS <= tick->data->freeticket_counter) { die = 1; DEBUG("ticket will die\n"); } else @@ -617,20 +612,15 @@ DEBUG("fetching ticket\n"); if (data->freeticket_counter == 0) { - //DEBUG("no tick :(\n"); tick = ticket_alloc(data); - //DEBUG("make then one\n"); mtx_lock(&data->ticket_mtx); } else { mtx_lock(&data->ticket_mtx); - //DEBUG("pop a tick\n"); tick = fdata_pop_ftick(data); KASSERT(tick, ("no free ticket available tho counter said there is")); } - //DEBUG("push into busy ones\n"); ticket_push_btick(tick); - //DEBUG("unlock mtx\n"); mtx_unlock(&data->ticket_mtx); return (tick); @@ -651,11 +641,8 @@ { tick->callbn.handler = handler; - //DEBUG("lock callb mtx\n"); mtx_lock(&tick->data->callback_mtx); - //DEBUG("insert callb list\n"); fuse_callbn_push(&tick->callbn); - //DEBUG("unlock callb mtx\n"); mtx_unlock(&tick->data->callback_mtx); } @@ -669,7 +656,6 @@ fuse_msgn_push(&tick->msgn); DEBUG("ring the bell\n"); cv_signal(&tick->data->msg_cv); - //DEBUG("bell sounded\n"); mtx_unlock(&tick->data->msg_mtx); } @@ -680,17 +666,18 @@ fuprintf("\tOut header -- len: %i, error: %i, unique: %llu; iovecs: %d\n", ohead->len, ohead->error, ohead->unique, uio->uio_iovcnt); - if (fuse_response_body_len(uio) + sizeof(struct fuse_out_header) != ohead->len) { + if (uio->uio_resid + sizeof(struct fuse_out_header) != ohead->len) { fuprintf("Format error: body size differs from size claimed by header\n"); return (EINVAL); } - if (fuse_response_body_len(uio) && ohead->error) { + if (uio->uio_resid && ohead->error) { fuprintf("Format error: non zero error but message had a body\n"); return (EINVAL); } - ohead->error = -(ohead->error); /* Sanitize the linuxism of negative errnos */ + /* Sanitize the linuxism of negative errnos */ + ohead->error = -(ohead->error); return (0); } @@ -748,11 +735,15 @@ err = blen == sizeof(struct fuse_open_out) ? 0 : EINVAL; break; case FUSE_READ: - /* we do whatever crazyness is needed to read the original + /* + * we do whatever crazyness is needed to read the original * request size, starting from the callback node, and then * check whether available data doesn't grow over that. */ - err = ((struct fuse_read_in *)((char *)caliban->ticket->msgn.msg.base + sizeof(struct fuse_in_header)))->size >= blen ? 0 : EINVAL; + err = ((struct fuse_read_in *)( + (char *)caliban->ticket->msgn.msg.base + + sizeof(struct fuse_in_header) + ))->size >= blen ? 0 : EINVAL; break; case FUSE_WRITE: err = blen == sizeof(struct fuse_write_out) ? 0 : EINVAL; @@ -788,7 +779,10 @@ err = blen == sizeof(struct fuse_open_out) ? 0 : EINVAL; break; case FUSE_READDIR: - err = ((struct fuse_read_in *)((char *)caliban->ticket->msgn.msg.base + sizeof(struct fuse_in_header)))->size >= blen ? 0 : EINVAL; + err = ((struct fuse_read_in *)( + (char *)caliban->ticket->msgn.msg.base + + sizeof(struct fuse_in_header) + ))->size >= blen ? 0 : EINVAL; break; case FUSE_RELEASEDIR: err = blen == 0 ? 0 : EINVAL; @@ -826,7 +820,9 @@ } while (0) static __inline void -fuse_setup_ihead(struct fuse_in_header *ihead, struct fuse_ticket *tick, uint64_t nid, enum fuse_opcode op, struct thread* td, struct ucred *cred) +fuse_setup_ihead(struct fuse_in_header *ihead, struct fuse_ticket *tick, + uint64_t nid, enum fuse_opcode op, struct thread* td, + struct ucred *cred) { ihead->len = 0; /* actually not used by lib */ ihead->unique = tick->unique; @@ -861,7 +857,8 @@ * ********************/ -/* fuse_standard_handler just pulls in data and wakes up pretender. +/* + * fuse_standard_handler just pulls in data and wakes up pretender. * Doesn't try to interpret data, that's left for the pretender. * Though might do a basic size verification before the pull-in takes place */ @@ -874,7 +871,7 @@ if (caliban->ohead->error) goto out; - if ((err = fuse_body_audit(caliban, fuse_response_body_len(uio)))) + if ((err = fuse_body_audit(caliban, uio->uio_resid))) goto out; if ((err = fuse_callbn_pull_uio(caliban, uio))) goto out; @@ -883,8 +880,8 @@ mtx_lock(&caliban->answer_mtx); if (fuse_callbn_answered(caliban)) /* The requester was interrupted and she set the "answered" flag - * to notify us. In this case, we don't have to care about anything, - * just drop the ticket and get out as fast as we can. + * to notify us. In this case, we don't have to care about + * anything, just drop the ticket and get out as fast as we can. */ dropflag = 1; else { @@ -905,8 +902,8 @@ * ****************************/ - -/* Resources are set up on a per-open basis +/* + * Resources are set up on a per-open basis */ static int fusedev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) @@ -959,9 +956,10 @@ return(0); } -/* fusedev_read hangs on the queue of VFS messages. - When it's notified that there is a new one, it picks that and - passes up to the daemon +/* + * fusedev_read hangs on the queue of VFS messages. + * When it's notified that there is a new one, it picks that and + * passes up to the daemon */ int fusedev_read(struct cdev *dev, struct uio *uio, int ioflag) @@ -976,27 +974,24 @@ mtx_lock(&data->msg_mtx); if (fdata_kick_get(data)) { - DEBUG("we know early on that reader should be kicked so we don't wait for newsn\n"); + DEBUG("we know early on that reader should be kicked so we don't wait for news\n"); mtx_unlock(&data->msg_mtx); return (ENODEV); } if ( ! (fmsgn = fdata_pop_msg(data))) { - //DEBUG("FR1,%d\n", uio->uio_td->td_tid); err = cv_wait_sig(&data->msg_cv, &data->msg_mtx); if (err != 0) { - //DEBUG("FR2,%d\n", uio->uio_td->td_tid); mtx_unlock(&data->msg_mtx); - //DEBUG("FR3,%d\n", uio->uio_td->td_tid); return err; } - //DEBUG("FR4,%d\n", uio->uio_td->td_tid); fmsgn = fdata_pop_msg(data); } mtx_unlock(&data->msg_mtx); if (fdata_kick_get(data)) { - /* somebody somewhere -- eg., umount routine -- + /* + * somebody somewhere -- eg., umount routine -- * wants this liaison finished off */ DEBUG("reader is to be sacked\n"); @@ -1007,43 +1002,51 @@ return (ENODEV); /* This should make the daemon get off of us */ } if (! fmsgn) { - /* We can get here if fuse daemon suddenly terminates, + /* + * We can get here if fuse daemon suddenly terminates, * eg, by being hit by a SIGKILL * -- and some other cases, too, tho not totally clear, when + * (cv_signal signals the whole process ?) */ DEBUG("no message on thread #%d\n", uio->uio_td->td_tid); return (EINTR); } DEBUG("message got on thread #%d\n", uio->uio_td->td_tid); - KASSERT(fmsgn->msg_bufdata || fmsgn->msg_bufsize == 0, ("non-null buf pointer with positive size")); - - /* Why not ban mercilessly stupid daemons who can't keep up with us? + KASSERT(fmsgn->msg_bufdata || fmsgn->msg_bufsize == 0, + ("non-null buf pointer with positive size")); + /* + * Why not ban mercilessly stupid daemons who can't keep up with us? * (There is no much use of a partial read here...) */ if (uio->uio_resid < fmsgn->msg.len) { - //fdata_kick_set(data); data->dataflag |= FU_KICK; err = ENODEV; } if (! err) - err = uiomove(fmsgn->msg.base, MIN(uio->uio_resid, fmsgn->msg.len), uio); + err = uiomove(fmsgn->msg.base, + MIN(uio->uio_resid, fmsgn->msg.len), uio); if (! err && fmsgn->msg_bufsize != 0) - err = uiomove(fmsgn->msg_bufdata, MIN(uio->uio_resid, fmsgn->msg_bufsize), uio); + err = uiomove(fmsgn->msg_bufdata, + MIN(uio->uio_resid, fmsgn->msg_bufsize), uio); - /* fusedev_read will drop "invalidated" tickets -- - for cases when no reply is expected + /* + * fusedev_read will drop "invalidated" tickets + * (used when the one who inserted the message thinks the daemon + * won't aswer ) */ ticket_drop_invalid(fmsgn->ticket); return(err); } -/* fusedev_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. +/* + * fusedev_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 fusedev_write(struct cdev *dev, struct uio *uio, int ioflag) @@ -1065,14 +1068,18 @@ return (EINVAL); } - MALLOC(ohead, struct fuse_out_header *, sizeof(struct fuse_out_header), M_TEMP, M_WAITOK); + MALLOC(ohead, struct fuse_out_header *, sizeof(struct fuse_out_header), + M_TEMP, M_WAITOK); if ((err = uiomove(ohead, sizeof(struct fuse_out_header), uio)) != 0) goto drophead; - /* 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. + /* + * 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. */ if ((err = fuse_ohead_audit(ohead, uio))) goto drophead; @@ -1083,9 +1090,10 @@ /* Looking for ticket with the unique id of header */ mtx_lock(&data->callback_mtx); - /* Note: actual type of container shows up (that is, not hidden by the closet oo) */ - TAILQ_FOREACH_SAFE(fcallbn, &data->fcallb_head, fcallb_link, fcallbn_temp) { - fuprintf("bumped into callback #%llu\n", fcallbn->ticket->unique); + TAILQ_FOREACH_SAFE(fcallbn, &data->fcallb_head, fcallb_link, + fcallbn_temp) { + fuprintf("bumped into callback #%llu\n", + fcallbn->ticket->unique); if (fcallbn->ticket->unique == ohead->unique) { found = 1; fuse_callbn_remove(fcallbn); @@ -1097,11 +1105,11 @@ if (found) { if (fcallbn->handler) { /* 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...) + * 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...) */ fcallbn->ohead = ohead; err = fcallbn->handler(fcallbn, uio); @@ -1114,24 +1122,25 @@ } } else { /* no callback at all! */ - /* this is BAD: - + if unique id was generated by fuse userspace, - that's way too bogus. Userspace should only - pass unique ids back and forth. - + else we generated the unique id by ticket_fetch() - somewhere in the foggy past. - Now that ticket is either - + dropped, which means it could have been - reused by now, and then this answer we work - with would be misdelivered (it's just luck that - it's not the case now) - + not dropped, which means it's either - + lost: will be kept on busy list for the - whole lifetime - + someone will drop it randomly without - any event based triggering (this would be - the place for such a thing), which is just - nonsense. + /* + * this is BAD: + * + if unique id was generated by fuse userspace, + * that's way too bogus. Userspace should only + * pass unique ids back and forth. + * + else we generated the unique id by ticket_fetch() + * somewhere in the foggy past. + * Now that ticket is either + * + dropped, which means it could have been + * reused by now, and then this answer we work + * with would be misdelivered (it's + * just luck that it's not the case now) + * + not dropped, which means it's either + * + lost: will be kept on busy list for + * the whole lifetime + * + someone will drop it randomly without + * any event based triggering (this + * would be the place for such a thing), + * which is just nonsense. */ fuprintf("erhm, no handler for this response\n"); goto drophead; @@ -1174,19 +1183,22 @@ /* aka stage 2 */ static void -fdisp_prepare_msg(struct fuse_dispatcher *fdip, enum fuse_opcode op, uint64_t nid, struct thread *td, struct ucred *cred) +fdisp_prepare_msg(struct fuse_dispatcher *fdip, enum fuse_opcode op, + uint64_t nid, struct thread *td, struct ucred *cred) { if (! fdip->tick) fdip->tick = ticket_fetch(fdip->data); - FUSE_DIMALLOC(&fdip->tick->msgn.msg, fdip->finh, fdip->indata, fdip->iosize); + FUSE_DIMALLOC(&fdip->tick->msgn.msg, fdip->finh, + fdip->indata, fdip->iosize); fuse_setup_ihead(fdip->finh, fdip->tick, nid, op, td, cred); } /* prev. two in one */ static __inline int -fdisp_prepare_all(struct fuse_dispatcher *fdip, enum fuse_opcode op, struct vnode *vp, struct thread *td, struct ucred *cred) +fdisp_prepare_all(struct fuse_dispatcher *fdip, enum fuse_opcode op, + struct vnode *vp, struct thread *td, struct ucred *cred) { int err = 0; @@ -1218,14 +1230,16 @@ mtx_lock(&fdip->tick->callbn.answer_mtx); if (fuse_callbn_answered(&fdip->tick->callbn)) { - /* Just between noticing the interrupt and getting here, + /* + * Just between noticing the interrupt and getting here, * the standard handler has completed his job. * So we drop the ticket and exit as usual. */ mtx_unlock(&fdip->tick->callbn.answer_mtx); goto out; } else { - /* So we were faster than the standard handler. + /* + * So we were faster than the standard handler. * Then by setting the answered flag we get *him* * to drop the ticket. */ @@ -1233,16 +1247,19 @@ fuse_callbn_set_answered(&fdip->tick->callbn); mtx_unlock(&fdip->tick->callbn.answer_mtx); #if ! DONT_TRY_HARD_PREVENT_IO_IN_VAIN - /* If we are willing to pay with one more locking, - * we can save on I/O by getting the device write handler + /* + * If we are willing to pay with one more locking, we + * can save on I/O by getting the device write handler * to drop the ticket. That is, if we are fast enough, * the standard handler -- who does the uiomove -- - * won't even be called. (No guarantee though for being fast.) + * won't even be called. (No guarantee though for + * being fast.) */ DEBUG2G("interrupted, now trying to prevent io in vain (I'll tell you if it succeeds...)\n"); mtx_lock(&fdip->data->callback_mtx); - TAILQ_FOREACH(fcallbn, &fdip->data->fcallb_head, fcallb_link) { + TAILQ_FOREACH(fcallbn, &fdip->data->fcallb_head, + fcallb_link) { if (fcallbn->ticket == fdip->tick) { if (fdip->tick->age == age) { DEBUG2G("preventing io in vain succeeded\n"); @@ -1260,7 +1277,8 @@ } if (fdip->tick->callbn.errno) { - /* Error with messaging, the VFS layer + /* + * Error with messaging, the VFS layer * won't be particularly interested about * its exact nature */ @@ -1269,7 +1287,8 @@ } if ((err = fdip->tick->callbn.ohead->error)) { - /* This means a "proper" fuse syscall 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 @@ -1296,7 +1315,8 @@ /* stage 1, 2, 3 together for the simple case when only a header is sent up */ static __inline int -fdisp_simple_putget(struct fuse_dispatcher *fdip, enum fuse_opcode op, struct vnode *vp, struct thread *td, struct ucred *cred) +fdisp_simple_putget(struct fuse_dispatcher *fdip, enum fuse_opcode op, + struct vnode *vp, struct thread *td, struct ucred *cred) { int err = 0; @@ -1331,7 +1351,7 @@ fiio = fdi.answ; /* XXX is the following check adequate? */ if (fiio->major < 7) { - DEBUG("userpace version too low\n"); + DEBUG2G("userpace version too low\n"); err = EPROTONOSUPPORT; } @@ -1340,17 +1360,14 @@ } static __inline int -fuse_send_forget(struct mount *mp, struct thread *td, struct ucred *cred, uint64_t nodeid, uint64_t nlookup, struct fuse_dispatcher *fdip) +fuse_send_forget(struct mount *mp, struct thread *td, struct ucred *cred, + uint64_t nodeid, uint64_t nlookup, + struct fuse_dispatcher *fdip) { struct fuse_forget_in *ffi; int err = 0; DEBUG("sending FORGET with %llu lookups\n", nlookup); -#if 0 & _DEBUG2G - DEBUG2G("=============>\n"); - kdb_backtrace(); - DEBUG2G("<=============\n"); -#endif fdip->iosize = sizeof(*ffi); if (fdip->tick) { @@ -1368,8 +1385,10 @@ ticket_invalidate(fdip->tick); fuse_insert_message(fdip->tick); - /* I think we can unlock here -- users of this routine won't wanna - * go and fetch a new ticket... let's just save them from dealing with this lock + /* + * I think we can unlock here -- users of this routine won't wanna + * go and fetch a new ticket... + * let's just save them from dealing with this lock */ sx_sunlock(fdip->slock); @@ -1390,7 +1409,7 @@ static vfs_unmount_t fuse_unmount; static vfs_root_t fuse_root; static vfs_statfs_t fuse_statfs; -//static vfs_vget_t fuse_vget; +/* static vfs_vget_t fuse_vget; */ static int fuse_vget_i(struct mount *mp, struct thread *td, uint64_t nodeid, enum vtype vtyp, struct vnode **vpp); static __inline void fat2vat(struct mount *mp, struct fuse_attr *fat, struct vattr *vap); #if __FreeBSD_version >= 600000 @@ -1406,20 +1425,18 @@ static __inline void fuse_vnode_kick(struct vnode *vp); static vop_access_t fuse_access; static __inline int fuse_access_by_attr(struct mount *mp, struct vattr *vap, mode_t mode, struct ucred *cred); -//static vop_cachedlookup_t fuse_lookup; +/* static vop_cachedlookup_t fuse_lookup; */ static vop_lookup_t fuse_lookup; -//static vop_pathconf_t fuse_pathconf; +/* static vop_pathconf_t fuse_pathconf; */ static int iterate_filehandles(struct vnode *vp, struct thread *td, struct ucred *cred, int mode, fuse_metrics_t fmetr, void *param); static int fuse_standard_metrics(struct vnode *vp, struct thread *td, struct ucred *cred, int mode, struct fuse_filehandle *fufh, void *param); static struct fuse_filehandle *get_filehandle(struct vnode *vp, struct thread *td, struct ucred *cred, int mode); static vop_open_t fuse_open; static int fuse_send_release(struct vnode *vp, struct thread *td, struct ucred *cred, struct fuse_filehandle *fufh, int flags); static fo_close_t fuse_close_f; -static int fuse_read_directbackend(struct vnode *vp, uint64_t fuse_fh, struct uio *uio, struct ucred *cred, struct thread *td, enum fuse_opcode op, fuse_buffeater_t *buffe, void *param); -static int fuse_read_biobackend(struct vnode *vp, uint64_t fuse_fh, struct uio *uio, struct ucred *cred, struct thread *td, enum fuse_opcode op, fuse_buffeater_t *buffe, void *param); -//static vop_read_t fuse_read; +static int fuse_read_directbackend(struct vnode *vp, struct fuse_filehandle *fufh, struct uio *uio, struct ucred *cred, struct thread *td, enum fuse_opcode op, fuse_buffeater_t *buffe, void *param); +static int fuse_read_biobackend(struct vnode *vp, struct fuse_filehandle *fufh, struct uio *uio, struct ucred *cred, struct thread *td, enum fuse_opcode op, fuse_buffeater_t *buffe, void *param); static fo_rdwr_t fuse_read_f; -//static vop_close_t fuse_close; static vop_readdir_t fuse_readdir; static vop_readlink_t fuse_readlink; static int fuse_newentry_backend(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize, enum vtype vtyp); @@ -1439,10 +1456,10 @@ static fuse_metrics_t fuse_fsync_filehandle; static vop_fsync_t fuse_fsync; static int fuse_write_directbackend(struct vnode *vp, uint64_t fh_id, struct uio *uio, struct ucred *cred, struct thread *td); -static int fuse_write_biobackend(struct vnode *vp, struct uio *uio, struct ucred *cred, struct thread *td); //;, size_t fsize, int ioflag); +static int fuse_write_biobackend(struct vnode *vp, struct uio *uio, struct ucred *cred, struct thread *td); static fo_rdwr_t fuse_write_f; +static int fuse_strategy_i(struct vnode *vp, struct buf *bp, struct fuse_filehandle *fufh); static vop_strategy_t fuse_strategy; -//static vop_getpages_t fuse_getpages; static vop_bmap_t fuse_bmap; static vop_print_t fuse_print; @@ -1454,8 +1471,8 @@ .vfs_unmount = fuse_unmount, .vfs_root = fuse_root, .vfs_statfs = fuse_statfs, - //.vfs_vget = fuse_vget, - //.vfs_sync = vfs_stdsync, + /* .vfs_vget = fuse_vget, + .vfs_sync = vfs_stdsync, */ }; #if __FreeBSD_version >= 600000 @@ -1469,9 +1486,6 @@ .vop_cachedlookup = */ fuse_lookup, //.vop_pathconf = fuse_pathconf, .vop_open = fuse_open, - //.vop_read = fuse_read, - //.vop_close = fuse_close, - //.vop_close = VOP_PANIC, .vop_readdir = fuse_readdir, .vop_readlink = fuse_readlink, .vop_mknod = fuse_mknod, @@ -1485,7 +1499,6 @@ .vop_setattr = fuse_setattr, .vop_fsync = fuse_fsync, .vop_strategy = fuse_strategy, - //.vop_getpages = fuse_getpages, .vop_bmap = fuse_bmap, .vop_print = fuse_print, }; @@ -1515,20 +1528,24 @@ static fuse_buffeater_t fuse_dir_buffeater; -/* As I don't use the name cache, I can muck with the v_dd field. - (First I tried to use a private field but v_dd has to be set - as vn_fullpath1() of vfs_cache.c b0rks without it, and __getcwd() - relies on that function +/* + * As I don't use the name cache, I can muck with the v_dd field. + * (First I tried to use a private field but v_dd has to be set + * as vn_fullpath1() of vfs_cache.c b0rks without it, and __getcwd() + * relies on that function */ -#define GETPARENT(pvp, vp) \ -do { \ - KASSERT((vp)->v_dd != (vp) || VTOI((vp)) == FUSE_ROOT_INODE, ("self-parented non-root")); \ - (pvp) = (vp)->v_dd; \ +#define GETPARENT(pvp, vp) \ +do { \ + KASSERT((vp)->v_dd != (vp) || VTOI((vp)) == FUSE_ROOT_INODE, \ + ("self-parented non-root")); \ >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509111716.j8BHGP6P060683>