Skip site navigation (1)Skip section navigation (2)
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>