From owner-p4-projects@FreeBSD.ORG Wed Feb 14 01:40:08 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C9ACA16A407; Wed, 14 Feb 2007 01:40:07 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 6725716A402 for ; Wed, 14 Feb 2007 01:40:07 +0000 (UTC) (envelope-from adamartin@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 4DADF13C481 for ; Wed, 14 Feb 2007 01:40:07 +0000 (UTC) (envelope-from adamartin@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id l1E1e7lB096480 for ; Wed, 14 Feb 2007 01:40:07 GMT (envelope-from adamartin@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l1E1e6F6096477 for perforce@freebsd.org; Wed, 14 Feb 2007 01:40:06 GMT (envelope-from adamartin@FreeBSD.org) Date: Wed, 14 Feb 2007 01:40:06 GMT Message-Id: <200702140140.l1E1e6F6096477@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to adamartin@FreeBSD.org using -f From: Adam Martin To: Perforce Change Reviews Cc: Subject: PERFORCE change 114464 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Feb 2007 01:40:08 -0000 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 #include +#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 +#include + #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 + } /**/