PERFORCE change 114464 for review
Adam Martin
adamartin at FreeBSD.org
Wed Feb 14 01:40:08 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=114464
Change 114464 by adamartin at 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
+ }
/**/
More information about the p4-projects
mailing list