PERFORCE change 85235 for review
soc-chenk
soc-chenk at FreeBSD.org
Thu Oct 13 14:59:56 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=85235
Change 85235 by soc-chenk at 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)
More information about the p4-projects
mailing list