Date: Thu, 13 Oct 2005 21:59:52 GMT From: soc-chenk <soc-chenk@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 85235 for review Message-ID: <200510132159.j9DLxq2n088776@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=85235 Change 85235 by soc-chenk@soc-chenk_leavemealone on 2005/10/13 21:59:09 make fmaster devices work again Submitted by: soc-chenk Affected files ... .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fmaster.c#3 edit .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.c#14 edit .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.h#7 edit Differences ... ==== //depot/projects/soc2005/fuse4bsd2/fuse_module/fmaster.c#3 (text+ko) ==== @@ -8,6 +8,7 @@ #include <sys/condvar.h> #include <sys/queue.h> #include <sys/sx.h> +#include <sys/proc.h> #include "fuse.h" @@ -25,11 +26,11 @@ extern void fuse_iov_adjust(struct fuse_iov *fiov, size_t size); extern void ticket_invalidate(struct fuse_ticket *tick); extern void fuse_insert_message(struct fuse_ticket *tick); +extern void fdata_destroy(struct fuse_data *data); extern int fuse_callbn_get_opcode(struct fuse_callback_node *caliban); extern int fuse_callbn_pull_uio(struct fuse_callback_node *caliban, struct uio *uio); extern int fuse_callbn_wait_answer(struct fuse_callback_node *caliban); extern struct fuse_iov *fuse_callbn_resp(struct fuse_callback_node *caliban); -extern size_t fuse_response_body_len(struct uio *uio); extern void ticket_drop(struct fuse_ticket *tick); extern void fuse_insert_callback(struct fuse_ticket *tick, fuse_handler_t *handler); extern int fuse_body_audit(struct fuse_callback_node *caliban, size_t blen); @@ -70,6 +71,9 @@ // .d_read = fmaster_read, .d_write = fmaster0_write, .d_version = D_VERSION +#if ! DO_GIANT_MANUALLY + .d_flags = D_NEEDGIANT, +#endif }, { .d_open = fmaster_open, @@ -78,6 +82,9 @@ // .d_read = fmaster_read, .d_write = fmaster1_write, .d_version = D_VERSION +#if ! DO_GIANT_MANUALLY + .d_flags = D_NEEDGIANT, +#endif }, { .d_open = fmaster_open, @@ -86,6 +93,9 @@ // .d_read = fmaster_read, .d_write = fmaster2_write, .d_version = D_VERSION +#if ! DO_GIANT_MANUALLY + .d_flags = D_NEEDGIANT, +#endif }, { .d_open = fmaster_open, @@ -94,6 +104,9 @@ // .d_read = fmaster_read, .d_write = fmaster3_write, .d_version = D_VERSION +#if ! DO_GIANT_MANUALLY + .d_flags = D_NEEDGIANT, +#endif }, { .d_open = fmaster_open, @@ -102,6 +115,9 @@ // .d_read = fmaster_read, .d_write = fmaster3_write, .d_version = D_VERSION +#if ! DO_GIANT_MANUALLY + .d_flags = D_NEEDGIANT, +#endif } }; @@ -113,39 +129,73 @@ ******************************/ int -fmaster_open(struct cdev *dev, int oflags, int devtype, struct thread *p) +fmaster_open(struct cdev *dev, int oflags, int devtype, struct thread *td) { - uprintf("Opened device \"fmaster\" successfully.\n"); +#if DO_GIANT_MANUALLY + mtx_lock(&Giant); +#endif + if (fuse_useco < 0) { + /* Module unload is going on */ +#if DO_GIANT_MANUALLY + mtx_unlock(&Giant); +#endif + DEBUG2G("caught in the middle of unload\n"); + return (ENOENT); + } + fuse_useco++; +#if DO_GIANT_MANUALLY + mtx_unlock(&Giant); +#endif + + DEBUG2G("Opened device \"fmaster\" (that of minor %d) successfully on thread %d.\n", + minor(dev), td->td_tid); + return(0); } int -fmaster_close(struct cdev *dev, int fflag, int devtype, struct thread *p) +fmaster_close(struct cdev *dev, int fflag, int devtype, struct thread *td) { - uprintf("Closing device \"fmaster.\"\n"); + fuse_useco--; + + DEBUG2G("Closed device \"fmaster\" (that of minor %d) successfully on thread %d.\n", + minor(dev), td->td_tid); + return(0); } -#define FMASTER_COMMON_BLAHBLAH \ +#if DO_GIANT_MANUALLY && ! USE_FUSE_LOCK +#define FMASTER_LOCK mtx_lock(&Giant) +#define FMASTER_UNLOCK mtx_unlock(&Giant) +#else +#define FMASTER_LOCK FUSE_LOCK +#define FMASTER_UNLOCK FUSE_UNLOCK +#endif + + +#define FMASTER_COMMON_INBLAHBLAH \ int err = 0; \ struct fuse_ticket *tick; \ size_t len; \ struct fuse_in_header *ihead; \ struct cdev *fusedev; \ - struct sx *slock; \ struct fuse_data *data; \ \ - if (! (fusedev = LIST_FIRST(&fuseclones->head))) \ + FMASTER_LOCK; \ + if (! (fusedev = LIST_FIRST(&fuseclones->head))) { \ + FMASTER_UNLOCK; \ return (ENXIO); \ - \ - slock = fusedev_get_lock(fusedev); \ + } \ \ - sx_slock(slock); \ if (! (data = fusedev_get_data(fusedev))) { \ + FMASTER_UNLOCK; \ uprintf("first fuse device is not in use\n"); \ err = ENXIO; \ goto out; \ } \ + data->mntco++; \ + dev_ref(fusedev); \ + FMASTER_UNLOCK; \ \ len = uio->uio_iov->iov_len; \ \ @@ -169,22 +219,36 @@ ihead = (struct fuse_in_header *)tick->msgn.msg.base; \ ihead->unique = tick->unique; -/* example how a syscall handler routine can send a request when answer is ignorable +#define FMASTER_COMMON_OUTBLAHBLAH \ +out: \ + if (data) { \ + data->mntco--; \ + FMASTER_LOCK; \ + if (data->mntco == 0 && \ + ! (data->dataflag & FDAT_OPENED)) { \ + fusedev->si_drv1 = NULL; \ + fdata_destroy(data); \ + } \ + FMASTER_UNLOCK; \ + dev_rel(fusedev); \ + } \ + return (err); + +/* + * example how a syscall handler routine can send a request when answer is ignorable */ int fmaster0_write(struct cdev *dev, struct uio *uio, int ioflag) { - FMASTER_COMMON_BLAHBLAH /* style(9) don't say you shouldn't do this ;P */ + FMASTER_COMMON_INBLAHBLAH /* style(9) don't say you shouldn't do this ;P */ /* Hey, I mean it's demo code... */ fuse_insert_callback(tick, NULL); fuse_insert_message(tick); -out: - sx_sunlock(slock); - return (err); + FMASTER_COMMON_OUTBLAHBLAH } /* example how a syscall handler routine can send a "background" request @@ -199,14 +263,12 @@ int fmaster1_write(struct cdev *dev, struct uio *uio, int ioflag) { - FMASTER_COMMON_BLAHBLAH + FMASTER_COMMON_INBLAHBLAH fuse_insert_callback(tick, prettyprint_handler); fuse_insert_message(tick); -out: - sx_sunlock(slock); - return (err); + FMASTER_COMMON_OUTBLAHBLAH } /* example how a syscall handler routine can send a request and handle response by itself @@ -215,7 +277,7 @@ int fmaster2_write(struct cdev *dev, struct uio *uio, int ioflag) { - FMASTER_COMMON_BLAHBLAH + FMASTER_COMMON_INBLAHBLAH fuse_insert_callback(tick, fuse_standard_handler); fuse_insert_message(tick); @@ -232,9 +294,7 @@ fuse_response_prettyprint(fuse_callbn_get_opcode(&tick->callbn), fuse_callbn_resp(&tick->callbn)); ticket_drop(tick); -out: - sx_sunlock(slock); - return (err); + FMASTER_COMMON_OUTBLAHBLAH } @@ -244,14 +304,12 @@ fmaster3_write(struct cdev *dev, struct uio *uio, int ioflag) { - FMASTER_COMMON_BLAHBLAH + FMASTER_COMMON_INBLAHBLAH ticket_invalidate(tick); /* so ticket will be dropped after read passes it up */ fuse_insert_message(tick); -out: - sx_sunlock(slock); - return (err); + FMASTER_COMMON_OUTBLAHBLAH } /* a not too effective application of the new API. @@ -267,9 +325,9 @@ { struct fuse_dispatcher fdi; - FMASTER_COMMON_BLAHBLAH + FMASTER_COMMON_INBLAHBLAH - fdi.slock = slock; + fdi.slock = NULL; fdi.tick = tick; if ((err = fdisp_wait_answ(&fdi))) return (err); @@ -277,9 +335,7 @@ fuse_response_prettyprint(fuse_callbn_get_opcode(&tick->callbn), fuse_callbn_resp(&tick->callbn)); ticket_drop(tick); -out: - sx_sunlock(slock); - return (err); + FMASTER_COMMON_OUTBLAHBLAH } /****************************** @@ -437,18 +493,26 @@ case FUSE_FSYNCDIR: //pp_buf(fresp); break; +#ifdef FUSE_GETLK case FUSE_GETLK: - KASSERT(0, ("FUSE_GETLK implementor has forgotten to define a response body format check")); + panic("FUSE_GETLK implementor has forgotten to define a response body format check"); break; +#endif +#ifdef FUSE_SETLK case FUSE_SETLK: - KASSERT(0, ("FUSE_SETLK implementor has forgotten to define a response body format check")); + panic("FUSE_SETLK implementor has forgotten to define a response body format check"); break; +#endif +#ifdef FUSE_SETLKW case FUSE_SETLKW: - KASSERT(0, ("FUSE_SETLKW implementor has forgotten to define a response body format check")); + panic("FUSE_SETLKW implementor has forgotten to define a response body format check"); break; +#endif +#ifdef FUSE_ACCESS case FUSE_ACCESS: - KASSERT(0, ("FUSE_ACCESS implementor has forgotten to define a response body format check")); + panic("FUSE_ACCESS implementor has forgotten to define a response body format check"); break; +#endif default: KASSERT(0, ("fuse opcodes out of sync")); } @@ -463,12 +527,25 @@ opcode = fuse_callbn_get_opcode(caliban); - if (opcode == FUSE_FORGET || opcode == FUSE_SETXATTR || opcode == FUSE_GETXATTR || opcode == FUSE_LISTXATTR || opcode == FUSE_REMOVEXATTR || opcode == FUSE_GETLK || opcode == FUSE_SETLK || opcode == FUSE_SETLKW || opcode == FUSE_ACCESS) { + if (opcode == FUSE_FORGET || opcode == FUSE_SETXATTR || opcode == FUSE_GETXATTR || opcode == FUSE_LISTXATTR || opcode == FUSE_REMOVEXATTR || +#ifdef FUSE_GETLK + opcode == FUSE_GETLK || +#endif +#ifdef FUSE_SETLK + opcode == FUSE_SETLK || +#endif +#ifdef FUSE_SETLKW + opcode == FUSE_SETLKW || +#endif +#ifdef FUSE_ACCESS + opcode == FUSE_ACCESS || +#endif + 0) { fuprintf("Hey, you've inserted a %s (#%d) request, don't do it in real life, it breaks an assertion!\n", fuse_opnames[opcode], opcode); goto out; } - if ((err = fuse_body_audit(caliban, fuse_response_body_len(uio)))) { + if ((err = fuse_body_audit(caliban, uio->uio_resid))) { fuprintf("body audit refused body\n"); goto out; } ==== //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.c#14 (text+ko) ==== @@ -47,27 +47,12 @@ #define NOT_YET_USED 0 -#ifndef DO_GIANT_MANUALLY -#define DO_GIANT_MANUALLY 1 -#endif -#ifndef USE_FUSE_LOCK -#define USE_FUSE_LOCK 1 -#endif - -#if USE_FUSE_LOCK -#define FUSE_LOCK mtx_lock(&fuse_mtx) -#define FUSE_UNLOCK mtx_unlock(&fuse_mtx) -#else -#define FUSE_LOCK -#define FUSE_UNLOCK -#endif - MALLOC_DEFINE(M_FUSEMSG, "fuse messaging", "buffer for fuse messaging related things"); -static uint32_t fuse_useco = 0; +uint32_t fuse_useco = 0; #if USE_FUSE_LOCK -static struct mtx fuse_mtx; +struct mtx fuse_mtx; #endif __static struct clonedevs *fuseclones; @@ -138,7 +123,7 @@ #endif static struct fuse_data *fdata_alloc(struct ucred *cred); -static void fdata_destroy(struct fuse_data *data); +__static void fdata_destroy(struct fuse_data *data); /**/ static __inline void fuse_msgn_push(struct fuse_msg_node *msgn); static __inline struct fuse_msg_node *fdata_pop_msg(struct fuse_data *data); @@ -501,7 +486,7 @@ return (data); } -static void +__static void fdata_destroy(struct fuse_data *data) { struct fuse_ticket *tick; @@ -1160,7 +1145,7 @@ static int fusedev_write(struct cdev *dev, struct uio *uio, int ioflag) { -#ifdef DEBUG_MSGING +#if _DEBUG_MSGING static int counter=0; #endif struct fuse_out_header *ohead; @@ -5187,6 +5172,7 @@ #if FMASTER extern struct cdevsw fmaster_cdevsw[5]; +static struct cdev *fmaster_dev[5]; #endif extern struct vfsconf fuse_vfsconf; @@ -5194,17 +5180,21 @@ static void fuse_bringdown(eventhandler_tag eh_tag) { - EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); +#if FMASTER + int i; +#endif + + EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); - clone_cleanup(&fuseclones); + clone_cleanup(&fuseclones); #if USE_FUSE_LOCK - mtx_destroy(&fuse_mtx); + mtx_destroy(&fuse_mtx); #endif #if FMASTER - for (i = 0; i < 5; i++) { - DEBUG("destroying fmaster%d\n", i); - destroy_dev(fmaster_dev[i]); - } + for (i = 0; i < 5; i++) { + DEBUG("destroying fmaster%d\n", i); + destroy_dev(fmaster_dev[i]); + } #endif } @@ -5215,7 +5205,6 @@ int err = 0; #if FMASTER int i; - static struct cdev *fmaster_dev[5]; char *fmaster_name = "fmasterx"; #endif ==== //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.h#7 (text+ko) ==== @@ -184,6 +184,30 @@ }; #endif +/* Fuse locking */ + +#ifndef DO_GIANT_MANUALLY +#define DO_GIANT_MANUALLY 1 +#endif +#ifndef USE_FUSE_LOCK +#define USE_FUSE_LOCK 1 +#endif + +#if USE_FUSE_LOCK +#define FUSE_LOCK mtx_lock(&fuse_mtx) +#define FUSE_UNLOCK mtx_unlock(&fuse_mtx) +#else +#define FUSE_LOCK +#define FUSE_UNLOCK +#endif + +extern uint32_t fuse_useco; +#if USE_FUSE_LOCK +extern struct mtx fuse_mtx; +#endif + +/* Debug related stuff */ + #if DEBUGTOLOG #define dprintf(args ...) log(LOG_DEBUG, args) #else @@ -211,6 +235,12 @@ #define DEBUG2G(args ...) #endif +#if FMASTER +#ifndef _DEBUG_MSGING +#define _DEBUG_MSGING 1 +#endif +#endif + #if _DEBUG_MSGING #define fuprintf(args...) \ uprintf("[kern] " args)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200510132159.j9DLxq2n088776>