afs/fs/afs volume.h,1.4,1.5 volume.c,1.7,1.8 vnode.h,1.4,1.5 vnode.c,1.6,1.7 vlocation.c,1.8,1.9 vlclient.h,1.4,1.5 vlclient.c,1.6,1.7 super.h,1.2,1.3 super.c,1.8,1.9 server.c,1.3,1.4 mntpt.c,1.6,1.7 main.c,1.11,1.12 kafstimod.c,1.6,1.7 internal.h,1.14,1.15 inode.c,1.10,1.11 file.c,1.7,1.8 dir.c,1.9,1.10 cmservice.c,1.6,1.7 cell.h,1.4,1.5 cell.c,1.8,1.9 callback.c,1.3,1.4 Makefile,1.11,1.12

dwh at infradead.org dwh at infradead.org
Fri Jul 4 17:26:34 BST 2003


Update of /home/cvs/afs/fs/afs
In directory phoenix.infradead.org:/tmp/cvs-serv10566/fs/afs

Modified Files:
	volume.h volume.c vnode.h vnode.c vlocation.c vlclient.h 
	vlclient.c super.h super.c server.c mntpt.c main.c kafstimod.c 
	internal.h inode.c file.c dir.c cmservice.c cell.h cell.c 
	callback.c Makefile 
Log Message:
done some cleaning up
moved a little towards hch-compliance (CodingStyle)
added automount/expiry (requires kernel patch)
made cache index match functions request update/delete if necessary


Index: volume.h
===================================================================
RCS file: /home/cvs/afs/fs/afs/volume.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- volume.h	6 Jun 2003 08:33:37 -0000	1.4
+++ volume.h	4 Jul 2003 15:26:31 -0000	1.5
@@ -87,13 +87,16 @@
 	unsigned short		valid;		/* T if valid */
 };
 
-extern int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_vlocation);
+extern int afs_vlocation_lookup(struct afs_cell *cell,
+				const char *name,
+				unsigned namesz,
+				struct afs_vlocation **_vlocation);
 
 #define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0)
 
-extern void __afs_put_vlocation(afs_vlocation_t *vlocation);
-extern void afs_put_vlocation(afs_vlocation_t *vlocation);
-extern void afs_vlocation_do_timeout(afs_vlocation_t *vlocation);
+extern void __afs_put_vlocation(struct afs_vlocation *vlocation);
+extern void afs_put_vlocation(struct afs_vlocation *vlocation);
+extern void afs_vlocation_do_timeout(struct afs_vlocation *vlocation);
 
 /*****************************************************************************/
 /*
@@ -114,14 +117,19 @@
 	struct rw_semaphore	server_sem;	/* lock for accessing current server */
 };
 
-extern int afs_volume_lookup(char *name, int ro, afs_volume_t **_volume);
+extern int afs_volume_lookup(const char *name,
+			     struct afs_cell *cell,
+			     int rwpath,
+			     struct afs_volume **_volume);
 
 #define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)
 
-extern void afs_put_volume(afs_volume_t *volume);
+extern void afs_put_volume(struct afs_volume *volume);
 
-extern int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server);
+extern int afs_volume_pick_fileserver(struct afs_volume *volume, struct afs_server **_server);
 
-extern int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, int result);
+extern int afs_volume_release_fileserver(struct afs_volume *volume,
+					 struct afs_server *server,
+					 int result);
 
 #endif /* _LINUX_AFS_VOLUME_H */

Index: volume.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/volume.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- volume.c	9 Jun 2003 13:52:04 -0000	1.7
+++ volume.c	4 Jul 2003 15:26:31 -0000	1.8
@@ -56,19 +56,19 @@
  * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W if not available
  * - Rule 3: If parent volume is R/W, then only mount R/W volume unless explicitly told otherwise
  */
-int afs_volume_lookup(char *name, int rwparent, afs_volume_t **_volume)
+int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
+		      afs_volume_t **_volume)
 {
-	afs_vlocation_t *vlocation = NULL;
+	struct afs_vlocation *vlocation = NULL;
+	struct afs_volume *volume = NULL;
 	afs_voltype_t type;
-	afs_volume_t *volume = NULL;
-	afs_cell_t *cell = NULL;
-	char *cellname, *volname, *suffix;
+	const char *cellname, *volname, *suffix;
 	char srvtmask;
-	int force, ret, loop;
+	int force, ret, loop, cellnamesz, volnamesz;
 
-	_enter(",%s,",name);
+	_enter("%s,,%d,", name, rwpath);
 
-	if (!name || (name[0]!='%' && name[0]!='#') || !name[1]) {
+	if (!name || (name[0] != '%' && name[0] != '#') || !name[1]) {
 		printk("kAFS: unparsable volume name\n");
 		return -EINVAL;
 	}
@@ -77,24 +77,22 @@
 	force = 0;
 	type = AFSVL_ROVOL;
 
-	if (rwparent || name[0]=='%') {
+	if (rwpath || name[0] == '%') {
 		type = AFSVL_RWVOL;
 		force = 1;
 	}
 
-	suffix = strrchr(name,'.');
+	suffix = strrchr(name, '.');
 	if (suffix) {
-		if (strcmp(suffix,".readonly")==0) {
+		if (strcmp(suffix, ".readonly") == 0) {
 			type = AFSVL_ROVOL;
 			force = 1;
 		}
-		else if (strcmp(suffix,".backup")==0) {
+		else if (strcmp(suffix, ".backup") == 0) {
 			type = AFSVL_BACKVOL;
 			force = 1;
 		}
-		else if (suffix[1]==0) {
-			*suffix = 0;
-			suffix = NULL;
+		else if (suffix[1] == 0) {
 		}
 		else {
 			suffix = NULL;
@@ -103,38 +101,45 @@
 
 	/* split the cell and volume names */
 	name++;
-	volname = strchr(name,':');
+	volname = strchr(name, ':');
 	if (volname) {
-		*volname++ = 0;
 		cellname = name;
+		cellnamesz = volname - name;
 	}
 	else {
 		volname = name;
 		cellname = NULL;
+		cellnamesz = 0;
 	}
 
-	_debug("CELL:%s VOLUME:%s SUFFIX:%s TYPE:%d%s",
-	       cellname,volname,suffix?:"-",type,force?" FORCE":"");
+	volnamesz = suffix ? suffix - volname : strlen(volname);
 
-	/* lookup the cell record */
-	ret = afs_cell_lookup(cellname,&cell);
-	if (ret<0)
-		printk("kAFS: unable to lookup cell '%s'\n",cellname?:"");
+	_debug("CELL:%*.*s [%p] VOLUME:%*.*s SUFFIX:%s TYPE:%d%s",
+	       cellnamesz, cellnamesz, cellname ?: "", cell,
+	       volnamesz, volnamesz, volname, suffix ?: "-",
+	       type,
+	       force ? " FORCE" : "");
 
-	if (cellname) volname[-1] = ':';
-	if (ret<0)
-		goto error;
+	/* lookup the cell record */
+	if (cellname || !cell) {
+		ret = afs_cell_lookup(cellname, cellnamesz, &cell);
+		if (ret<0) {
+			printk("kAFS: unable to lookup cell '%s'\n", cellname ?: "");
+			goto error;
+		}
+	}
+	else {
+		afs_get_cell(cell);
+	}
 
 	/* lookup the volume location record */
-	if (suffix) *suffix = 0;
-	ret = afs_vlocation_lookup(cell,volname,&vlocation);
-	if (suffix) *suffix = '.';
-	if (ret<0)
+	ret = afs_vlocation_lookup(cell, volname, volnamesz, &vlocation);
+	if (ret < 0)
 		goto error;
 
 	/* make the final decision on the type we want */
 	ret = -ENOMEDIUM;
-	if (force && !(vlocation->vldb.vidmask & (1<<type)))
+	if (force && !(vlocation->vldb.vidmask & (1 << type)))
 		goto error;
 
 	srvtmask = 0;
@@ -142,7 +147,7 @@
 		srvtmask |= vlocation->vldb.srvtmask[loop];
 
 	if (force) {
-		if (!(srvtmask & (1 <<type)))
+		if (!(srvtmask & (1 << type)))
 			goto error;
 	}
 	else if (srvtmask & AFS_VOL_VTM_RO) {
@@ -169,12 +174,12 @@
 	_debug("creating new volume record");
 
 	ret = -ENOMEM;
-	volume = kmalloc(sizeof(afs_volume_t),GFP_KERNEL);
+	volume = kmalloc(sizeof(afs_volume_t), GFP_KERNEL);
 	if (!volume)
 		goto error_up;
 
-	memset(volume,0,sizeof(afs_volume_t));
-	atomic_set(&volume->usage,1);
+	memset(volume, 0, sizeof(afs_volume_t));
+	atomic_set(&volume->usage, 1);
 	volume->type		= type;
 	volume->type_force	= force;
 	volume->cell		= cell;
@@ -207,7 +212,7 @@
 	vlocation->vols[type] = volume;
 
  success:
-	_debug("kAFS selected %s volume %08x",afs_voltypes[volume->type],volume->vid);
+	_debug("kAFS selected %s volume %08x", afs_voltypes[volume->type], volume->vid);
 	*_volume = volume;
 	ret = 0;
 
@@ -215,18 +220,17 @@
  error_up:
 	up_write(&cell->vl_sem);
  error:
-	if (vlocation)	afs_put_vlocation(vlocation);
-	if (cell)	afs_put_cell(cell);
+	afs_put_vlocation(vlocation);
+	afs_put_cell(cell);
 
-	_leave(" = %d (%p)",ret,volume);
+	_leave(" = %d (%p)", ret, volume);
 	return ret;
 
  error_discard:
 	up_write(&cell->vl_sem);
 
 	for (loop=volume->nservers-1; loop>=0; loop--)
-		if (volume->servers[loop])
-			afs_put_server(volume->servers[loop]);
+		afs_put_server(volume->servers[loop]);
 
 	kfree(volume);
 	goto error;
@@ -241,6 +245,9 @@
 	afs_vlocation_t *vlocation;
 	int loop;
 
+	if (!volume)
+		return;
+
 	_enter("%p",volume);
 
 	vlocation = volume->vlocation;
@@ -267,8 +274,7 @@
 	afs_put_vlocation(vlocation);
 
 	for (loop=volume->nservers-1; loop>=0; loop--)
-		if (volume->servers[loop])
-			afs_put_server(volume->servers[loop]);
+		afs_put_server(volume->servers[loop]);
 
 	kfree(volume);
 

Index: vnode.h
===================================================================
RCS file: /home/cvs/afs/fs/afs/vnode.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- vnode.h	6 Jun 2003 08:33:37 -0000	1.4
+++ vnode.h	4 Jul 2003 15:26:31 -0000	1.5
@@ -27,7 +27,9 @@
  */
 struct afs_cache_vnode
 {
-	afs_vnodeid_t		vnode;		/* vnode ID */
+	afs_vnodeid_t		vnode_id;	/* vnode ID */
+	unsigned		vnode_unique;	/* vnode ID uniquifier */
+	afs_dataversion_t	data_version;	/* data version */
 };
 
 extern struct cachefs_index_def afs_vnode_cache_index_def;

Index: vnode.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/vnode.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vnode.c	10 Jun 2003 17:49:49 -0000	1.6
+++ vnode.c	4 Jul 2003 15:26:31 -0000	1.7
@@ -72,8 +72,7 @@
 
 	spin_unlock(&vnode->lock);
 
-	if (oldserver)
-		afs_put_server(oldserver);
+	afs_put_server(oldserver);
 
 	_leave("");
 } /* end afs_vnode_cb_timed_out() */
@@ -137,8 +136,7 @@
 
 	wake_up_all(&vnode->update_waitq);
 
-	if (oldserver)
-		afs_put_server(oldserver);
+	afs_put_server(oldserver);
 
 	_leave("");
 
@@ -337,8 +335,12 @@
 
 	_enter("");
 
-	if (vnode->fid.vnode == cvnode->vnode)
-		return CACHEFS_MATCH_SUCCESS;
+	if (vnode->fid.vnode != cvnode->vnode_id)
+		return CACHEFS_MATCH_FAILED;
+
+	if (vnode->fid.unique != cvnode->vnode_unique ||
+	    vnode->status.version != cvnode->data_version)
+		return CACHEFS_MATCH_SUCCESS_DELETE;
 
 	return CACHEFS_MATCH_FAILED;
 } /* end afs_vnode_cache_match() */
@@ -354,6 +356,8 @@
 
 	_enter("");
 
-	cvnode->vnode = vnode->fid.vnode;
+	cvnode->vnode_id	= vnode->fid.vnode;
+	cvnode->vnode_unique	= vnode->fid.unique;
+	cvnode->data_version	= vnode->status.version;
 
 } /* end afs_vnode_cache_update() */

Index: vlocation.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/vlocation.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- vlocation.c	9 Jun 2003 13:52:04 -0000	1.8
+++ vlocation.c	4 Jul 2003 15:26:31 -0000	1.9
@@ -75,21 +75,23 @@
  */
 static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation,
 					   const char *name,
+					   unsigned namesz,
 					   struct afs_cache_vlocation *vldb)
 {
 	afs_server_t *server = NULL;
 	afs_cell_t *cell = vlocation->cell;
 	int count, ret;
 
-	_enter("%s,%s,",cell->name,name);
+	_enter("%s,%*.*s,%u", cell->name, namesz, namesz, name, namesz);
 
 	ret = -ENOMEDIUM;
 	for (count=cell->vl_naddrs; count>0; count--) {
 		_debug("CellServ[%hu]: %08x",
-		       cell->vl_curr_svix,cell->vl_addrs[cell->vl_curr_svix].s_addr);
+		       cell->vl_curr_svix,
+		       cell->vl_addrs[cell->vl_curr_svix].s_addr);
 
 		/* try and create a server */
-		ret = afs_server_lookup(cell,&cell->vl_addrs[cell->vl_curr_svix],&server);
+		ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server);
 		switch (ret) {
 		case 0:
 			break;
@@ -101,7 +103,7 @@
 		}
 
 		/* attempt to access the VL server */
-		ret = afs_rxvl_get_entry_by_name(server,name,vldb);
+		ret = afs_rxvl_get_entry_by_name(server, name, namesz, vldb);
 		switch (ret) {
 		case 0:
 			afs_put_server(server);
@@ -118,7 +120,7 @@
 			}
 			up_write(&server->sem);
 			afs_put_server(server);
-			if (ret==-ENOMEM || ret==-ENONET)
+			if (ret == -ENOMEM || ret == -ENONET)
 				goto out;
 			goto rotate;
 		case -ENOMEDIUM:
@@ -157,15 +159,16 @@
 	afs_cell_t *cell = vlocation->cell;
 	int count, ret;
 
-	_enter("%s,%x,%d,",cell->name,volid,voltype);
+	_enter("%s,%x,%d,", cell->name, volid, voltype);
 
 	ret = -ENOMEDIUM;
 	for (count=cell->vl_naddrs; count>0; count--) {
 		_debug("CellServ[%hu]: %08x",
-		       cell->vl_curr_svix,cell->vl_addrs[cell->vl_curr_svix].s_addr);
+		       cell->vl_curr_svix,
+		       cell->vl_addrs[cell->vl_curr_svix].s_addr);
 
 		/* try and create a server */
-		ret = afs_server_lookup(cell,&cell->vl_addrs[cell->vl_curr_svix],&server);
+		ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server);
 		switch (ret) {
 		case 0:
 			break;
@@ -177,7 +180,7 @@
 		}
 
 		/* attempt to access the VL server */
-		ret = afs_rxvl_get_entry_by_id(server,volid,voltype,vldb);
+		ret = afs_rxvl_get_entry_by_id(server, volid, voltype, vldb);
 		switch (ret) {
 		case 0:
 			afs_put_server(server);
@@ -194,7 +197,7 @@
 			}
 			up_write(&server->sem);
 			afs_put_server(server);
-			if (ret==-ENOMEM || ret==-ENONET)
+			if (ret == -ENOMEM || ret == -ENONET)
 				goto out;
 			goto rotate;
 		case -ENOMEDIUM:
@@ -227,7 +230,8 @@
  * - lookup in the local cache if not able to find on the VL server
  * - insert/update in the local cache if did get a VL response
  */
-int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_vlocation)
+int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
+			 afs_vlocation_t **_vlocation)
 {
 	struct afs_cache_vlocation vldb;
 	struct list_head *_p;
@@ -236,48 +240,56 @@
 	afs_volid_t vid;
 	int active = 0, ret;
 
-	_enter(",%s,%s,",cell->name,name);
+	_enter("{%s},%*.*s,%u,", cell->name, namesz, namesz, name, namesz);
 
-	if (strlen(name)>sizeof(vlocation->vldb.name)) {
+	if (namesz > sizeof(vlocation->vldb.name)) {
 		_leave(" = -ENAMETOOLONG");
 		return -ENAMETOOLONG;
 	}
 
 	/* search the cell's active list first */
-	list_for_each(_p,&cell->vl_list) {
-		vlocation = list_entry(_p,afs_vlocation_t,link);
-		if (strncmp(vlocation->vldb.name,name,sizeof(vlocation->vldb.name))==0)
+	list_for_each(_p, &cell->vl_list) {
+		vlocation = list_entry(_p, afs_vlocation_t, link);
+		if (namesz < sizeof(vlocation->vldb.name) &&
+		    vlocation->vldb.name[namesz] != '\0')
+			continue;
+
+		if (memcmp(vlocation->vldb.name, name, namesz) == 0)
 			goto found_in_memory;
 	}
 
 	/* search the cell's graveyard list second */
 	spin_lock(&cell->vl_gylock);
-	list_for_each(_p,&cell->vl_graveyard) {
-		vlocation = list_entry(_p,afs_vlocation_t,link);
-		if (strncmp(vlocation->vldb.name,name,sizeof(vlocation->vldb.name))==0)
+	list_for_each(_p, &cell->vl_graveyard) {
+		vlocation = list_entry(_p, afs_vlocation_t, link);
+		if (namesz < sizeof(vlocation->vldb.name) &&
+		    vlocation->vldb.name[namesz] != '\0')
+			continue;
+
+		if (memcmp(vlocation->vldb.name, name, namesz) == 0)
 			goto found_in_graveyard;
 	}
 	spin_unlock(&cell->vl_gylock);
 
 	/* not in the cell's in-memory lists - create a new record */
-	vlocation = kmalloc(sizeof(afs_vlocation_t),GFP_KERNEL);
+	vlocation = kmalloc(sizeof(afs_vlocation_t), GFP_KERNEL);
 	if (!vlocation)
 		return -ENOMEM;
 
-	memset(vlocation,0,sizeof(afs_vlocation_t));
-	atomic_set(&vlocation->usage,1);
+	memset(vlocation, 0, sizeof(afs_vlocation_t));
+	atomic_set(&vlocation->usage, 1);
 	INIT_LIST_HEAD(&vlocation->link);
 	rwlock_init(&vlocation->lock);
-	strncpy(vlocation->vldb.name,name,sizeof(vlocation->vldb.name));
+	memcpy(vlocation->vldb.name, name, namesz);
 
-	afs_timer_init(&vlocation->timeout,&afs_vlocation_timer_ops);
-	afs_timer_init(&vlocation->upd_timer,&afs_vlocation_update_timer_ops);
-	afs_async_op_init(&vlocation->upd_op,&afs_vlocation_update_op_ops);
+	afs_timer_init(&vlocation->timeout, &afs_vlocation_timer_ops);
+	afs_timer_init(&vlocation->upd_timer, &afs_vlocation_update_timer_ops);
+	afs_async_op_init(&vlocation->upd_op, &afs_vlocation_update_op_ops);
 
 	afs_get_cell(cell);
 	vlocation->cell = cell;
 
-	list_add_tail(&vlocation->link,&cell->vl_list);
+	list_add_tail(&vlocation->link, &cell->vl_list);
 
 	/* we want to store it in the cache, plus it might already be encached */
 	cachefs_acquire_cookie(cell->cache,
@@ -289,9 +301,10 @@
 		goto found_in_cache;
 
 	/* try to look up an unknown volume in the cell VL databases by name */
-	ret = afs_vlocation_access_vl_by_name(vlocation,name,&vldb);
+	ret = afs_vlocation_access_vl_by_name(vlocation, name, namesz, &vldb);
 	if (ret<0) {
-		printk("kAFS: failed to locate '%s' in cell '%s'\n",name,cell->name);
+		printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
+		       namesz, namesz, name, cell->name);
 		goto error;
 	}
 
@@ -302,7 +315,7 @@
 	_debug("found in graveyard");
 	atomic_inc(&vlocation->usage);
 	list_del(&vlocation->link);
-	list_add_tail(&vlocation->link,&cell->vl_list);
+	list_add_tail(&vlocation->link, &cell->vl_list);
 	spin_unlock(&cell->vl_gylock);
 
 	afs_kafstimod_del_timer(&vlocation->timeout);
@@ -323,13 +336,13 @@
 	_debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
 	       vlocation->vldb.name,
 	       vlocation->vldb.vidmask,
-	       ntohl(vlocation->vldb.servers[0].s_addr),vlocation->vldb.srvtmask[0],
-	       ntohl(vlocation->vldb.servers[1].s_addr),vlocation->vldb.srvtmask[1],
-	       ntohl(vlocation->vldb.servers[2].s_addr),vlocation->vldb.srvtmask[2]
+	       ntohl(vlocation->vldb.servers[0].s_addr), vlocation->vldb.srvtmask[0],
+	       ntohl(vlocation->vldb.servers[1].s_addr), vlocation->vldb.srvtmask[1],
+	       ntohl(vlocation->vldb.servers[2].s_addr), vlocation->vldb.srvtmask[2]
 	       );
 
 	_debug("Vids: %08x %08x %08x",
-	       vlocation->vldb.vid[0],vlocation->vldb.vid[1],vlocation->vldb.vid[2]);
+	       vlocation->vldb.vid[0], vlocation->vldb.vid[1], vlocation->vldb.vid[2]);
 
 	if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
 		vid = vlocation->vldb.vid[0];
@@ -349,12 +362,12 @@
 		voltype = 0;
 	}
 
-	ret = afs_vlocation_access_vl_by_id(vlocation,vid,voltype,&vldb);
+	ret = afs_vlocation_access_vl_by_id(vlocation, vid, voltype, &vldb);
 	switch (ret) {
 		/* net error */
 	default:
-		printk("kAFS: failed to volume '%s' (%x) up in '%s': %d\n",
-		       name,vid,cell->name,ret);
+		printk("kAFS: failed to volume '%*.*s' (%x) up in '%s': %d\n",
+		       namesz, namesz, name, vid, cell->name, ret);
 		goto error;
 
 		/* pulled from local cache into memory */
@@ -363,27 +376,30 @@
 
 		/* uh oh... looks like the volume got deleted */
 	case -ENOMEDIUM:
-		printk("kAFS: volume '%s' (%x) does not exist '%s'\n",name,vid,cell->name);
+		printk("kAFS: volume '%*.*s' (%x) does not exist '%s'\n",
+		       namesz, namesz, name, vid, cell->name);
 
 		/* TODO: make existing record unavailable */
 		goto error;
 	}
 
  found_on_vlserver:
-	_debug("Done VL Lookup: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
-	       name,
+	_debug("Done VL Lookup: %*.*s %02x { %08x(%x) %08x(%x) %08x(%x) }",
+	       namesz, namesz, name,
 	       vldb.vidmask,
-	       ntohl(vldb.servers[0].s_addr),vldb.srvtmask[0],
-	       ntohl(vldb.servers[1].s_addr),vldb.srvtmask[1],
-	       ntohl(vldb.servers[2].s_addr),vldb.srvtmask[2]
+	       ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
+	       ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
+	       ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
 	       );
 
-	_debug("Vids: %08x %08x %08x",vldb.vid[0],vldb.vid[1],vldb.vid[2]);
+	_debug("Vids: %08x %08x %08x", vldb.vid[0], vldb.vid[1], vldb.vid[2]);
 
-	if (strncmp(vldb.name,name,sizeof(vlocation->vldb.name))!=0)
-		printk("kAFS: name of volume '%s' changed to '%s' on server\n",name,vldb.name);
+	if ((namesz < sizeof(vlocation->vldb.name) && vlocation->vldb.name[namesz] != '\0') ||
+	    memcmp(vldb.name, name, namesz) != 0)
+		printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
+		       namesz, namesz, name, vldb.name);
 
-	memcpy(&vlocation->vldb,&vldb,sizeof(vlocation->vldb));
+	memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
 
 #if 0
 	/* add volume entry to local cache */
@@ -392,7 +408,7 @@
 		goto error;
 #endif
 
-	afs_kafstimod_add_timer(&vlocation->upd_timer,10*HZ);
+	afs_kafstimod_add_timer(&vlocation->upd_timer, 10*HZ);
 
 	*_vlocation = vlocation;
 	_leave(" = 0 (%p)",vlocation);
@@ -405,7 +421,7 @@
 		}
 		else {
 			list_del(&vlocation->link);
-			cachefs_relinquish_cookie(vlocation->cache,0);
+			cachefs_relinquish_cookie(vlocation->cache, 0);
 			afs_put_cell(vlocation->cell);
 			kfree(vlocation);
 		}
@@ -420,12 +436,17 @@
  * finish using a volume location record
  * - caller must have cell->vol_sem write-locked
  */
-void __afs_put_vlocation(afs_vlocation_t *vlocation)
+void __afs_put_vlocation(struct afs_vlocation *vlocation)
 {
-	afs_cell_t *cell = vlocation->cell;
+	struct afs_cell *cell;
+
+	if (!vlocation)
+		return;
 
 	_enter("%s",vlocation->vldb.name);
 
+	cell = vlocation->cell;
+
 	/* sanity check */
 	if (atomic_read(&vlocation->usage)<=0)
 		BUG();
@@ -459,11 +480,13 @@
  */
 void afs_put_vlocation(afs_vlocation_t *vlocation)
 {
-	afs_cell_t *cell = vlocation->cell;
+	if (vlocation) {
+		struct afs_cell *cell = vlocation->cell;
 
-	down_write(&cell->vl_sem);
-	__afs_put_vlocation(vlocation);
-	up_write(&cell->vl_sem);
+		down_write(&cell->vl_sem);
+		__afs_put_vlocation(vlocation);
+		up_write(&cell->vl_sem);
+	}
 } /* end afs_put_vlocation() */
 
 /*****************************************************************************/
@@ -575,10 +598,8 @@
 		printk("kAFS: Abandoning VL update '%s': %d\n",vlocation->vldb.name,ret);
 
 	/* discard the server record */
-	if (vlocation->upd_op.server) {
-		afs_put_server(vlocation->upd_op.server);
-		vlocation->upd_op.server = NULL;
-	}
+	afs_put_server(vlocation->upd_op.server);
+	vlocation->upd_op.server = NULL;
 
 	spin_lock(&afs_vlocation_update_lock);
 	afs_vlocation_update = NULL;
@@ -766,11 +787,9 @@
  try_next:
 	vlocation->upd_busy_cnt = 0;
 
-	if (vlocation->upd_op.server) {
-		/* discard the server record */
-		afs_put_server(vlocation->upd_op.server);
-		vlocation->upd_op.server = NULL;
-	}
+	/* discard the server record */
+	afs_put_server(vlocation->upd_op.server);
+	vlocation->upd_op.server = NULL;
 
 	tmp = vlocation->cell->vl_naddrs;
 	if (tmp==0)
@@ -832,20 +851,36 @@
  * match a VLDB record stored in the cache
  * - may also load target from entry
  */
-static cachefs_match_val_t afs_vlocation_cache_match(void *target, const void *entry)
+static cachefs_match_val_t afs_vlocation_cache_match(void *target,
+						     const void *entry)
 {
 	const struct afs_cache_vlocation *vldb = entry;
 	struct afs_vlocation *vlocation = target;
 
 	_enter("");
 
-	if (strncmp(vlocation->vldb.name,vldb->name,sizeof(vldb->name))==0) {
-		if (!vlocation->valid || vlocation->vldb.rtime == vldb->rtime) {
+	if (strncmp(vlocation->vldb.name,
+		    vldb->name,
+		    sizeof(vldb->name)) == 0) {
+		if (!vlocation->valid ||
+		    vlocation->vldb.rtime == vldb->rtime) {
 			struct_cpy(&vlocation->vldb,vldb);
 			vlocation->valid = 1;
+			return CACHEFS_MATCH_SUCCESS;
 		}
+		/* need to update cache if cached info differs */
+		else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
+			/* delete if VIDs for this name differ */
+			if (memcmp(&vlocation->vldb.vid,
+				   &vldb->vid,
+				   sizeof(vldb->vid)) != 0)
+				return CACHEFS_MATCH_SUCCESS_DELETE;
 
-		return CACHEFS_MATCH_SUCCESS;
+			return CACHEFS_MATCH_SUCCESS_UPDATE;
+		}
+		else {
+			return CACHEFS_MATCH_SUCCESS;
+		}
 	}
 
 	return CACHEFS_MATCH_FAILED;

Index: vlclient.h
===================================================================
RCS file: /home/cvs/afs/fs/afs/vlclient.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- vlclient.h	6 Jun 2003 08:33:37 -0000	1.4
+++ vlclient.h	4 Jul 2003 15:26:31 -0000	1.5
@@ -77,6 +77,7 @@
 /* look up a volume location database entry by name */
 extern int afs_rxvl_get_entry_by_name(afs_server_t *server,
 				      const char *volname,
+				      unsigned volnamesz,
 				      struct afs_cache_vlocation *entry);
 
 /* look up a volume location database entry by ID */

Index: vlclient.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/vlclient.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vlclient.c	6 Jun 2003 08:33:37 -0000	1.6
+++ vlclient.c	4 Jul 2003 15:26:31 -0000	1.7
@@ -176,7 +176,7 @@
 /*
  * look up a volume location database entry by name
  */
-int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
+int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsigned volnamesz,
 			       struct afs_cache_vlocation *entry)
 {
 	DECLARE_WAITQUEUE(myself,current);
@@ -189,29 +189,29 @@
 	int ret, loop;
 	u32 *bp, param[2], zero;
 
-	_enter(",%s,",volname);
+	_enter(",%*.*s,%u,", volnamesz, volnamesz, volname, volnamesz);
 
-	memset(entry,0,sizeof(*entry));
+	memset(entry, 0, sizeof(*entry));
 
 	/* get hold of the vlserver connection */
-	ret = afs_server_get_vlconn(server,&conn);
+	ret = afs_server_get_vlconn(server, &conn);
 	if (ret<0)
 		goto out;
 
 	/* create a call through that connection */
-	ret = rxrpc_create_call(conn,NULL,NULL,afs_rxvl_aemap,&call);
-	if (ret<0) {
-		printk("kAFS: Unable to create call: %d\n",ret);
+	ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
+	if (ret < 0) {
+		printk("kAFS: Unable to create call: %d\n", ret);
 		goto out_put_conn;
 	}
 	call->app_opcode = VLGETENTRYBYNAME;
 
 	/* we want to get event notifications from the call */
-	add_wait_queue(&call->waitq,&myself);
+	add_wait_queue(&call->waitq, &myself);
 
 	/* marshall the parameters */
-	piov[1].iov_len = strlen(volname);
-	piov[1].iov_base = (char*)volname;
+	piov[1].iov_len = volnamesz;
+	piov[1].iov_base = (char*) volname;
 
 	zero = 0;
 	piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
@@ -224,16 +224,16 @@
 	piov[0].iov_base = param;
 
 	/* send the parameters to the server */
-	ret = rxrpc_call_write_data(call,3,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
+	ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS, 0, &sent);
 	if (ret<0)
 		goto abort;
 
 	/* wait for the reply to completely arrive */
-	bp = rxrpc_call_alloc_scratch(call,384);
+	bp = rxrpc_call_alloc_scratch(call, 384);
 
-	ret = rxrpc_call_read_data(call,bp,384,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
-	if (ret<0) {
-		if (ret==-ECONNABORTED) {
+	ret = rxrpc_call_read_data(call, bp, 384, RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
+	if (ret < 0) {
+		if (ret == -ECONNABORTED) {
 			ret = call->app_errno;
 			goto out_unwait;
 		}
@@ -281,12 +281,12 @@
 
  out_unwait:
 	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&call->waitq,&myself);
+	remove_wait_queue(&call->waitq, &myself);
 	rxrpc_put_call(call);
  out_put_conn:
 	rxrpc_put_connection(conn);
  out:
-	_leave(" = %d",ret);
+	_leave(" = %d", ret);
 	return ret;
 
  abort:

Index: super.h
===================================================================
RCS file: /home/cvs/afs/fs/afs/super.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- super.h	14 Oct 2002 12:06:58 -0000	1.2
+++ super.h	4 Jul 2003 15:26:31 -0000	1.3
@@ -29,7 +29,7 @@
  */
 struct afs_super_info
 {
-	afs_volume_t		*volume;	/* volume record */
+	struct afs_volume	*volume;	/* volume record */
 	char			rwparent;	/* T if parent is R/W AFS volume */
 };
 

Index: super.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/super.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- super.c	16 Oct 2002 12:45:03 -0000	1.8
+++ super.c	4 Jul 2003 15:26:31 -0000	1.9
@@ -29,18 +29,26 @@
 
 #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
 
+struct afs_mount_params {
+	int			rwpath;
+	struct afs_cell		*default_cell;
+	struct afs_volume	*volume;
+};
+
 static inline char *strdup(const char *s)
 {
-	char *ns = kmalloc(strlen(s)+1,GFP_KERNEL);
+	char *ns = kmalloc(strlen(s) + 1, GFP_KERNEL);
 	if (ns)
-		strcpy(ns,s);
+		strcpy(ns, s);
 	return ns;
 }
 
-static void afs_i_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags);
+static void afs_i_init_once(void *foo, kmem_cache_t *cachep,
+			    unsigned long flags);
 
 static struct super_block *afs_get_sb(struct file_system_type *fs_type,
-				      int flags, char *dev_name, void *data);
+				      int flags, const char *dev_name,
+				      void *data);
 
 static struct inode *afs_alloc_inode(struct super_block *sb);
 
@@ -65,6 +73,7 @@
 };
 
 static kmem_cache_t *afs_inode_cachep;
+static atomic_t afs_count_active_inodes;
 
 /*****************************************************************************/
 /*
@@ -76,14 +85,18 @@
 
 	kenter("");
 
+	afs_timer_init(&afs_mntpt_expiry_timer, &afs_mntpt_expiry_timer_ops);
+
 	/* create ourselves an inode cache */
+	atomic_set(&afs_count_active_inodes, 0);
+
 	ret = -ENOMEM;
 	afs_inode_cachep = kmem_cache_create("afs_inode_cache",
-						sizeof(afs_vnode_t),
-						0,
-						SLAB_HWCACHE_ALIGN,
-						afs_i_init_once,
-						NULL);
+					     sizeof(afs_vnode_t),
+					     0,
+					     SLAB_HWCACHE_ALIGN,
+					     afs_i_init_once,
+					     NULL);
 	if (!afs_inode_cachep) {
 		printk(KERN_NOTICE "kAFS: Failed to allocate inode cache\n");
 		return ret;
@@ -91,9 +104,9 @@
 
 	/* now export our filesystem to lesser mortals */
 	ret = register_filesystem(&afs_fs_type);
-	if (ret<0) {
+	if (ret < 0) {
 		kmem_cache_destroy(afs_inode_cachep);
-		kleave(" = %d",ret);
+		kleave(" = %d", ret);
 		return ret;
 	}
 
@@ -107,11 +120,16 @@
  */
 void __exit afs_fs_exit(void)
 {
-	/* destroy our private inode cache */
-	kmem_cache_destroy(afs_inode_cachep);
-
 	unregister_filesystem(&afs_fs_type);
 
+	if (atomic_read(&afs_count_active_inodes) != 0) {
+		printk("kAFS: %d active inode objects still present\n",
+		       atomic_read(&afs_count_active_inodes));
+		BUG();
+	}
+
+	kmem_cache_destroy(afs_inode_cachep);
+
 } /* end afs_fs_exit() */
 
 /*****************************************************************************/
@@ -121,7 +139,7 @@
 static int want_arg(char **_value, const char *option)
 {
 	if (!_value || !*_value || !**_value) {
-		printk(KERN_NOTICE "kAFS: %s: argument missing\n",option);
+		printk(KERN_NOTICE "kAFS: %s: argument missing\n", option);
 		return 0;
 	}
 	return 1;
@@ -129,27 +147,13 @@
 
 /*****************************************************************************/
 /*
- * check that there is a value
- */
-#if 0
-static int want_value(char **_value, const char *option)
-{
-	if (!_value || !*_value || !**_value) {
-		printk(KERN_NOTICE "kAFS: %s: argument incomplete\n",option);
-		return 0;
-	}
-	return 1;
-} /* end want_value() */
-#endif
-
-/*****************************************************************************/
-/*
  * check that there's no subsequent value
  */
 static int want_no_value(char *const *_value, const char *option)
 {
 	if (*_value && **_value) {
-		printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",option,*_value);
+		printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",
+		       option, *_value);
 		return 0;
 	}
 	return 1;
@@ -157,150 +161,55 @@
 
 /*****************************************************************************/
 /*
- * extract a number from an option string value
- */
-#if 0
-static int want_number(char **_value, const char *option, unsigned long *number,
-		       unsigned long limit)
-{
-	char *value = *_value;
-
-	if (!want_value(_value,option))
-		return 0;
-
-	*number = simple_strtoul(value,_value,0);
-
-	if (value==*_value) {
-		printk(KERN_NOTICE "kAFS: %s: Invalid number: %s\n",option,value);
-		return 0;
-	}
-
-	if (*number>limit) {
-		printk(KERN_NOTICE "kAFS: %s: numeric value %lu > %lu\n",option,*number,limit);
-		return 0;
-	}
-
-	return 1;
-} /* end want_number() */
-#endif
-
-/*****************************************************************************/
-/*
- * extract a separator from an option string value
- */
-#if 0
-static int want_sep(char **_value, const char *option, char sep)
-{
-	if (!want_value(_value,option))
-		return 0;
-
-	if (*(*_value)++ != sep) {
-		printk(KERN_NOTICE "kAFS: %s: '%c' expected: %s\n",option,sep,*_value-1);
-		return 0;
-	}
-
-	return 1;
-} /* end want_number() */
-#endif
-
-/*****************************************************************************/
-/*
- * extract an IP address from an option string value
- */
-#if 0
-static int want_ipaddr(char **_value, const char *option, struct in_addr *addr)
-{
-	unsigned long number[4];
-
-	if (!want_value(_value,option))
-		return 0;
-
-	if (!want_number(_value,option,&number[0],255) ||
-	    !want_sep(_value,option,'.') ||
-	    !want_number(_value,option,&number[1],255) ||
-	    !want_sep(_value,option,'.') ||
-	    !want_number(_value,option,&number[2],255) ||
-	    !want_sep(_value,option,'.') ||
-	    !want_number(_value,option,&number[3],255))
-		return 0;
-
-	((u8*)addr)[0] = number[0];
-	((u8*)addr)[1] = number[1];
-	((u8*)addr)[2] = number[2];
-	((u8*)addr)[3] = number[3];
-
-	return 1;
-} /* end want_numeric() */
-#endif
-
-/*****************************************************************************/
-/*
  * parse the mount options
  * - this function has been shamelessly adapted from the ext3 fs which shamelessly adapted it from
  *   the msdos fs
  */
-static int afs_super_parse_options(struct afs_super_info *as, char *options, char **devname)
+static int afs_super_parse_options(struct afs_mount_params *params,
+				   char *options,
+				   const char **devname)
 {
 	char *key, *value;
 	int ret;
 
-	_enter("%s",options);
+	_enter("%s", options);
+
+	options[PAGE_SIZE - 1] = 0;
 
 	ret = 0;
-	while ((key = strsep(&options,",")))
+	while ((key = strsep(&options, ",")))
 	{
-		value = strchr(key,'=');
+		value = strchr(key, '=');
 		if (value)
 			*value++ = 0;
 
-		printk("kAFS: KEY: %s, VAL:%s\n",key,value?:"-");
+		printk("kAFS: KEY: %s, VAL:%s\n", key, value ?: "-");
 
-		if (strcmp(key,"rwpath")==0) {
-			if (!want_no_value(&value,"rwpath")) return -EINVAL;
-			as->rwparent = 1;
+		if (strcmp(key, "rwpath") == 0) {
+			if (!want_no_value(&value, "rwpath"))
+				return -EINVAL;
+			params->rwpath = 1;
 			continue;
 		}
-		else if (strcmp(key,"vol")==0) {
-			if (!want_arg(&value,"vol")) return -EINVAL;
+		else if (strcmp(key, "vol") == 0) {
+			if (!want_arg(&value, "vol"))
+				return -EINVAL;
 			*devname = value;
 			continue;
 		}
-
-#if 0
-		if (strcmp(key,"servers")==0) {
-			if (!want_arg(&value,"servers")) return -EINVAL;
-
-			_debug("servers=%s",value);
-
-			for (;;) {
-				struct in_addr addr;
-
-				if (!want_ipaddr(&value,"servers",&addr))
-					return -EINVAL;
-
-				ret = afs_create_server(as->cell,&addr,&as->server);
-				if (ret<0) {
-					printk("kAFS: unable to create server: %d\n",ret);
-					return ret;
-				}
-
-				if (!*value)
-					break;
-
-				if (as->server) {
-					printk(KERN_NOTICE
-					       "kAFS: only one server can be specified\n");
-					return -EINVAL;
-				}
-
-				if (!want_sep(&value,"servers",':'))
-					return -EINVAL;
-			}
+		else if (strcmp(key, "cell") == 0) {
+			if (!want_arg(&value, "cell"))
+				return -EINVAL;
+			afs_put_cell(params->default_cell);
+			ret = afs_cell_lookup(value,
+					      strlen(value),
+					      &params->default_cell);
+			if (ret < 0)
+				return -EINVAL;
 			continue;
 		}
-#endif
 
-		printk("kAFS: Unknown mount option: '%s'\n",key);
+		printk("kAFS: Unknown mount option: '%s'\n",  key);
 		ret = -EINVAL;
 		goto error;
 	}
@@ -308,61 +217,48 @@
 	ret = 0;
 
  error:
-	_leave(" = %d",ret);
-
+	_leave(" = %d", ret);
 	return ret;
 } /* end afs_super_parse_options() */
 
 /*****************************************************************************/
 /*
+ * check a superblock to see if it's the one we're looking for
+ */
+static int afs_test_super(struct super_block *sb, void *data)
+{
+	struct afs_mount_params *params = data;
+	struct afs_super_info *as = sb->s_fs_info;
+
+	return as->volume == params->volume;
+} /* end afs_test_super() */
+
+/*****************************************************************************/
+/*
  * fill in the superblock
  */
-static int afs_fill_super(struct super_block *sb, void *_data, int silent)
+static int afs_fill_super(struct super_block *sb, void *data, int silent)
 {
+	struct afs_mount_params *params = data;
 	struct afs_super_info *as = NULL;
 	struct dentry *root = NULL;
 	struct inode *inode = NULL;
 	afs_fid_t fid;
-	void **data = _data;
-	char *options, *devname;
 	int ret;
 
-	_enter("");
-
-	if (!data) {
-		_leave(" = -EINVAL");
-		return -EINVAL;
-	}
-	devname = data[0];
-	options = data[1];
-	if (options)
-		options[PAGE_SIZE-1] = 0;
+	kenter("");
 
 	/* allocate a superblock info record */
-	as = kmalloc(sizeof(struct afs_super_info),GFP_KERNEL);
+	as = kmalloc(sizeof(struct afs_super_info), GFP_KERNEL);
 	if (!as) {
 		_leave(" = -ENOMEM");
 		return -ENOMEM;
 	}
 
-	memset(as,0,sizeof(struct afs_super_info));
-
-	/* parse the options */
-	if (options) {
-		ret = afs_super_parse_options(as,options,&devname);
-		if (ret<0)
-			goto error;
-		if (!devname) {
-			printk("kAFS: no volume name specified\n");
-			ret = -EINVAL;
-			goto error;
-		}
-	}
+	memset(as, 0, sizeof(struct afs_super_info));
 
-	/* parse the device name */
-	ret = afs_volume_lookup(devname,as->rwparent,&as->volume);
-	if (ret<0)
-		goto error;
+	afs_get_volume(params->volume);
+	as->volume = params->volume;
 
 	/* fill in the superblock */
 	sb->s_blocksize		= PAGE_CACHE_SIZE;
@@ -375,8 +271,8 @@
 	fid.vid		= as->volume->vid;
 	fid.vnode	= 1;
 	fid.unique	= 1;
-	ret = afs_iget(sb,&fid,&inode);
-	if (ret<0)
+	ret = afs_iget(sb, &fid, &inode);
+	if (ret < 0)
 		goto error;
 
 	ret = -ENOMEM;
@@ -386,19 +282,18 @@
 
 	sb->s_root = root;
 
-	_leave(" = 0");
+	kleave(" = 0");
 	return 0;
 
  error:
-	if (root) dput(root);
-	if (inode) iput(inode);
-	if (as) {
-		if (as->volume)		afs_put_volume(as->volume);
-		kfree(as);
-	}
+	dput(root);
+	iput(inode);
+	afs_put_volume(as->volume);
+	kfree(as);
+
 	sb->s_fs_info = NULL;
 
-	_leave(" = %d",ret);
+	kleave(" = %d", ret);
 	return ret;
 } /* end afs_fill_super() */
 
@@ -409,31 +304,78 @@
  */
 static struct super_block *afs_get_sb(struct file_system_type *fs_type,
 				      int flags,
-				      char *dev_name,
+				      const char *dev_name,
 				      void *options)
 {
+	struct afs_mount_params params;
 	struct super_block *sb;
-	void *data[2] = { dev_name, options };
 	int ret;
 
-	_enter(",,%s,%p",dev_name,options);
+	kenter(",,%s,%p", dev_name, options);
+
+	memset(&params, 0, sizeof(params));
 
 	/* start the cache manager */
 	ret = afscm_start();
-	if (ret<0) {
-		_leave(" = %d",ret);
+	if (ret < 0) {
+		kleave(" = %d", ret);
 		return ERR_PTR(ret);
 	}
 
+	/* parse the options */
+	if (options) {
+		ret = afs_super_parse_options(&params, options, &dev_name);
+		if (ret < 0)
+			goto error;
+		if (!dev_name) {
+			printk("kAFS: no volume name specified\n");
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	/* parse the device name */
+	ret = afs_volume_lookup(dev_name,
+				params.default_cell,
+				params.rwpath,
+				&params.volume);
+	if (ret < 0)
+		goto error;
+
 	/* allocate a deviceless superblock */
-	sb = get_sb_nodev(fs_type,flags,data,afs_fill_super);
-	if (IS_ERR(sb)) {
+#if 0
+	sb = get_sb_nodev(fs_type, flags, &params, afs_fill_super);
+	if (IS_ERR(sb))
 		afscm_stop();
-		return sb;
+
+#else
+	sb = sget(fs_type, afs_test_super, set_anon_super, &params);
+	if (IS_ERR(sb))
+		goto error;
+
+	sb->s_flags = flags;
+
+	ret = afs_fill_super(sb, &params, flags & MS_VERBOSE ? 1 : 0);
+	if (ret < 0) {
+		up_write(&sb->s_umount);
+		deactivate_super(sb);
+		goto error;
 	}
+	sb->s_flags |= MS_ACTIVE;
 
-	_leave("");
+#endif
+
+	afs_put_volume(params.volume);
+	afs_put_cell(params.default_cell);
+	kleave(" = %p", sb);
 	return sb;
+
+ error:
+	afs_put_volume(params.volume);
+	afs_put_cell(params.default_cell);
+	afscm_stop();
+	kleave(" = %d", ret);
+	return ERR_PTR(ret);
 } /* end afs_get_sb() */
 
 /*****************************************************************************/
@@ -446,11 +388,7 @@
 
 	_enter("");
 
-	if (as) {
-		if (as->volume)		afs_put_volume(as->volume);
-	}
-
-	/* stop the cache manager */
+	afs_put_volume(as->volume);
 	afscm_stop();
 
 	_leave("");
@@ -460,18 +398,21 @@
 /*
  * initialise an inode cache slab element prior to any use
  */
-static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, unsigned long flags)
+static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep,
+			    unsigned long flags)
 {
 	afs_vnode_t *vnode = (afs_vnode_t *) _vnode;
 
-	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) {
-		memset(vnode,0,sizeof(*vnode));
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		memset(vnode, 0, sizeof(*vnode));
 		inode_init_once(&vnode->vfs_inode);
 		init_waitqueue_head(&vnode->update_waitq);
 		spin_lock_init(&vnode->lock);
 		INIT_LIST_HEAD(&vnode->cb_link);
 		INIT_LIST_HEAD(&vnode->cb_hash_link);
-		afs_timer_init(&vnode->cb_timeout,&afs_vnode_cb_timed_out_ops);
+		afs_timer_init(&vnode->cb_timeout,
+			       &afs_vnode_cb_timed_out_ops);
 	}
 
 } /* end afs_i_init_once() */
@@ -484,16 +425,19 @@
 {
 	afs_vnode_t *vnode;
 
-	vnode = (afs_vnode_t *) kmem_cache_alloc(afs_inode_cachep,SLAB_KERNEL);
+	vnode = (afs_vnode_t *)
+		kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL);
 	if (!vnode)
 		return NULL;
 
-	memset(&vnode->fid,0,sizeof(vnode->fid));
-	memset(&vnode->status,0,sizeof(vnode->status));
+	atomic_inc(&afs_count_active_inodes);
 
-	vnode->volume = NULL;
-	vnode->update_cnt = 0;
-	vnode->flags = 0;
+	memset(&vnode->fid, 0, sizeof(vnode->fid));
+	memset(&vnode->status, 0, sizeof(vnode->status));
+
+	vnode->volume		= NULL;
+	vnode->update_cnt	= 0;
+	vnode->flags		= 0;
 
 	return &vnode->vfs_inode;
 } /* end afs_alloc_inode() */
@@ -504,6 +448,10 @@
  */
 static void afs_destroy_inode(struct inode *inode)
 {
-	_enter("{%lu}",inode->i_ino);
+	_enter("{%lu}", inode->i_ino);
+
 	kmem_cache_free(afs_inode_cachep, AFS_FS_I(inode));
+
+	atomic_dec(&afs_count_active_inodes);
+
 } /* end afs_destroy_inode() */

Index: server.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/server.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- server.c	16 Oct 2002 09:59:50 -0000	1.3
+++ server.c	4 Jul 2003 15:26:31 -0000	1.4
@@ -148,6 +148,9 @@
 {
 	afs_cell_t *cell;
 
+	if (!server)
+		return;
+
 	_enter("%p",server);
 
 	cell = server->cell;

Index: mntpt.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/mntpt.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- mntpt.c	16 Oct 2002 12:45:03 -0000	1.6
+++ mntpt.c	4 Jul 2003 15:26:31 -0000	1.7
@@ -16,13 +16,20 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/namespace.h>
+#include "super.h"
+#include "cell.h"
 #include "volume.h"
 #include "vnode.h"
+#define __KDEBUG
 #include "internal.h"
 
 
 static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry);
 static int afs_mntpt_open(struct inode *inode, struct file *file);
+static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
 
 struct file_operations afs_mntpt_file_operations = {
 	.open		= afs_mntpt_open,
@@ -30,10 +37,23 @@
 
 struct inode_operations afs_mntpt_inode_operations = {
 	.lookup		= afs_mntpt_lookup,
+	.follow_link	= afs_mntpt_follow_link,
 	.readlink	= page_readlink,
 	.getattr	= afs_inode_getattr,
 };
 
+static LIST_HEAD(afs_vfsmounts);
+
+static void afs_mntpt_expiry_timed_out(struct afs_timer *timer);
+
+struct afs_timer_ops afs_mntpt_expiry_timer_ops = {
+	.timed_out	= afs_mntpt_expiry_timed_out,
+};
+
+struct afs_timer afs_mntpt_expiry_timer;
+
+unsigned long afs_mntpt_expiry_timeout = 20;
+
 /*****************************************************************************/
 /*
  * check a symbolic link to see whether it actually encodes a mountpoint
@@ -95,6 +115,13 @@
  */
 static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry)
 {
+	kenter("%p,%p{%p{%s},%s}",
+	       dir,
+	       dentry,
+	       dentry->d_parent,
+	       dentry->d_parent ? dentry->d_parent->d_name.name : (const unsigned char*)"",
+	       dentry->d_name.name);
+
 	return ERR_PTR(-EREMOTE);
 } /* end afs_mntpt_lookup() */
 
@@ -104,5 +131,144 @@
  */
 static int afs_mntpt_open(struct inode *inode, struct file *file)
 {
+	kenter("%p,%p{%p{%s},%s}",
+	       inode, file,
+	       file->f_dentry->d_parent,
+	       file->f_dentry->d_parent ? file->f_dentry->d_parent->d_name.name : (const unsigned char*)"",
+	       file->f_dentry->d_name.name);
+
 	return -EREMOTE;
 } /* end afs_mntpt_open() */
+
+/*****************************************************************************/
+/*
+ * create a vfsmount to be automounted
+ */
+static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
+{
+	struct afs_super_info *super;
+	struct vfsmount *mnt;
+	struct page *page = NULL;
+	size_t size;
+	char *buf, *devname = NULL, *options = NULL;
+	int ret;
+
+	kenter("{%s}", mntpt->d_name.name);
+
+	BUG_ON(!mntpt->d_inode);
+
+	ret = -EINVAL;
+	size = mntpt->d_inode->i_size;
+	if (size > PAGE_SIZE - 1)
+		goto error;
+
+	ret = -ENOMEM;
+	devname = (char *) get_zeroed_page(GFP_KERNEL);
+	if (!devname)
+		goto error;
+
+	options = (char *) get_zeroed_page(GFP_KERNEL);
+	if (!options)
+		goto error;
+
+	/* read the contents of the AFS special symlink */
+	page = read_cache_page(mntpt->d_inode->i_mapping,
+			       0,
+			       (filler_t*)mntpt->d_inode->i_mapping->a_ops->readpage,
+			       NULL);
+	if (IS_ERR(page)) {
+		ret = PTR_ERR(page);
+		goto error;
+	}
+
+	ret = -EIO;
+	wait_on_page_locked(page);
+	if (!PageUptodate(page) || PageError(page))
+		goto error;
+
+	buf = kmap(page);
+	memcpy(devname, buf, size);
+	kunmap(page);
+	page_cache_release(page);
+	page = NULL;
+
+	/* work out what options we want */
+	super = AFS_FS_S(mntpt->d_sb);
+	memcpy(options, "cell=", 5);
+	strcpy(options + 5, super->volume->cell->name);
+	if (super->volume->type == AFSVL_RWVOL)
+		strcat(options,",rwpath");
+
+	/* try and do the mount */
+	kdebug("--- attempting mount %s -o %s ---", devname, options);
+	mnt = do_kern_mount("afs", 0, devname, options);
+	kdebug("--- mount result %p ---", mnt);
+
+	free_page((unsigned long)devname);
+	free_page((unsigned long)options);
+	kleave(" = %p",mnt);
+	return mnt;
+
+ error:
+	if (page)
+		page_cache_release(page);
+	if (devname)
+		free_page((unsigned long)devname);
+	if (options)
+		free_page((unsigned long)options);
+	kleave(" = %d",ret);
+	return ERR_PTR(ret);
+} /* end afs_mntpt_do_automount() */
+
+/*****************************************************************************/
+/*
+ * follow a link from a mountpoint directory, thus causing it to be mounted
+ */
+static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	struct nameidata newnd;
+	struct vfsmount *newmnt;
+	int err;
+
+	kenter("%p{%s},{%s:%p{%s}}",
+	       dentry,
+	       dentry->d_name.name,
+	       nd->mnt->mnt_devname,
+	       dentry,
+	       nd->dentry->d_name.name);
+
+	newmnt = afs_mntpt_do_automount(dentry);
+	if (IS_ERR(newmnt))
+		return PTR_ERR(newmnt);
+
+	struct_cpy(&newnd,nd);
+	newnd.dentry = dentry;
+	err = do_add_mount(newmnt, &newnd, 0, &afs_vfsmounts);
+
+	if (!err) {
+		path_release(nd);
+		mntget(newmnt);
+		nd->mnt = newmnt;
+		dget(newmnt->mnt_root);
+		nd->dentry = newmnt->mnt_root;
+	}
+
+	kleave(" = %d", err);
+	return err;
+} /* end afs_mntpt_follow_link() */
+
+/*****************************************************************************/
+/*
+ * handle mountpoint expiry timer going off
+ */
+static void afs_mntpt_expiry_timed_out(struct afs_timer *timer)
+{
+	kenter("");
+
+	mark_mounts_for_expiry(&afs_vfsmounts);
+
+	afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
+				afs_mntpt_expiry_timeout * HZ);
+
+	kleave("");
+} /* end afs_mntpt_expiry_timed_out() */

Index: main.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/main.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- main.c	6 Jun 2003 08:33:37 -0000	1.11
+++ main.c	4 Jul 2003 15:26:31 -0000	1.12
@@ -210,3 +210,48 @@
 	_leave("");
 
 } /* end afs_discarding_peer() */
+
+/*****************************************************************************/
+/*
+ * clear the dead space between task_struct and kernel stack
+ * - called by supplying -finstrument-functions to gcc
+ */
+#if 1
+void __cyg_profile_func_enter (void *this_fn, void *call_site)
+__attribute__((no_instrument_function));
+
+void __cyg_profile_func_enter (void *this_fn, void *call_site)
+{
+       asm volatile("  movl    %%esp,%%edi     \n"
+                    "  andl    %0,%%edi        \n"
+                    "  addl    %1,%%edi        \n"
+                    "  movl    %%esp,%%ecx     \n"
+                    "  subl    %%edi,%%ecx     \n"
+                    "  shrl    $2,%%ecx        \n"
+                    "  movl    $0xedededed,%%eax     \n"
+                    "  rep stosl               \n"
+                    :
+                    : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
+                    : "eax", "ecx", "edi", "memory", "cc"
+                    );
+}
+
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
+__attribute__((no_instrument_function));
+
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
+{
+       asm volatile("  movl    %%esp,%%edi     \n"
+                    "  andl    %0,%%edi        \n"
+                    "  addl    %1,%%edi        \n"
+                    "  movl    %%esp,%%ecx     \n"
+                    "  subl    %%edi,%%ecx     \n"
+                    "  shrl    $2,%%ecx        \n"
+                    "  movl    $0xdadadada,%%eax     \n"
+                    "  rep stosl               \n"
+                    :
+                    : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
+                    : "eax", "ecx", "edi", "memory", "cc"
+                    );
+}
+#endif

Index: kafstimod.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/kafstimod.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- kafstimod.c	9 Apr 2003 15:43:07 -0000	1.6
+++ kafstimod.c	4 Jul 2003 15:26:31 -0000	1.7
@@ -177,7 +177,7 @@
 	wake_up(&kafstimod_sleepq);
 
 	_leave("");
-} /* end afs_kafstimod_queue_vlocation() */
+} /* end afs_kafstimod_add_timer() */
 
 /*****************************************************************************/
 /*

Index: internal.h
===================================================================
RCS file: /home/cvs/afs/fs/afs/internal.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- internal.h	6 Jun 2003 08:33:37 -0000	1.14
+++ internal.h	4 Jul 2003 15:26:31 -0000	1.15
@@ -28,7 +28,7 @@
 #define kproto(FMT, a...)	printk("### "FMT"\n" , ## a)
 #define knet(FMT, a...)		printk(FMT"\n" , ## a)
 
-#if 0
+#ifdef __KDEBUG
 #define _enter(FMT, a...)	kenter(FMT , ## a)
 #define _leave(FMT, a...)	kleave(FMT , ## a)
 #define _debug(FMT, a...)	kdebug(FMT , ## a)
@@ -92,8 +92,11 @@
  */
 extern struct inode_operations afs_mntpt_inode_operations;
 extern struct file_operations afs_mntpt_file_operations;
+extern struct afs_timer afs_mntpt_expiry_timer;
+extern struct afs_timer_ops afs_mntpt_expiry_timer_ops;
 
 extern int afs_mntpt_check_symlink(afs_vnode_t *vnode);
+extern unsigned long afs_mntpt_expiry_timeout;
 
 /*
  * super.c

Index: inode.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/inode.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- inode.c	9 Jun 2003 13:39:13 -0000	1.10
+++ inode.c	4 Jul 2003 15:26:31 -0000	1.11
@@ -79,7 +79,7 @@
 	inode->i_mapping->a_ops	= &afs_fs_aops;
 
 	/* check to see whether a symbolic link is really a mountpoint */
-	if (vnode->status.type==AFS_FTYPE_SYMLINK) {
+	if (vnode->status.type == AFS_FTYPE_SYMLINK) {
 		afs_mntpt_check_symlink(vnode);
 
 		if (vnode->flags & AFS_VNODE_MOUNTPOINT) {
@@ -105,7 +105,7 @@
 
 	ret = afs_vnode_fetch_status(vnode);
 
-	if (ret==0)
+	if (ret == 0)
 		ret = afs_inode_map_status(vnode);
 
 	return ret;
@@ -120,8 +120,8 @@
 {
 	struct afs_iget_data *data = opaque;
 
-	/* only match inodes with the same version number */
-	return inode->i_ino==data->fid.vnode && inode->i_version==data->fid.unique;
+	return inode->i_ino == data->fid.vnode &&
+		inode->i_version == data->fid.unique;
 } /* end afs_iget5_test() */
 
 /*****************************************************************************/
@@ -145,7 +145,8 @@
 /*
  * inode retrieval
  */
-inline int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inode)
+inline int afs_iget(struct super_block *sb, afs_fid_t *fid,
+		    struct inode **_inode)
 {
 	struct afs_iget_data data = { fid: *fid };
 	struct afs_super_info *as;
@@ -153,12 +154,13 @@
 	struct inode *inode;
 	int ret;
 
-	_enter(",{%u,%u,%u},,",fid->vid,fid->vnode,fid->unique);
+	_enter(",{%u,%u,%u},,", fid->vid, fid->vnode, fid->unique);
 
 	as = sb->s_fs_info;
 	data.volume = as->volume;
 
-	inode = iget5_locked(sb,fid->vnode,afs_iget5_test,afs_iget5_set,&data);
+	inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
+			     &data);
 	if (!inode) {
 		_leave(" = -ENOMEM");
 		return -ENOMEM;
@@ -173,7 +175,7 @@
 			*_inode = inode;
 		else
 			iput(inode);
-		_leave(" = %d",ret);
+		_leave(" = %d", ret);
 		return ret;
 	}
 
@@ -208,7 +210,7 @@
 	unlock_new_inode(inode);
 	iput(inode);
 
-	_leave(" = %d [bad]",ret);
+	_leave(" = %d [bad]", ret);
 	return ret;
 } /* end afs_iget() */
 
@@ -216,7 +218,8 @@
 /*
  * read the attributes of an inode
  */
-int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
+		      struct kstat *stat)
 {
 	struct inode *inode;
 	afs_vnode_t *vnode;
@@ -224,23 +227,25 @@
 
 	inode = dentry->d_inode;
 
-	_enter("{ ino=%lu v=%lu }",inode->i_ino,inode->i_version);
+	_enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version);
 
 	vnode = AFS_FS_I(inode);
 
 	ret = afs_inode_fetch_status(inode);
-	if (ret==-ENOENT) {
-		_leave(" = %d [%d %p]",ret,atomic_read(&dentry->d_count),dentry->d_inode);
+	if (ret == -ENOENT) {
+		_leave(" = %d [%d %p]",
+		       ret, atomic_read(&dentry->d_count), dentry->d_inode);
 		return ret;
 	}
-	else if (ret<0) {
+	else if (ret < 0) {
 		make_bad_inode(inode);
-		_leave(" = %d",ret);
+		_leave(" = %d", ret);
 		return ret;
 	}
 
-	/* transfer attributes from the inode structure to the stat structure */
-	generic_fillattr(inode,stat);
+	/* transfer attributes from the inode structure to the stat
+	 * structure */
+	generic_fillattr(inode, stat);
 
 	_leave(" = 0 CB { v=%u x=%u t=%u }",
 	       vnode->cb_version,
@@ -268,11 +273,11 @@
 	       vnode->cb_type
 	       );
 
-	if (inode->i_ino!=vnode->fid.vnode) BUG();
+	BUG_ON(inode->i_ino != vnode->fid.vnode);
 
 	afs_vnode_give_up_callback(vnode);
 
-	cachefs_relinquish_cookie(vnode->cache,0);
+	cachefs_relinquish_cookie(vnode->cache, 0);
 	vnode->cache = NULL;
 
 	_leave("");

Index: file.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/file.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- file.c	10 Jun 2003 17:49:49 -0000	1.7
+++ file.c	4 Jul 2003 15:26:31 -0000	1.8
@@ -230,8 +230,13 @@
 		 * The get_block cached value has been unconditionally invalidated,
 		 * so real IO is not possible anymore.
 		 */
-		if (offset == 0)
-			ret = try_to_release_page(page,0);
+		if (offset == 0) {
+			BUG_ON(!PageLocked(page));
+
+			ret = 0;
+			if (!PageWriteback(page))
+				ret = page->mapping->a_ops->releasepage(page, 0);
+		}
 	}
 
 	_leave(" = %d",ret);

Index: dir.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/dir.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- dir.c	9 Apr 2003 15:43:07 -0000	1.9
+++ dir.c	4 Jul 2003 15:26:31 -0000	1.10
@@ -423,11 +423,11 @@
 	unsigned fpos;
 	int ret;
 
-	_enter("{%lu},{%s}",dir->i_ino,dentry->d_name.name);
+	_enter("{%lu},%p{%s}",dir->i_ino,dentry,dentry->d_name.name);
 
 	/* insanity checks first */
-	if (sizeof(afs_dir_block_t) != 2048) BUG();
-	if (sizeof(afs_dirent_t) != 32) BUG();
+	BUG_ON(sizeof(afs_dir_block_t) != 2048);
+	BUG_ON(sizeof(afs_dirent_t) != 32);
 
 	if (dentry->d_name.len > 255) {
 		_leave(" = -ENAMETOOLONG");
@@ -495,7 +495,7 @@
 	unsigned fpos;
 	int ret;
 
-	_enter("%s,%x",dentry->d_name.name,flags);
+	_enter("{sb=%p n=%s},%x",dentry->d_sb,dentry->d_name.name,flags);
 
 	/* lock down the parent dentry so we can peer at it */
 	parent = dget_parent(dentry->d_parent);

Index: cmservice.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/cmservice.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- cmservice.c	2 Mar 2003 18:56:15 -0000	1.6
+++ cmservice.c	4 Jul 2003 15:26:31 -0000	1.7
@@ -301,15 +301,18 @@
 
 	down_write(&afscm_sem);
 	if (!afscm_usage) {
-		ret = kernel_thread(kafscmd,NULL,0);
-		if (ret<0)
+		ret = kernel_thread(kafscmd, NULL, 0);
+		if (ret < 0)
 			goto out;
 
 		wait_for_completion(&kafscmd_alive);
 
-		ret = rxrpc_add_service(afs_transport,&AFSCM_service);
+		ret = rxrpc_add_service(afs_transport, &AFSCM_service);
 		if (ret<0)
 			goto kill;
+
+		afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
+					afs_mntpt_expiry_timeout * HZ);
 	}
 
 	afscm_usage++;
@@ -338,17 +341,20 @@
 
 	down_write(&afscm_sem);
 
-	if (afscm_usage==0) BUG();
+	if (afscm_usage == 0) BUG();
 	afscm_usage--;
 
-	if (afscm_usage==0) {
+	if (afscm_usage == 0) {
 		/* don't want more incoming calls */
-		rxrpc_del_service(afs_transport,&AFSCM_service);
+		rxrpc_del_service(afs_transport, &AFSCM_service);
 
 		/* abort any calls I've still got open (the afscm_error() will dequeue them) */
 		spin_lock(&afscm_calls_lock);
 		while (!list_empty(&afscm_calls)) {
-			call = list_entry(afscm_calls.next,struct rxrpc_call,app_link);
+			call = list_entry(afscm_calls.next,
+					  struct rxrpc_call,
+					  app_link);
+
 			list_del_init(&call->app_link);
 			rxrpc_get_call(call);
 			spin_unlock(&afscm_calls_lock);
@@ -356,7 +362,8 @@
 			rxrpc_call_abort(call,-ESRCH); /* abort, dequeue and put */
 
 			_debug("nuking active call %08x.%d",
-			       ntohl(call->conn->conn_id),ntohl(call->call_id));
+			       ntohl(call->conn->conn_id),
+			       ntohl(call->call_id));
 			rxrpc_put_call(call);
 			rxrpc_put_call(call);
 
@@ -384,6 +391,8 @@
 			spin_lock(&kafscmd_attention_lock);
 		}
 		spin_unlock(&kafscmd_attention_lock);
+
+		afs_kafstimod_del_timer(&afs_mntpt_expiry_timer);
 	}
 
 	up_write(&afscm_sem);
@@ -498,7 +507,7 @@
 	if (ret<0)
 		rxrpc_call_abort(call,ret);
 
-	if (server) afs_put_server(server);
+	afs_put_server(server);
 
 	_leave(" = %d",ret);
 
@@ -564,7 +573,7 @@
 	if (ret<0)
 		rxrpc_call_abort(call,ret);
 
-	if (server) afs_put_server(server);
+	afs_put_server(server);
 
 	_leave(" = %d",ret);
 
@@ -630,7 +639,7 @@
 	if (ret<0)
 		rxrpc_call_abort(call,ret);
 
-	if (server) afs_put_server(server);
+	afs_put_server(server);
 
 	_leave(" = %d",ret);
 

Index: cell.h
===================================================================
RCS file: /home/cvs/afs/fs/afs/cell.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- cell.h	6 Jun 2003 08:33:37 -0000	1.4
+++ cell.h	4 Jul 2003 15:26:31 -0000	1.5
@@ -25,7 +25,7 @@
 struct afs_cache_cell
 {
 	char			name[64];	/* cell name (padded with NULs) */
-	struct in_addr		servers[15];	/* cached cell servers */
+	struct in_addr		vl_servers[15];	/* cached cell VL servers */
 };
 
 /*****************************************************************************/
@@ -60,15 +60,15 @@
 
 extern int afs_cell_init(void);
 
-extern int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell);
+extern int afs_cell_create(const char *name, char *vllist, struct afs_cell **_cell);
 
-extern int afs_cell_lookup(const char *name, afs_cell_t **_cell);
+extern int afs_cell_lookup(const char *name, unsigned nmsize, struct afs_cell **_cell);
 
 #define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)
 
-extern afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell);
+extern struct afs_cell *afs_get_cell_maybe(struct afs_cell **_cell);
 
-extern void afs_put_cell(afs_cell_t *cell);
+extern void afs_put_cell(struct afs_cell *cell);
 
 extern void afs_cell_purge(void);
 

Index: cell.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/cell.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- cell.c	9 Jun 2003 13:52:04 -0000	1.8
+++ cell.c	4 Jul 2003 15:26:31 -0000	1.9
@@ -182,36 +182,45 @@
 /*
  * lookup a cell record
  */
-int afs_cell_lookup(const char *name, afs_cell_t **_cell)
+int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell)
 {
 	struct list_head *_p;
 	afs_cell_t *cell;
+	int ret;
 
-	_enter("\"%s\",",name?name:"*thiscell*");
+	_enter("\"%*.*s\",", namesz, namesz, name ? name : "");
 
-	cell = afs_cell_root;
+	*_cell = NULL;
 
 	if (name) {
 		/* if the cell was named, look for it in the cell record list */
+		ret = -ENOENT;
 		cell = NULL;
 		read_lock(&afs_cells_lock);
 
 		list_for_each(_p,&afs_cells) {
-			cell = list_entry(_p,afs_cell_t,link);
-			if (strcmp(cell->name,name)==0)
+			cell = list_entry(_p, struct afs_cell, link);
+			if (strncmp(cell->name, name, namesz) == 0) {
+				afs_get_cell(cell);
 				break;
+			}
 			cell = NULL;
 		}
 
 		read_unlock(&afs_cells_lock);
-	}
 
-	if (cell)
+		if (cell)
+			ret = 0;
+	}
+	else {
+		cell = afs_cell_root;
 		afs_get_cell(cell);
+		ret = 0;
+	}
 
 	*_cell = cell;
-	_leave(" = %d (%p)",cell?0:-ENOENT,cell);
-	return cell ? 0 : -ENOENT;
+	_leave(" = %d (%p)", ret, cell);
+	return ret;
 
 } /* end afs_cell_lookup() */
 
@@ -227,7 +236,7 @@
 
 	cell = *_cell;
 	if (cell && !list_empty(&cell->link))
-		atomic_inc(&cell->usage);
+		afs_get_cell(cell);
 	else
 		cell = NULL;
 
@@ -242,6 +251,9 @@
  */
 void afs_put_cell(afs_cell_t *cell)
 {
+	if (!cell)
+		return;
+
 	_enter("%p{%d,%s}",cell,atomic_read(&cell->usage),cell->name);
 
 	/* sanity check */
@@ -395,8 +407,7 @@
 
 	_enter("");
 
-	if (afs_cell_root)
-		afs_put_cell(afs_cell_root);
+	afs_put_cell(afs_cell_root);
 
 	while (!list_empty(&afs_cells)) {
 		cell = NULL;
@@ -480,7 +491,7 @@
 
 	_enter("");
 
-	if (strncmp(ccell->name,cell->name,sizeof(ccell->name))==0)
+	if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0)
 		return CACHEFS_MATCH_SUCCESS;
 
 	return CACHEFS_MATCH_FAILED;
@@ -495,8 +506,12 @@
 	struct afs_cache_cell *ccell = entry;
 	struct afs_cell *cell = source;
 
-	kenter("%p,%p",source,entry);
+	kenter("%p,%p", source, entry);
+
+	strncpy(ccell->name, cell->name, sizeof(ccell->name));
 
-	strncpy(ccell->name,cell->name,sizeof(ccell->name));
+	memcpy(ccell->vl_servers,
+	       cell->vl_addrs,
+	       min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs)));
 
 } /* end afs_cell_cache_update() */

Index: callback.c
===================================================================
RCS file: /home/cvs/afs/fs/afs/callback.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- callback.c	8 Oct 2002 09:06:33 -0000	1.3
+++ callback.c	4 Jul 2003 15:26:31 -0000	1.4
@@ -68,7 +68,7 @@
 			spin_unlock(&vnode->lock);
 
 			iput(inode);
-			if (release) afs_put_server(server);
+			afs_put_server(server);
 
 			spin_lock(&server->cb_lock);
 		}

Index: Makefile
===================================================================
RCS file: /home/cvs/afs/fs/afs/Makefile,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Makefile	4 Feb 2003 16:12:05 -0000	1.11
+++ Makefile	4 Jul 2003 15:26:31 -0000	1.12
@@ -2,6 +2,8 @@
 # Makefile for Red Hat Linux AFS client.
 #
 
+CFLAGS += -finstrument-functions
+
 kafs-objs := \
 	callback.o \
 	cell.o \




More information about the linux-afs-cvs mailing list