Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Feb 2007 01:40:06 GMT
From:      Adam Martin <adamartin@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 114464 for review
Message-ID:  <200702140140.l1E1e6F6096477@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=114464

Change 114464 by adamartin@adamartin_hobbes on 2007/02/14 01:39:33

	Fixed panics on mount, mostly.
	
	TemplateFS seems to be complete now, but for accurately placing the
	lookup interceptor.  Mount_autofs checks if the device is named
	"autofs", to avoid panics, on mounting non autofs devices.
	
	Added a makefile to the "root" dir, but forgot to make it work.  (Will
	fix in next submission.)

Affected files ...

.. //depot/projects/soc2006/adamartin_autofs/Makefile#4 add
.. //depot/projects/soc2006/adamartin_autofs/autofs/Makefile#8 edit
.. //depot/projects/soc2006/adamartin_autofs/autofs/autofs.h#10 edit
.. //depot/projects/soc2006/adamartin_autofs/autofs/autofs_ctl.c#10 edit
.. //depot/projects/soc2006/adamartin_autofs/autofs/autofs_ctl.h#8 edit
.. //depot/projects/soc2006/adamartin_autofs/autofs/autofs_tfsops.c#4 edit
.. //depot/projects/soc2006/adamartin_autofs/autofs/autofs_types.h#5 edit
.. //depot/projects/soc2006/adamartin_autofs/autofs/autofs_user.h#1 add
.. //depot/projects/soc2006/adamartin_autofs/autofs/protocol.c#9 edit
.. //depot/projects/soc2006/adamartin_autofs/mount_autofs/mount_autofs.c#3 edit
.. //depot/projects/soc2006/adamartin_autofs/templatefs/templatefs.c#4 edit
.. //depot/projects/soc2006/adamartin_autofs/templatefs/templatefs.h#3 edit
.. //depot/projects/soc2006/adamartin_autofs/templatefs/templatefs_vnops.c#2 edit

Differences ...

==== //depot/projects/soc2006/adamartin_autofs/autofs/Makefile#8 (text+ko) ====

@@ -27,7 +27,7 @@
 
 
 AUTOFS_DEV_SOURCE=autofs_ctl.c autofs_dev.c
-AUTOFS_FS_SOURCE=autofs_tfsops.c vnode_if.h 
+AUTOFS_FS_SOURCE=autofs_tfsops.c autofs_tfsinit.c vnode_if.h 
 AUTOFS_CORE_SOURCE=autofs.c protocol.c
 AUTOFS_SUPPORT_SOURCE=autofs_subr.c
 SRCS=$(AUTOFS_CORE_SOURCE) $(AUTOFS_FS_SOURCE) $(AUTOFS_DEV_SOURCE) $(AUTOFS_SUPPORT_SOURCE)

==== //depot/projects/soc2006/adamartin_autofs/autofs/autofs.h#10 (text+ko) ====


==== //depot/projects/soc2006/adamartin_autofs/autofs/autofs_ctl.c#10 (text+ko) ====

@@ -181,7 +181,7 @@
 	 */
 
 	device= make_dev( devsw, num, UID_ROOT, GID_WHEEL, 0600,
-			"autofs%d", num );
+			AUTOFS_DEV_FORMAT"%d", num );
 
 	/* Possible race?  Locking the device? */
 	/* How to lock it? */
@@ -196,6 +196,7 @@
 	buffers->this_instance= instance;
 	ti->ti_priv= (void *) instance;
 	device->si_priv= (struct cdev_priv *) instance;
+	instance->templatefs_info= ti;
 
 	/*
 	 * Don't deallocate the resources --

==== //depot/projects/soc2006/adamartin_autofs/autofs/autofs_ctl.h#8 (text+ko) ====

@@ -48,6 +48,7 @@
 #include <sys/param.h>
 #include <sys/vnode.h>
 
+#include "autofs_user.h"
 
 
 

==== //depot/projects/soc2006/adamartin_autofs/autofs/autofs_tfsops.c#4 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006
+ * Copyright (c) 2006,2007
  *	Adam Martin, Erez Zadok.  All rights reserved.
  *
  * This code is derived from software in FreeBSD, and 4.4BSD.
@@ -57,26 +57,25 @@
 #include "../templatefs/templatefs.h"
 
 #include <sys/time.h>
+#include <sys/errno.h>
 
+
 #include "protocol.h"
 #include "debug.h"
 #include "autofs_ctl.h"
 #include "autofs_dev.h"
 
+#include "autofs_templatefs.h"
 
-MALLOC_DEFINE( M_AUTOFS_MOUNTBUF, "AutoFS mntbuf",
-		"AutoFS mountpoint data, to simulate filesystem contents.");
 
-struct tfs_node *foo;
-
-static int
+int
 autofs_vis( TFS_VIS_ARGS )
 {
 	KPRINTF( "autofs visibility called\n" );
 	return 0;
 }
 
-static int
+int
 autofs_attr( TFS_ATTR_ARGS )
 {
 	KPRINTF( "autofs attr called\n" );
@@ -99,7 +98,7 @@
 }
 
 
-static int
+int
 autofs_lookup( TFS_LOOKUP_ARGS )
 {
 	struct componentname c= *cnp;
@@ -110,16 +109,18 @@
 	autofs_instance_t	*instance;
 	autofs_dev_bufs_t	*buffers;
 
+	DEBUG1 EPRINTF( "autofs lookup called\n" );
 
 	ti=	tn->tn_info;
 
-	instance=	AUTOFS_GET_INSTANCE( NODE, tn );
-	buffers=	AUTOFS_GET_BUFFERS( NODE, tn );
+	DEBUG1 EPRINTF( "Templatefs info: %p\n", ti );
+
+	instance=	AUTOFS_GET_INSTANCE( ROOT, ti );
+	buffers=	AUTOFS_GET_BUFFERS( ROOT, ti );
 
-	DEBUG1 KPRINTF( "autofs lookup called\n" );
-	DEBUG7 KPRINTF( "cn_nameptr= %s, cn_pnbuf= %s\n", c.cn_nameptr,
+	DEBUG7 EPRINTF( "cn_nameptr= %s, cn_pnbuf= %s\n", c.cn_nameptr,
 				c.cn_pnbuf );
-	DEBUG7 KPRINTF( "cn_namelen= %ld, cn_consume= %ld\n", c.cn_namelen,
+	DEBUG7 EPRINTF( "cn_namelen= %ld, cn_consume= %ld\n", c.cn_namelen,
 				c.cn_consume );
 
 	/* Prepare a mount message */
@@ -132,6 +133,11 @@
 	mr.mountpoint_len=	c.cn_namelen;
 	strlcpy( mr.mountpoint, c.cn_nameptr, c.cn_namelen );
 
+	if( strcmp( mr.mountpoint, ".." ) )
+	{
+		return 0;
+	}
+
 	/* Take a lock and if it's not taken yet fire off the request. */
 
 	//if( take_autofs_lock( instance, node ) )
@@ -143,100 +149,3 @@
 }
 
 
-static int
-autofs_mount_handler( TFS_MOUNT_HANDLER_ARGS )
-{
-	struct vnode		*devvp;
-	struct cdev		*dev;
-	struct nameidata	nd;
-	struct nameidata	*ndp;
-	int			error;
-	char			*dev_name;
-	int			dev_name_len;
-	struct vfsoptlist	*opts;
-
-	error= 0;
-
-	ndp= &nd;
-	opts= mp->mnt_optnew;
-
-	error= vfs_getopt( opts, MNT_DEVICE, (void **) &dev_name,
-			&dev_name_len );
-
-	if( !error && dev_name[ dev_name_len - 1 ] != '\0' )
-	{
-		return ( EINVAL );
-	}
-
-	NDINIT( ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, dev_name, td );
-	if( ( error= namei( ndp ) ) )
-	{
-		return ( error );
-	}
-	NDFREE( ndp, NDF_ONLY_PNBUF );
-	devvp= ndp->ni_vp;
-
-	/** Take the lock here, and get the struct cdev out of it, and use the
-	private data there, to assign the instance. **/
-
-	dev= devvp->v_rdev;
-
-	/** Now we have the dev object.  Work with it. **/
-
-	ti->ti_priv= (void *) AUTOFS_GET_INSTANCE( DEV, dev );
-
-	return error;
-}
-
-static int
-autofs_init(struct tfs_info *ti, struct vfsconf *vfc)
-{
-	struct vnode *devvp;
-	struct cdev *dev;
-	struct nameidata nd, *ndp= &nd;
-	struct thread *td;
-	int error;
-
-	td= curthread;
-
-
-	/** Get the fake device vnode from name **/
-
-	NDINIT( ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, ti->ti_name, td );
-	if( ( error= namei( ndp ) ) != 0 )
-	{
-		return error;
-	}
-	NDFREE( ndp, NDF_ONLY_PNBUF );
-	devvp= ndp->ni_vp;
-
-	/** Verify that the vnode is a device **/
-	if( devvp->v_type != VCHR )
-	{
-		panic( "Can't mount from non-char device for Autofs!\n" );
-	}
-
-	/* Get out the cdev object, and store in the private field for the
-	pfs_info object  (I think we need to release the vnode too!)*/
-
-	dev= devvp->v_rdev;
-	ti->ti_priv= (void *) dev;
-	VOP_UNLOCK( devvp, LK_RELEASE, td );
-
-
-	/** Make some fake files... **/
-
-	foo= tfs_create_dir( ti->ti_root, "foo", autofs_attr, autofs_vis, 0 ); 
-	foo->tn_lookup= autofs_lookup;
-	return 0;
-}
-
-
-static int
-autofs_uninit(struct tfs_info *ti, struct vfsconf *vfc)
-{
-	return 0;
-}
-
-
-TEMPLATEFS( autofs, AUTOFS_VERSION, autofs_mount_handler );

==== //depot/projects/soc2006/adamartin_autofs/autofs/autofs_types.h#5 (text+ko) ====

@@ -43,8 +43,8 @@
 
 
 
-/* This is needed as there's no true private field on pfs_node */
-#define	pn_priv	pn_data
+/* This is needed as there's no true private field on tfs_node */
+#define	tn_priv	tn_data
 
 
 struct autofs_instance
@@ -58,6 +58,8 @@
 						transactions **/
 	autofs_protocol_state_t *protocol_state;
 
+	struct tfs_info		*templatefs_info;
+
 	void			*extensions;
 };
 
@@ -74,7 +76,7 @@
 	int			state;
 	unsigned long long int	flags;
 
-	struct pfs_node		*mount_file; /*	The pn_priv field points to
+	struct tfs_node		*mount_file; /*	The pn_priv field points to
 						the autofs mount structure */
 
 	int			timeout;	/* Timeout in seconds */
@@ -149,7 +151,7 @@
 E.G.: AUTOFS_GET_TXNS( DEV, autofs_cdevsw )
 
 one can get:
-	BUFFERS, DEV, TXNS, INSTANCE, PROTOCOL
+	BUFFERS, DEV, TXNS, INSTANCE, PROTOCOL, ROOT
 
 ****************************************************************************/
 
@@ -173,6 +175,10 @@
 	( (struct autofs_protocol_state *) ( AUTOFS_GET_INSTANCE( TYPE, \
 			__datum__ )->protocol_state ) )
 
+#define AUTOFS_GET_ROOT( TYPE, __datum__ )\
+	( (struct tfs_info *) ( AUTOFS_GET_INSTANCE( TYPE, \
+			__datum__ )->templatefs_info ) )
+
 
 #define AUTOFS_DEV_GET_INSTANCE( dev )\
 	( ( dev )->si_priv )
@@ -189,7 +195,7 @@
 #define AUTOFS_PROTOCOL_GET_INSTANCE( protocol )\
 	( ( protocol )->instance )
 
-#define AUTOFS_BUFFERS_GET_INSTANCE( protocol )\
-	( ( protocol )->this_instance )
+#define AUTOFS_BUFFERS_GET_INSTANCE( buffers )\
+	( ( buffers )->this_instance )
 
 #endif	/*** __AUTOFS_TYPES_H__ ***/

==== //depot/projects/soc2006/adamartin_autofs/autofs/protocol.c#9 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006
+ * Copyright (c) 2006,2007
  *	Adam Martin, Erez Zadok.  All rights reserved.
  *
  * This code is derived from software in FreeBSD, and 4.4BSD.
@@ -87,7 +87,7 @@
  * XXX: FIXME: This is a big nasty. (ADAM)
  * This parses input from the data buffers (queues),
  * and dispatches out the results to complete command handlers.
- * This could DEFINATELY be fixed up by somebody at some point.
+ * This could DEFINITELY be fixed up by somebody at some point.
  */
 
 void
@@ -206,10 +206,11 @@
 static void
 command_dispatch( autofs_protocol_state_t *protocol )
 {
-	autofs_instance_t		*instance;
-	int		cnt;
+	autofs_instance_t	*instance;
+	int			cnt;
+
 
-	cnt= 0;
+	cnt=		0;
 	instance=	AUTOFS_GET_INSTANCE( PROTOCOL, protocol );
 
 	if( protocol->bytes_read < protocol->max_bytes_to_read )

==== //depot/projects/soc2006/adamartin_autofs/mount_autofs/mount_autofs.c#3 (text+ko) ====

@@ -57,6 +57,8 @@
 
 #include "mntopts.h"
 
+#include "../autofs/autofs_user.h"
+
 
 #define FSTYPE		"autofs"
 #define FSTYPE_HANDLE	"fstype"
@@ -93,6 +95,14 @@
 	strcpy(target, argv[1]);
 	(void)checkpath(argv[2], source);
 
+	if( strncmp( "/dev/"AUTOFS_DEV_FORMAT, target,
+			strlen( "/dev/"AUTOFS_DEV_FORMAT ) ) )
+	{
+		fprintf( stderr, "Not an autofs device!\n" );
+		return 2;
+	}
+
+
 	iov[0].iov_base = FSTYPE_HANDLE;
 	iov[0].iov_len = strlen(FSTYPE_HANDLE) + 1;
 	iov[1].iov_base = FSTYPE;

==== //depot/projects/soc2006/adamartin_autofs/templatefs/templatefs.c#4 (text+ko) ====

@@ -75,6 +75,9 @@
 #include "templatefs.h"
 #include "templatefs_internal.h"
 
+#define	FREEBSD_SYS
+#include "../autofs/debug.h"
+
 static MALLOC_DEFINE(M_TFSNODES, "tfs_nodes", "templatefs nodes");
 
 MALLOC_DECLARE(M_TFSINFO);
@@ -294,18 +297,33 @@
  * Mount a templatefs instance
  */
 int
-tfs_mount(struct tfs_info *ti, struct mount *mp, struct thread *td)
+tfs_mount(struct tfs_info *global_ti, struct mount *mp, struct thread *td)
 {
 	struct statfs *sbp;
+	struct tfs_info *ti;
 
+	DEBUG EPRINTF( "TFS_MOUNT: tfs_info is %llx\n",
+			(unsigned long long int) global_ti );
+
 	if (mp->mnt_flag & MNT_UPDATE)
 		return (EOPNOTSUPP);
 
+
+	if (global_ti->ti_mount_handler == NULL)
+		panic("Need a mount handler for templatefs!\n");
+
+	/* Tell the instance to do its thing, and also get the ti from them */
+	ti= global_ti->ti_mount_handler(global_ti, mp, td);
+
+	if (ti == NULL)
+		panic("Unable to get templatefs instance data!\n");
+
 	mp->mnt_flag |= MNT_LOCAL;
 	mp->mnt_data = (qaddr_t)ti;
 	vfs_getnewfsid(mp);
 
 	sbp = &mp->mnt_stat;
+	/** Make the mounted from be according to the ti of the instance */
 	vfs_mountedfrom(mp, ti->ti_name);
 	sbp->f_bsize = PAGE_SIZE;
 	sbp->f_iosize = PAGE_SIZE;
@@ -315,9 +333,11 @@
 	sbp->f_files = 1;
 	sbp->f_ffree = 0;
 
+	/** Create the root vnode, for use by vfs_root(8) **/
+
+	
+
 	/** Mount intercept handler, by ADAM **/
-	if( ti->ti_mount_handler != NULL )
-		ti->ti_mount_handler( ti, mp, td );
 
 	return (0);
 }
@@ -335,6 +355,13 @@
 
 	/* XXX do stuff with pi... */
 
+	/*
+	 * ADAM -- FIXME: need to get the specific ti instance data.
+	 * Maybe implementors need their own tfs_unmount too?
+	 * What are we using ti for?  Can we unmount on the in-use filesystem?
+	 * (What happens if AMD is still using the afs devices?)
+	 */
+
 	error = vflush(mp, 0, (mntflags & MNT_FORCE) ?  FORCECLOSE : 0, td);
 	return (error);
 }
@@ -348,9 +375,23 @@
 
 	/** ADAM: TODO: Make this handle multiple clients of the same type **/
 	struct tfs_info *ti;
+	int rv;
+
+	//printf("Entered tfs_root()\n");
 
+	//printf("Getting mount data...\n");
 	ti = (struct tfs_info *)mp->mnt_data;
-	return tfs_vncache_alloc(mp, vpp, ti->ti_root, NO_PID);
+	//printf("Returning templatefs root: %llx\n", (unsigned long long int) ti->ti_root);
+
+	if( ti->ti_root == NULL )
+	{
+		return 0;
+	}
+
+	rv = tfs_vncache_alloc(mp, vpp, ti->ti_root, NO_PID);
+
+	//printf("Returning templatefs root: %llx\n", (unsigned long long int) *vpp);
+	return rv;
 }
 
 /*
@@ -375,6 +416,7 @@
 	struct tfs_info *ti;
 	int error;
 
+	printf("Entered tfs_create_instance()\n");
 	error= 0;
 
 	/* Insulate against returning free'd memory in case of error. */
@@ -421,6 +463,8 @@
 	/* struct tfs_node *root; */
 	int error;
 
+	printf("tfs_init called...\n");
+
 	error = 0;
 
 	mtx_init(&ti->ti_mutex, "templatefs", NULL, MTX_DEF);

==== //depot/projects/soc2006/adamartin_autofs/templatefs/templatefs.h#3 (text+ko) ====

@@ -56,8 +56,8 @@
  *      $FreeBSD: src/sys/fs/pseudofs/pseudofs.h,v 1.30 2005/03/24 07:36:15 jeff Exp $
  */
 
-#ifndef _PSEUDOFS_H_INCLUDED
-#define _PSEUDOFS_H_INCLUDED
+#ifndef _TEMPLATE_H_INCLUDED
+#define _TEMPLATE_H_INCLUDED
 
 /*
  * Opaque structures
@@ -123,10 +123,10 @@
  * Mount callback (ADAM)
  */
 #define TFS_MOUNT_HANDLER_ARGS \
-	struct tfs_info *ti, struct mount *mp, struct thread *td
+	struct tfs_info *global_ti, struct mount *mp, struct thread *td
 #define TFS_MOUNT_HANDLER_PROTO(name) \
-	int name(TFS_MOUNT_HANDLER_ARGS);
-typedef int (*tfs_mount_handler_t)(TFS_MOUNT_HANDLER_ARGS);
+	struct tfs_info *name(TFS_MOUNT_HANDLER_ARGS);
+typedef struct tfs_info *(*tfs_mount_handler_t)(TFS_MOUNT_HANDLER_ARGS);
 
 /*
  * Filler callback
@@ -296,9 +296,9 @@
 
 /*
  * Now for some initialization magic...
- * (call with mount_func == NULL, should you not need a mount function.)
+ * Must have a non-NULL mount_func.  Failure to do so causes panics.
  */
-#define TEMPLATEFS(name, version, mount_func)					\
+#define TEMPLATEFS(name, version, mount_func)				\
 									\
 static struct tfs_info name##_info = {					\
 	.ti_name=		#name,					\
@@ -306,15 +306,17 @@
 	.ti_uninit=		name##_uninit,				\
 	.ti_mount_handler=	mount_func,				\
 };									\
-/* FIXME: Drop this (tfs_mount): */					\
+/* TODO: Perhaps handle this differently?  (passes global tfs_info) */	\
 static int								\
-_##name##_mount(struct mount *mp, struct thread *td) {			\
+_##name##_mount(struct mount *mp, struct thread *td)			\
+{									\
 	return tfs_mount(&name##_info, mp, td);				\
 }									\
 									\
 static int								\
 _##name##_init(struct vfsconf *vfc) {					\
-	return tfs_init(&name##_info, vfc);				\
+	/*return tfs_init(&name##_info, vfc);*/				\
+	return 0;							\
 }									\
 									\
 static int								\

==== //depot/projects/soc2006/adamartin_autofs/templatefs/templatefs_vnops.c#2 (text+ko) ====

@@ -453,11 +453,14 @@
 
 	// LOOKUP_ENABLE (to drop this whole section change // to /*)
 	if (td->tn_lookup != 0)
+	{
+		printf( "Calling templatefs lookup handler...\n" );
 	#ifdef USE_TFSRETURN_ON_LOOKUP_CALLBACK
 		TFS_RETURN (td->tn_lookup(curthread, pfind(pid), td, cnp));
 	#else
 		td->tn_lookup(curthread, pfind(pid), td, cnp);
 	#endif
+	}
 	/**/
 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200702140140.l1E1e6F6096477>