Index: openafs/src/afs/afs_analyze.c
diff -c openafs/src/afs/afs_analyze.c:1.22.14.6 openafs/src/afs/afs_analyze.c:1.22.14.6.2.1
*** openafs/src/afs/afs_analyze.c:1.22.14.6	Wed Apr 30 15:08:04 2008
--- openafs/src/afs/afs_analyze.c	Fri May 23 10:25:34 2008
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_analyze.c,v 1.22.14.6 2008/04/30 19:08:04 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_analyze.c,v 1.22.14.6.2.1 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 318,323 ****
--- 318,337 ----
      struct afs_stats_RPCErrors *aerrP;
      afs_int32 markeddown;
  
+  
+     if (AFS_IS_DISCONNECTED) {
+ 	/* SXW - This may get very tired after a while. We should try and
+ 	 *       intercept all RPCs before they get here ... */
+ 	/*printf("afs_Analyze: disconnected\n");*/
+ 	afs_FinalizeReq(areq);
+ 	if (aconn) {
+ 	    /* SXW - I suspect that this will _never_ happen - we shouldn't
+ 	     *       get a connection because we're disconnected !!!*/
+ 	    afs_PutConn(aconn, locktype);
+ 	}
+ 	return 0;
+     }
+   
      AFS_STATCNT(afs_Analyze);
      afs_Trace4(afs_iclSetp, CM_TRACE_ANALYZE, ICL_TYPE_INT32, op,
  	       ICL_TYPE_POINTER, aconn, ICL_TYPE_INT32, acode, ICL_TYPE_LONG,
Index: openafs/src/afs/afs_conn.c
diff -c openafs/src/afs/afs_conn.c:1.14.8.2 openafs/src/afs/afs_conn.c:1.14.8.2.2.1
*** openafs/src/afs/afs_conn.c:1.14.8.2	Wed Apr 30 15:08:04 2008
--- openafs/src/afs/afs_conn.c	Fri May 23 10:25:34 2008
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_conn.c,v 1.14.8.2 2008/04/30 19:08:04 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_conn.c,v 1.14.8.2.2.1 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 158,163 ****
--- 158,169 ----
  	ReleaseSharedLock(&afs_xconn);
  	return NULL;
      }
+     
+     if (AFS_IS_DISCONNECTED) {
+         afs_warnuser("afs_ConnBySA: disconnected\n");
+         ReleaseSharedLock(&afs_xconn);
+         return NULL;
+     }
  
      if (!tc) {
  	/* No such connection structure exists.  Create one and splice it in.
***************
*** 269,274 ****
--- 275,286 ----
      struct srvAddr *sa = 0;
  
      AFS_STATCNT(afs_ConnByHost);
+ 
+     if (AFS_IS_DISCONNECTED) {
+         afs_warnuser("afs_ConnByHost: disconnected\n");
+         return NULL;
+     }
+ 
  /* 
    1.  look for an existing connection
    2.  create a connection at an address believed to be up
Index: openafs/src/afs/afs_daemons.c
diff -c openafs/src/afs/afs_daemons.c:1.43.2.2.2.2 openafs/src/afs/afs_daemons.c:1.43.2.2.2.3
*** openafs/src/afs/afs_daemons.c:1.43.2.2.2.2	Tue May 20 18:17:32 2008
--- openafs/src/afs/afs_daemons.c	Fri May 23 10:25:34 2008
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_daemons.c,v 1.43.2.2.2.2 2008/05/20 22:17:32 shadow Exp $");
  
  #ifdef AFS_AIX51_ENV
  #define __FULL_PROTO
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_daemons.c,v 1.43.2.2.2.3 2008/05/23 14:25:34 shadow Exp $");
  
  #ifdef AFS_AIX51_ENV
  #define __FULL_PROTO
***************
*** 195,203 ****
--- 195,205 ----
  	    afs_FlushReclaimedVcaches();
  	    ReleaseWriteLock(&afs_xvcache);
  	    afs_FlushActiveVcaches(1);	/* keep flocks held & flush nfs writes */
+ #if 0
  #ifdef AFS_DISCON_ENV
  	    afs_StoreDirtyVcaches();
  #endif
+ #endif
  	    afs_CheckRXEpoch();
  	    last1MinCheck = now;
  	}
Index: openafs/src/afs/afs_dcache.c
diff -c openafs/src/afs/afs_dcache.c:1.64.4.7 openafs/src/afs/afs_dcache.c:1.64.4.7.2.1
*** openafs/src/afs/afs_dcache.c:1.64.4.7	Sat Dec  8 12:59:06 2007
--- openafs/src/afs/afs_dcache.c	Fri May 23 10:25:34 2008
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_dcache.c,v 1.64.4.7 2007/12/08 17:59:06 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_dcache.c,v 1.64.4.7.2.1 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 1292,1304 ****
  #endif
      MReleaseWriteLock(&afs_xdcache);
      /*
!      * It's treated like a callback so that when we do lookups we'll invalidate the unique bit if any
       * trytoSmush occured during the lookup call
       */
      afs_allCBs++;
  }
  
  /*
   * afs_FindDCache
   *
   * Description:
--- 1292,1358 ----
  #endif
      MReleaseWriteLock(&afs_xdcache);
      /*
!      * It's treated like a callback so that when we do lookups we'll 
!      * invalidate the unique bit if any
       * trytoSmush occured during the lookup call
       */
      afs_allCBs++;
  }
  
  /*
+  * afs_DCacheMissingChunks
+  *
+  * Description
+  * 	Given the cached info for a file, return the number of chunks that
+  * 	are not available from the dcache.
+  * 
+  * Parameters:
+  * 	avc:    Pointer to the (held) vcache entry to look in.
+  * 
+  * Returns:
+  * 	The number of chunks which are not currently cached.
+  * 
+  * Environment:
+  * 	The vcache entry is held upon entry.
+  */
+ 
+ int
+ afs_DCacheMissingChunks(struct vcache *avc)
+ {
+     int i, index;
+     afs_size_t totalLength;
+     afs_uint32 totalChunks;
+     struct dcache *tdc;
+ 
+     totalLength = avc->m.Length;
+     if (avc->truncPos < totalLength)
+         totalLength = avc->truncPos;
+ 
+     totalChunks = AFS_CHUNK(totalLength) + 1;
+ 
+     /*printf("Should have %d chunks for %d bytes\n", totalChunks, totalLength);*/
+     
+     i = DVHash(&avc->fid);
+     MObtainWriteLock(&afs_xdcache, 1001);
+     for (index = afs_dvhashTbl[i]; index != NULLIDX; index = i) {
+         i = afs_dvnextTbl[index];
+         if (afs_indexUnique[index] == avc->fid.Fid.Unique) {
+             tdc = afs_GetDSlot(index, NULL);
+             if (!FidCmp(&tdc->f.fid, &avc->fid)) {
+ 		totalChunks--;
+             }
+             ReleaseReadLock(&tdc->tlock);
+             afs_PutDCache(tdc);
+         }
+     }
+     MReleaseWriteLock(&afs_xdcache);
+ 
+     /*printf("Missing %d chunks\n", totalChunks);*/
+ 
+     return (totalChunks);
+ }
+ 
+ /*
   * afs_FindDCache
   *
   * Description:
***************
*** 1815,1820 ****
--- 1869,1885 ----
  	 * If we didn't find the entry, we'll create one.
  	 */
  	if (index == NULLIDX) {
+ 	    /* If we're disconnected, we can't do anything */
+             if (AFS_IS_DISCONNECTED) {
+                 MReleaseWriteLock(&afs_xdcache);
+                 if (setLocks) {
+                     if (slowPass)
+ 	                ReleaseWriteLock(&avc->lock);
+ 	            else
+ 		        ReleaseReadLock(&avc->lock);
+                 }
+                 return NULL;
+             }
  	    /*
  	     * Locks held:
  	     * avc->lock(R) if setLocks
***************
*** 2059,2064 ****
--- 2124,2146 ----
  	/*
  	 * Version number mismatch.
  	 */
+         /*
+          * If we are disconnected, then we can't do much of anything
+          * because the data doesn't match the file.
+          */
+         if (AFS_IS_DISCONNECTED) {
+             ReleaseSharedLock(&tdc->lock);
+             if (setLocks) {
+                 if (slowPass)
+                     ReleaseWriteLock(&avc->lock);
+                 else
+                     ReleaseReadLock(&avc->lock);
+             }
+             /* Flush the Dcache */
+             afs_PutDCache(tdc);
+                 
+             return NULL;
+         }
  	UpgradeSToWLock(&tdc->lock, 609);
  
  	/*
Index: openafs/src/afs/afs_disconnected.c
diff -c /dev/null openafs/src/afs/afs_disconnected.c:1.2.4.2
*** /dev/null	Fri May 23 11:06:27 2008
--- openafs/src/afs/afs_disconnected.c	Fri May 23 10:25:34 2008
***************
*** 0 ****
--- 1,18 ----
+ /*
+  * This software has been released under the terms of the IBM Public
+  * License.  For details, see the LICENSE file in the top-level source
+  * directory or online at http://www.openafs.org/dl/license10.html
+  */
+  
+ #include <afsconfig.h>
+ #include "afs/param.h"
+  
+ RCSID("$Header: /cvs/openafs/src/afs/afs_disconnected.c,v 1.2.4.2 2008/05/23 14:25:34 shadow Exp $");
+  
+ #include "afs/sysincludes.h"
+ #include "afsincludes.h"
+  
+ #ifdef AFS_DISCON_ENV
+ 
+ /* Nothing here any more. Remove from the build unless stuff comes back! */
+ #endif
Index: openafs/src/afs/afs_init.c
diff -c openafs/src/afs/afs_init.c:1.37.4.5 openafs/src/afs/afs_init.c:1.37.4.5.2.1
*** openafs/src/afs/afs_init.c:1.37.4.5	Wed Oct 10 13:40:30 2007
--- openafs/src/afs/afs_init.c	Fri May 23 10:25:34 2008
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_init.c,v 1.37.4.5 2007/10/10 17:40:30 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_init.c,v 1.37.4.5.2.1 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 45,50 ****
--- 45,53 ----
  #if defined(AFS_XBSD_ENV)
  static struct vnode *volumeVnode;
  #endif
+ #if defined(AFS_DISCON_ENV)
+ afs_rwlock_t afs_discon_lock;
+ #endif
  
  /*
   * Initialization order is important.  Must first call afs_CacheInit,
***************
*** 110,115 ****
--- 113,121 ----
  
      LOCK_INIT(&afs_ftf, "afs_ftf");
      RWLOCK_INIT(&afs_xaxs, "afs_xaxs");
+ #ifdef AFS_DISCON_ENV
+     RWLOCK_INIT(&afs_discon_lock, "afs_discon_lock");
+ #endif
      osi_dnlc_init();
  
      /* 
Index: openafs/src/afs/afs_pioctl.c
diff -c openafs/src/afs/afs_pioctl.c:1.110.2.15.2.2 openafs/src/afs/afs_pioctl.c:1.110.2.15.2.3
*** openafs/src/afs/afs_pioctl.c:1.110.2.15.2.2	Wed May 21 00:22:43 2008
--- openafs/src/afs/afs_pioctl.c	Fri May 23 10:25:34 2008
***************
*** 11,17 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.110.2.15.2.2 2008/05/21 04:22:43 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifdef AFS_OBSD_ENV
--- 11,17 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.110.2.15.2.3 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #ifdef AFS_OBSD_ENV
***************
*** 30,35 ****
--- 30,40 ----
  short afs_waitForeverCount = 0;
  afs_int32 afs_showflags = GAGUSER | GAGCONSOLE;	/* show all messages */
  
+ #ifdef AFS_DISCON_ENV
+ afs_int32 afs_is_disconnected;
+ afs_int32 afs_is_logging;
+ #endif
+ 
  #define DECL_PIOCTL(x) static int x(struct vcache *avc, int afun, struct vrequest *areq, \
  	char *ain, char *aout, afs_int32 ainSize, afs_int32 *aoutSize, \
  	struct AFS_UCRED **acred)
***************
*** 90,95 ****
--- 95,101 ----
  DECL_PIOCTL(PPrefetchFromTape);
  DECL_PIOCTL(PResidencyCmd);
  DECL_PIOCTL(PCallBackAddr);
+ DECL_PIOCTL(PDiscon);
  DECL_PIOCTL(PNFSNukeCreds);
  DECL_PIOCTL(PNewUuid);
  DECL_PIOCTL(PPrecache); 
***************
*** 196,202 ****
  	PListAliases,		/* 2 -- list cell aliases */
  	PCallBackAddr,		/* 3 -- request addr for callback rxcon */
      PBogus,			/* 4 */
!     PBogus,			/* 5 */
      PBogus,			/* 6 */
      PBogus,			/* 7 */
      PBogus,			/* 8 */
--- 202,208 ----
  	PListAliases,		/* 2 -- list cell aliases */
  	PCallBackAddr,		/* 3 -- request addr for callback rxcon */
      PBogus,			/* 4 */
!     PDiscon,			/* 5 */
      PBogus,			/* 6 */
      PBogus,			/* 7 */
      PBogus,			/* 8 */
***************
*** 3967,3972 ****
--- 3973,4024 ----
      return 0;
  }
  
+ DECL_PIOCTL(PDiscon)
+ {
+ #ifdef AFS_DISCON_ENV
+     static afs_int32 mode = 4; /* Start up in 'full' */
+ 
+     if (ainSize == sizeof(afs_int32)) {
+ 
+ 	if (!afs_osi_suser(*acred))
+ 	    return EPERM;
+ 
+ 	memcpy(&mode, ain, sizeof(afs_int32));
+ 
+ 	/*
+ 	 * All of these numbers are hard coded in fs.c. If they
+ 	 * change here, they should change there and vice versa
+ 	 */
+ 	switch (mode) {
+ 	case 0: /* Disconnect, breaking all callbacks */
+ 	    if (!AFS_IS_DISCONNECTED) {
+ 		ObtainWriteLock(&afs_discon_lock, 999);
+ 		afs_DisconGiveUpCallbacks();
+ 		afs_RemoveAllConns();
+ 		afs_is_disconnected = 1;
+ 		ReleaseWriteLock(&afs_discon_lock);
+ 	    }
+ 	    break;
+ 	case 4: /* Fully connected */
+ 	    ObtainWriteLock(&afs_discon_lock, 998);
+ 	    afs_is_disconnected = 0;
+ 	    ReleaseWriteLock(&afs_discon_lock);
+ 	    break;
+ 	default:
+ 	    return EINVAL;
+ 	}
+     } else {
+ 	return EINVAL;
+     }
+ 
+     memcpy(aout, &mode, sizeof(afs_int32));
+     *aoutSize = sizeof(afs_int32);
+     return 0;
+ #else
+     return EINVAL;
+ #endif
+ }
+ 
  DECL_PIOCTL(PNFSNukeCreds)
  {
      afs_uint32 addr, code;
Index: openafs/src/afs/afs_prototypes.h
diff -c openafs/src/afs/afs_prototypes.h:1.74.2.14.2.1 openafs/src/afs/afs_prototypes.h:1.74.2.14.2.2
*** openafs/src/afs/afs_prototypes.h:1.74.2.14.2.1	Tue May 20 17:59:38 2008
--- openafs/src/afs/afs_prototypes.h	Fri May 23 10:25:34 2008
***************
*** 268,274 ****
--- 268,276 ----
  extern int afs_WriteDCache(register struct dcache *adc, int atime);
  extern int afs_wakeup(register struct vcache *avc);
  extern int afs_InitCacheFile(char *afile, ino_t ainode);
+ extern int afs_DCacheHasAllChunks(struct vcache *avc);
  
+ /* afs_disconnected.c */
  
  /* afs_dynroot.c */
  extern int afs_IsDynrootFid(struct VenusFid *fid);
***************
*** 768,774 ****
  #endif
  extern int afs_HaveCallBacksFrom(struct server *aserver);
  extern void shutdown_server(void);
! 
  
  
  /* afs_osidnlc.c */
--- 770,776 ----
  #endif
  extern int afs_HaveCallBacksFrom(struct server *aserver);
  extern void shutdown_server(void);
! extern void afs_RemoveAllConns(void);
  
  
  /* afs_osidnlc.c */
***************
*** 938,943 ****
--- 940,946 ----
  				   struct VenusFid *afid);
  extern void afs_vcacheInit(int astatSize);
  extern void shutdown_vcache(void);
+ extern void afs_DisconGiveUpCallbacks(void);
  
  
  /* VNOPS/afs_vnop_access.c */
Index: openafs/src/afs/afs_segments.c
diff -c openafs/src/afs/afs_segments.c:1.22.8.1 openafs/src/afs/afs_segments.c:1.22.8.1.2.1
*** openafs/src/afs/afs_segments.c:1.22.8.1	Tue Dec  4 16:09:49 2007
--- openafs/src/afs/afs_segments.c	Fri May 23 10:25:34 2008
***************
*** 14,20 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_segments.c,v 1.22.8.1 2007/12/04 21:09:49 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 14,20 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_segments.c,v 1.22.8.1.2.1 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 215,221 ****
  #endif
  	    osi_VM_StoreAllSegments(avc);
      }
! 
      ConvertWToSLock(&avc->lock);
  
      /*
--- 215,227 ----
  #endif
  	    osi_VM_StoreAllSegments(avc);
      }
!     if (AFS_IS_DISCONNECTED) {
!         if (!AFS_IS_LOGGING) {
!             /* This will probably make someone sad ... */
! 	    /*printf("Net down in afs_StoreSegments\n");*/
!             return ENETDOWN;
!         }
!     }
      ConvertWToSLock(&avc->lock);
  
      /*
Index: openafs/src/afs/afs_server.c
diff -c openafs/src/afs/afs_server.c:1.43.4.6 openafs/src/afs/afs_server.c:1.43.4.6.2.1
*** openafs/src/afs/afs_server.c:1.43.4.6	Wed Apr 30 15:08:04 2008
--- openafs/src/afs/afs_server.c	Fri May 23 10:25:34 2008
***************
*** 33,39 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_server.c,v 1.43.4.6 2008/04/30 19:08:04 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 33,39 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_server.c,v 1.43.4.6.2.1 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 547,552 ****
--- 547,559 ----
  
      AFS_STATCNT(afs_CheckServers);
  
+     /* 
+      * No sense in doing the server checks if we are running in disconnected
+      * mode
+      */
+     if (AFS_IS_DISCONNECTED)
+         return;
+ 
      conns = (struct conn **)0;
      rxconns = (struct rx_connection **) 0;
      conntimer = 0;
***************
*** 1845,1850 ****
--- 1852,1897 ----
      }
  }
  
+ #ifdef AFS_DISCON_ENV
+ 
+ void afs_RemoveAllConns()
+ {
+     int i;
+     struct server *ts, *nts;
+     struct srvAddr *sa;
+     struct conn *tc, *ntc;
+ 
+     ObtainReadLock(&afs_xserver);
+     ObtainWriteLock(&afs_xconn, 1001);
+     
+     /*printf("Destroying connections ... ");*/
+     for (i = 0; i < NSERVERS; i++) {
+         for (ts = afs_servers[i]; ts; ts = nts) {
+             nts = ts->next;
+             for (sa = ts->addr; sa; sa = sa->next_sa) {
+                 if (sa->conns) {
+                     tc = sa->conns;
+                     while (tc) {
+                         ntc = tc->next;
+                         AFS_GUNLOCK();
+                         rx_DestroyConnection(tc->id);
+                         AFS_GLOCK();
+                         afs_osi_Free(tc, sizeof(struct conn));
+                         tc = ntc;
+                     }
+                     sa->conns = NULL;
+                 }
+             }
+         }
+     }
+     /*printf("done\n");*/
+ 
+     ReleaseWriteLock(&afs_xconn);
+     ReleaseReadLock(&afs_xserver);
+     
+ }
+ 
+ #endif /* AFS_DISCON_ENV */
  
  void shutdown_server()
  {
Index: openafs/src/afs/afs_vcache.c
diff -c openafs/src/afs/afs_vcache.c:1.114.2.7.2.1 openafs/src/afs/afs_vcache.c:1.114.2.7.2.2
*** openafs/src/afs/afs_vcache.c:1.114.2.7.2.1	Tue May 20 15:52:29 2008
--- openafs/src/afs/afs_vcache.c	Fri May 23 10:25:34 2008
***************
*** 39,45 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_vcache.c,v 1.114.2.7.2.1 2008/05/20 19:52:29 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
--- 39,45 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_vcache.c,v 1.114.2.7.2.2 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/sysincludes.h"	/*Standard vendor system headers */
  #include "afsincludes.h"	/*AFS-based standard headers */
***************
*** 1658,1664 ****
      struct AFSFetchStatus OutDirStatus;
      XSTATS_DECLS;
      if (!name)
! 	name = "";		/* XXX */
      do {
  	tc = afs_Conn(afid, areq, SHARED_LOCK);
  	if (tc) {
--- 1658,1664 ----
      struct AFSFetchStatus OutDirStatus;
      XSTATS_DECLS;
      if (!name)
! 	name = "";		/* XXX */    
      do {
  	tc = afs_Conn(afid, areq, SHARED_LOCK);
  	if (tc) {
***************
*** 1899,1905 ****
  	    tvc->parentUnique = OutStatus.ParentUnique;
  	    code = 0;
  	} else {
! 	    code = afs_FetchStatus(tvc, afid, areq, &OutStatus);
  	    /* For the NFS translator's benefit, make sure
  	     * non-directory vnodes always have their parent FID set
  	     * correctly, even when created as a result of decoding an
--- 1899,1913 ----
  	    tvc->parentUnique = OutStatus.ParentUnique;
  	    code = 0;
  	} else {
! 	    /* If we've got here and we're disconnected, then we can go
! 	     * no further
! 	     */
! 	    if (AFS_IS_DISCONNECTED) {
! 		code = ENETDOWN;
! 		/*printf("Network is down in afs_GetCache");*/
! 	    } else
! 	        code = afs_FetchStatus(tvc, afid, areq, &OutStatus);
! 
  	    /* For the NFS translator's benefit, make sure
  	     * non-directory vnodes always have their parent FID set
  	     * correctly, even when created as a result of decoding an
***************
*** 1986,1994 ****
      nfid = *afid;
      now = osi_Time();
      origCBs = afs_allCBs;	/* if anything changes, we don't have a cb */
!     code =
! 	afs_RemoteLookup(&adp->fid, areq, aname, &nfid, &OutStatus, &CallBack,
! 			 &serverp, &tsync);
  
  #if	defined(AFS_SGI_ENV) && !defined(AFS_SGI53_ENV)
    loop2:
--- 1994,2007 ----
      nfid = *afid;
      now = osi_Time();
      origCBs = afs_allCBs;	/* if anything changes, we don't have a cb */
!     
!     if (AFS_IS_DISCONNECTED) {
! 	/*printf("Network is down in afs_LookupVcache\n");*/
!         code = ENETDOWN;
!     } else 
!         code =
! 	    afs_RemoteLookup(&adp->fid, areq, aname, &nfid, &OutStatus, 
! 	                     &CallBack, &serverp, &tsync);
  
  #if	defined(AFS_SGI_ENV) && !defined(AFS_SGI53_ENV)
    loop2:
***************
*** 3103,3105 ****
--- 3116,3147 ----
      for(i = 0; i < VCSIZE; ++i)
  	QInit(&afs_vhashTV[i]);
  }
+ 
+ #ifdef AFS_DISCON_ENV
+ void afs_DisconGiveUpCallbacks() {
+     int i;
+     struct vcache *tvc;
+     int nq=0;
+             
+     ObtainWriteLock(&afs_xvcache, 1002); /* XXX - should be a unique number */
+     
+     /* Somehow, walk the set of vcaches, with each one coming out as tvc */
+     for (i = 0; i < VCSIZE; i++) {
+         for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
+             if ((tvc->states & CRO) == 0 && tvc->callback) {
+                 /* XXX - should we check if the callback has expired here? */
+                 afs_QueueVCB(tvc);
+                 tvc->callback = NULL;
+                 tvc->states &- ~(CStatd | CUnique);
+                 nq++;
+             }
+         }
+     }
+     /*printf("%d callbacks to be discarded. queued ... ", nq);*/
+     afs_FlushVCBs(0);
+     
+     ReleaseWriteLock(&afs_xvcache);
+     /*printf("gone\n");*/
+ }
+ 
+ #endif
Index: openafs/src/afs/afs_volume.c
diff -c openafs/src/afs/afs_volume.c:1.31.2.5 openafs/src/afs/afs_volume.c:1.31.2.5.2.1
*** openafs/src/afs/afs_volume.c:1.31.2.5	Thu Jan 25 06:20:47 2007
--- openafs/src/afs/afs_volume.c	Fri May 23 10:25:34 2008
***************
*** 19,25 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_volume.c,v 1.31.2.5 2007/01/25 11:20:47 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
--- 19,25 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_volume.c,v 1.31.2.5.2.1 2008/05/23 14:25:34 shadow Exp $");
  
  #include "afs/stds.h"
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 578,583 ****
--- 578,586 ----
  
      ReleaseWriteLock(&afs_xvolume);
  
+     if (AFS_IS_DISCONNECTED)
+         return NULL;
+ 
      tv = afs_NewVolumeByName(aname, acell, agood, areq, locktype);
      return (tv);
  }
Index: openafs/src/afs/afsincludes.h
diff -c openafs/src/afs/afsincludes.h:1.9 openafs/src/afs/afsincludes.h:1.9.20.1
*** openafs/src/afs/afsincludes.h:1.9	Sun Apr  3 14:09:05 2005
--- openafs/src/afs/afsincludes.h	Fri May 23 10:25:34 2008
***************
*** 51,56 ****
--- 51,57 ----
  #include "afs/icl.h"
  #include "afs/afs_stats.h"
  #include "afs/afs_prototypes.h"
+ #include "afs/discon.h"
  #if defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
  #include "osi_machdep.h"
  #endif
Index: openafs/src/afs/discon.h
diff -c /dev/null openafs/src/afs/discon.h:1.2.4.2
*** /dev/null	Fri May 23 11:06:28 2008
--- openafs/src/afs/discon.h	Fri May 23 10:25:35 2008
***************
*** 0 ****
--- 1,22 ----
+ #ifndef _DISCON_H
+ #define _DISCON_H
+ 
+ #ifndef AFS_DISCON_ENV
+ #define AFS_IS_DISCONNECTED 0
+ #define AFS_IS_LOGGING 0
+ #define AFS_DISCON_LOCK()
+ #define AFS_DISCON_UNLOCK()
+ 
+ #else
+ 
+ extern afs_int32    afs_is_disconnected;
+ extern afs_int32    afs_is_logging;
+ extern afs_rwlock_t afs_discon_lock;
+ 
+ #define AFS_IS_DISCONNECTED (afs_is_disconnected)
+ #define AFS_IS_LOGGING (afs_is_logging)
+ #define AFS_DISCON_LOCK() ObtainReadLock(&afs_discon_lock)
+ #define AFS_DISCON_UNLOCK() ReleaseReadLock(&afs_discon_lock)
+ 
+ #endif /* AFS_DISCON_ENV */
+ #endif /* _DISCON_H */
Index: openafs/src/afs/UKERNEL/afsincludes.h
diff -c openafs/src/afs/UKERNEL/afsincludes.h:1.5 openafs/src/afs/UKERNEL/afsincludes.h:1.5.32.1
*** openafs/src/afs/UKERNEL/afsincludes.h:1.5	Tue Oct 15 23:58:24 2002
--- openafs/src/afs/UKERNEL/afsincludes.h	Fri May 23 10:25:35 2008
***************
*** 26,28 ****
--- 26,29 ----
  #include "afs/icl.h"
  #include "afs/afs_stats.h"
  #include "afs/afs_prototypes.h"
+ #include "afs/discon.h"
Index: openafs/src/afs/VNOPS/afs_vnop_access.c
diff -c openafs/src/afs/VNOPS/afs_vnop_access.c:1.11.8.5 openafs/src/afs/VNOPS/afs_vnop_access.c:1.11.8.5.2.1
*** openafs/src/afs/VNOPS/afs_vnop_access.c:1.11.8.5	Wed Apr  9 09:39:19 2008
--- openafs/src/afs/VNOPS/afs_vnop_access.c	Fri May 23 10:25:35 2008
***************
*** 23,29 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_access.c,v 1.11.8.5 2008/04/09 13:39:19 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 23,29 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_access.c,v 1.11.8.5.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 209,218 ****
--- 209,221 ----
      if ((code = afs_InitReq(&treq, acred)))
  	return code;
  
+     AFS_DISCON_LOCK();
+ 
      if (afs_fakestat_enable && avc->mvstat == 1) {
  	code = afs_TryEvalFakeStat(&avc, &fakestate, &treq);
          if (code == 0 && avc->mvstat == 1) {
  	    afs_PutFakeStat(&fakestate);
+ 	    AFS_DISCON_UNLOCK();
  	    return 0;
          }
      } else {
***************
*** 221,226 ****
--- 224,230 ----
  
      if (code) {
  	afs_PutFakeStat(&fakestate);
+ 	AFS_DISCON_UNLOCK();
  	return code;
      }
  
***************
*** 228,233 ****
--- 232,238 ----
  	code = afs_VerifyVCache(avc, &treq);
  	if (code) {
  	    afs_PutFakeStat(&fakestate);
+ 	    AFS_DISCON_UNLOCK();
  	    code = afs_CheckCode(code, &treq, 16);
  	    return code;
  	}
***************
*** 236,243 ****
--- 241,258 ----
      /* if we're looking for write access and we have a read-only file system, report it */
      if ((amode & VWRITE) && (avc->states & CRO)) {
  	afs_PutFakeStat(&fakestate);
+ 	AFS_DISCON_UNLOCK();
  	return EROFS;
      }
+     
+     /* If we're looking for write access, and we're disconnected without logging, forget it */
+     if ((amode & VWRITE) && (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING)) {
+         afs_PutFakeStat(&fakestate);
+ 	AFS_DISCON_UNLOCK();
+ 	/*printf("Network is down in afs_vnop_access\n");*/
+         return ENETDOWN;
+     }
+     
      code = 1;			/* Default from here on in is access ok. */
      if (avc->states & CForeign) {
  	/* In the dfs xlator the EXEC bit is mapped to LOOKUP */
***************
*** 316,321 ****
--- 331,339 ----
  	}
      }
      afs_PutFakeStat(&fakestate);
+ 
+     AFS_DISCON_UNLOCK();
+     
      if (code) {
  	return 0;		/* if access is ok */
      } else {
Index: openafs/src/afs/VNOPS/afs_vnop_attrs.c
diff -c openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.41.2.1 openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.41.2.1.4.1
*** openafs/src/afs/VNOPS/afs_vnop_attrs.c:1.41.2.1	Thu Nov  9 19:11:08 2006
--- openafs/src/afs/VNOPS/afs_vnop_attrs.c	Fri May 23 10:25:35 2008
***************
*** 24,30 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.41.2.1 2006/11/10 00:11:08 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 24,30 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.41.2.1.4.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 230,235 ****
--- 230,237 ----
      }
  #endif
  
+     AFS_DISCON_LOCK();
+ 
  #ifdef AFS_BOZONLOCK_ENV
      afs_BozonLock(&avc->pvnLock, avc);
  #endif
***************
*** 328,333 ****
--- 330,338 ----
  	    }
  	}
      }
+ 
+     AFS_DISCON_UNLOCK();
+ 
      if (!code)
  	return 0;
      code = afs_CheckCode(code, &treq, 14);
***************
*** 463,468 ****
--- 468,475 ----
      if ((code = afs_InitReq(&treq, acred)))
  	return code;
  
+     AFS_DISCON_LOCK();
+ 
      afs_InitFakeStat(&fakestate);
      code = afs_EvalFakeStat(&avc, &fakestate, &treq);
      if (code)
***************
*** 502,507 ****
--- 509,519 ----
  	}
      }
  
+     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
+         code = ENETDOWN;
+         goto done;
+     }
+ 
      afs_VAttrToAS(avc, attrs, &astat);	/* interpret request */
      code = 0;
  #ifdef AFS_BOZONLOCK_ENV
***************
*** 551,569 ****
  	hzero(avc->flushDV);
  	osi_FlushText(avc);	/* do this after releasing all locks */
      }
!     if (code == 0) {
! 	ObtainSharedLock(&avc->lock, 16);	/* lock entry */
! 	code = afs_WriteVCache(avc, &astat, &treq);	/* send request */
! 	ReleaseSharedLock(&avc->lock);	/* release lock */
!     }
!     if (code) {
! 	ObtainWriteLock(&afs_xcbhash, 487);
! 	afs_DequeueCallback(avc);
! 	avc->states &= ~CStatd;
! 	ReleaseWriteLock(&afs_xcbhash);
! 	if (avc->fid.Fid.Vnode & 1 || (vType(avc) == VDIR))
! 	    osi_dnlc_purgedp(avc);
! 	/* error?  erase any changes we made to vcache entry */
      }
  #if	defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
      if (AFS_NFSXLATORREQ(acred)) {
--- 563,587 ----
  	hzero(avc->flushDV);
  	osi_FlushText(avc);	/* do this after releasing all locks */
      }
!     
!     if (!AFS_IS_DISCONNECTED) {
!         if (code == 0) {
! 	    ObtainSharedLock(&avc->lock, 16);	/* lock entry */
! 	    code = afs_WriteVCache(avc, &astat, &treq);	/* send request */
! 	    ReleaseSharedLock(&avc->lock);	/* release lock */
!         }
!         if (code) {
! 	    ObtainWriteLock(&afs_xcbhash, 487);
! 	    afs_DequeueCallback(avc);
! 	    avc->states &= ~CStatd;
! 	    ReleaseWriteLock(&afs_xcbhash);
! 	    if (avc->fid.Fid.Vnode & 1 || (vType(avc) == VDIR))
! 	        osi_dnlc_purgedp(avc);
! 	    /* error?  erase any changes we made to vcache entry */
!         }
!     } else {
!         /* Must be logging - but not implemented yet ... */
!         code = ENETDOWN;
      }
  #if	defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
      if (AFS_NFSXLATORREQ(acred)) {
***************
*** 578,583 ****
--- 596,603 ----
  #endif
    done:
      afs_PutFakeStat(&fakestate);
+ 
+     AFS_DISCON_UNLOCK();
      code = afs_CheckCode(code, &treq, 15);
      return code;
  }
Index: openafs/src/afs/VNOPS/afs_vnop_create.c
diff -c openafs/src/afs/VNOPS/afs_vnop_create.c:1.23.4.3 openafs/src/afs/VNOPS/afs_vnop_create.c:1.23.4.3.2.1
*** openafs/src/afs/VNOPS/afs_vnop_create.c:1.23.4.3	Sat Dec  8 12:59:06 2007
--- openafs/src/afs/VNOPS/afs_vnop_create.c	Fri May 23 10:25:35 2008
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_create.c,v 1.23.4.3 2007/12/08 17:59:06 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_create.c,v 1.23.4.3.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 84,95 ****
  
      if (strlen(aname) > AFSNAMEMAX) {
  	code = ENAMETOOLONG;
! 	goto done;
      }
  
      if (!afs_ENameOK(aname)) {
  	code = EINVAL;
! 	goto done;
      }
      switch (attrs->va_type) {
      case VBLK:
--- 84,95 ----
  
      if (strlen(aname) > AFSNAMEMAX) {
  	code = ENAMETOOLONG;
! 	goto done3;
      }
  
      if (!afs_ENameOK(aname)) {
  	code = EINVAL;
! 	goto done3;
      }
      switch (attrs->va_type) {
      case VBLK:
***************
*** 100,109 ****
      case VFIFO:
  	/* We don't support special devices or FIFOs */
  	code = EINVAL;
! 	goto done;
      default:
  	;
      }
      code = afs_EvalFakeStat(&adp, &fakestate, &treq);
      if (code)
  	goto done;
--- 100,111 ----
      case VFIFO:
  	/* We don't support special devices or FIFOs */
  	code = EINVAL;
! 	goto done3;
      default:
  	;
      }
+     AFS_DISCON_LOCK();
+ 
      code = afs_EvalFakeStat(&adp, &fakestate, &treq);
      if (code)
  	goto done;
***************
*** 120,125 ****
--- 122,132 ----
  	goto done;
      }
  
+     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
+         code = ENETDOWN;
+         goto done;
+     }
+ 
      tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &offset, &len, 1);
      ObtainWriteLock(&adp->lock, 135);
      if (tdc)
***************
*** 252,257 ****
--- 259,269 ----
  	    goto done;
  	}
      }
+     
+     if (AFS_IS_DISCONNECTED) {
+         /* XXX - If we get here, logging must be enabled (as we bypassed the
+          * earlier check. So - do that logging thang, then return */
+     }       
  
      /* if we create the file, we don't do any access checks, since
       * that's how O_CREAT is supposed to work */
***************
*** 447,452 ****
--- 459,467 ----
      ReleaseWriteLock(&afs_xvcache);
  
    done:
+     AFS_DISCON_UNLOCK();
+ 
+   done3:
      if (volp)
  	afs_PutVolume(volp, READ_LOCK);
  
Index: openafs/src/afs/VNOPS/afs_vnop_dirops.c
diff -c openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.21.4.1 openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.21.4.1.2.1
*** openafs/src/afs/VNOPS/afs_vnop_dirops.c:1.21.4.1	Sat Dec  8 12:59:07 2007
--- openafs/src/afs/VNOPS/afs_vnop_dirops.c	Fri May 23 10:25:35 2008
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_dirops.c,v 1.21.4.1 2007/12/08 17:59:07 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_dirops.c,v 1.21.4.1.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 65,77 ****
  
      if (strlen(aname) > AFSNAMEMAX) {
  	code = ENAMETOOLONG;
! 	goto done;
      }
  
      if (!afs_ENameOK(aname)) {
  	code = EINVAL;
! 	goto done;
      }
      code = afs_EvalFakeStat(&adp, &fakestate, &treq);
      if (code)
  	goto done;
--- 65,80 ----
  
      if (strlen(aname) > AFSNAMEMAX) {
  	code = ENAMETOOLONG;
! 	goto done3;
      }
  
      if (!afs_ENameOK(aname)) {
  	code = EINVAL;
! 	goto done3;
      }
+     
+     AFS_DISCON_LOCK();
+ 
      code = afs_EvalFakeStat(&adp, &fakestate, &treq);
      if (code)
  	goto done;
***************
*** 86,91 ****
--- 89,99 ----
  	code = EROFS;
  	goto done;
      }
+    
+     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
+ 	/*printf("Network is down in afs_mkdir\n");*/
+ 	code = ENETDOWN;
+     }
  
      InStatus.Mask = AFS_SETMODTIME | AFS_SETMODE | AFS_SETGROUP;
      InStatus.ClientModTime = osi_Time();
***************
*** 156,161 ****
--- 164,171 ----
      } else
  	code = ENOENT;
    done:
+     AFS_DISCON_UNLOCK();
+   done3:
      afs_PutFakeStat(&fakestate);
      code = afs_CheckCode(code, &treq, 26);
    done2:
***************
*** 198,203 ****
--- 208,215 ----
  	goto done;
      }
  
+     AFS_DISCON_LOCK();
+ 
      code = afs_EvalFakeStat(&adp, &fakestate, &treq);
      if (code)
  	goto done;
***************
*** 214,219 ****
--- 226,236 ----
  	goto done;
      }
  
+     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
+         code = ENETDOWN;
+         goto done;
+     }
+     
      tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &offset, &len, 1);	/* test for error below */
      ObtainWriteLock(&adp->lock, 154);
      if (tdc)
***************
*** 304,309 ****
--- 321,328 ----
      code = 0;
  
    done:
+     AFS_DISCON_UNLOCK();
+   done3:
      afs_PutFakeStat(&fakestate);
      code = afs_CheckCode(code, &treq, 27);
    done2:
Index: openafs/src/afs/VNOPS/afs_vnop_flock.c
diff -c openafs/src/afs/VNOPS/afs_vnop_flock.c:1.29.2.5 openafs/src/afs/VNOPS/afs_vnop_flock.c:1.29.2.5.2.1
*** openafs/src/afs/VNOPS/afs_vnop_flock.c:1.29.2.5	Sat Mar 10 11:03:21 2007
--- openafs/src/afs/VNOPS/afs_vnop_flock.c	Fri May 23 10:25:35 2008
***************
*** 16,22 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_flock.c,v 1.29.2.5 2007/03/10 16:03:21 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 16,22 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_flock.c,v 1.29.2.5.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 219,224 ****
--- 219,227 ----
      94.04.13 add "force" parameter.  If a child explicitly unlocks a
      file, I guess we'll permit it.  however, we don't want simple,
      innocent closes by children to unlock files in the parent process.
+ 
+     If called when disconnected support is unabled, the discon_lock must
+     be held
  */
  /* clid - nonzero on sgi sunos osf1 only */
  int
***************
*** 295,314 ****
  	    avc->slocks = 0;
  	}
  	if (avc->flockCount == 0) {
! 	    do {
! 		tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
! 		if (tc) {
! 		    XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
! 		    RX_AFS_GUNLOCK();
! 		    code = RXAFS_ReleaseLock(tc->id, (struct AFSFid *)
! 					     &avc->fid.Fid, &tsync);
! 		    RX_AFS_GLOCK();
! 		    XSTATS_END_TIME;
! 		} else
  		    code = -1;
! 	    } while (afs_Analyze
! 		     (tc, code, &avc->fid, areq,
! 		      AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK, NULL));
  	}
      } else {
  	while (1) {		/* set a new lock */
--- 298,322 ----
  	    avc->slocks = 0;
  	}
  	if (avc->flockCount == 0) {
! 	    if (!AFS_IS_DISCONNECTED) {
! 	        do {
! 		    tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
! 		    if (tc) {
! 		        XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
! 		        RX_AFS_GUNLOCK();
! 		        code = RXAFS_ReleaseLock(tc->id, (struct AFSFid *)
! 					         &avc->fid.Fid, &tsync);
! 		        RX_AFS_GLOCK();
! 		        XSTATS_END_TIME;
! 		    } else
  		    code = -1;
! 	        } while (afs_Analyze
! 		         (tc, code, &avc->fid, areq,
! 		          AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK, NULL));
! 	    } else {
! 	  	/*printf("Network is dooooooowwwwwwwnnnnnnn\n");*/
! 	       code = ENETDOWN;
! 	    }
  	}
      } else {
  	while (1) {		/* set a new lock */
***************
*** 348,371 ****
  		    }
  		}
  		if (!code && avc->flockCount == 0) {
! 		    do {
! 			tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
! 			if (tc) {
! 			    XSTATS_START_TIME
! 				(AFS_STATS_FS_RPCIDX_RELEASELOCK);
! 			    RX_AFS_GUNLOCK();
! 			    code =
! 				RXAFS_ReleaseLock(tc->id,
! 						  (struct AFSFid *)&avc->fid.
! 						  Fid, &tsync);
! 			    RX_AFS_GLOCK();
! 			    XSTATS_END_TIME;
! 			} else
! 			    code = -1;
! 		    } while (afs_Analyze
! 			     (tc, code, &avc->fid, areq,
! 			      AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK,
! 			      NULL));
  		}
  	    } else if (avc->flockCount == -1 && (acom & LOCK_EX)) {
  		if (lockIdcmp2(&flock, avc, NULL, 1, clid)) {
--- 356,381 ----
  		    }
  		}
  		if (!code && avc->flockCount == 0) {
! 		    if (!AFS_IS_DISCONNECTED) {
! 		        do {
! 			    tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
! 			    if (tc) {
! 			        XSTATS_START_TIME
! 				    (AFS_STATS_FS_RPCIDX_RELEASELOCK);
! 			        RX_AFS_GUNLOCK();
! 			        code =
! 				    RXAFS_ReleaseLock(tc->id,
! 						      (struct AFSFid *)&avc->
! 						      fid.Fid, &tsync);
! 			        RX_AFS_GLOCK();
! 			       XSTATS_END_TIME;
! 			    } else
! 			        code = -1;
! 		        } while (afs_Analyze
! 			         (tc, code, &avc->fid, areq,
! 			          AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK,
! 			          NULL));
! 		    }
  		}
  	    } else if (avc->flockCount == -1 && (acom & LOCK_EX)) {
  		if (lockIdcmp2(&flock, avc, NULL, 1, clid)) {
***************
*** 381,402 ****
  		if (avc->flockCount == 0) {
  		    /* we're the first on our block, send the call through */
  		    lockType = ((acom & LOCK_EX) ? LockWrite : LockRead);
! 		    do {
! 			tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
! 			if (tc) {
! 			    XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SETLOCK);
! 			    RX_AFS_GUNLOCK();
! 			    code = RXAFS_SetLock(tc->id, (struct AFSFid *)
! 						 &avc->fid.Fid, lockType,
! 						 &tsync);
! 			    RX_AFS_GLOCK();
! 			    XSTATS_END_TIME;
! 			} else
! 			    code = -1;
! 		    } while (afs_Analyze
! 			     (tc, code, &avc->fid, areq,
! 			      AFS_STATS_FS_RPCIDX_SETLOCK, SHARED_LOCK,
! 			      NULL));
  		} else
  		    code = 0;	/* otherwise, pretend things worked */
  	    }
--- 391,418 ----
  		if (avc->flockCount == 0) {
  		    /* we're the first on our block, send the call through */
  		    lockType = ((acom & LOCK_EX) ? LockWrite : LockRead);
! 		    if (!AFS_IS_DISCONNECTED) {
! 		        do {
! 			    tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
! 			    if (tc) {
! 			        XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SETLOCK);
! 			        RX_AFS_GUNLOCK();
! 			        code = RXAFS_SetLock(tc->id, (struct AFSFid *)
! 						     &avc->fid.Fid, lockType,
! 						     &tsync);
! 			        RX_AFS_GLOCK();
! 			        XSTATS_END_TIME;
! 			    } else
! 			        code = -1;
! 		        } while (afs_Analyze
! 			         (tc, code, &avc->fid, areq,
! 			          AFS_STATS_FS_RPCIDX_SETLOCK, SHARED_LOCK,
! 			          NULL));
! 		    } else
! 		        /* XXX - Should probably try and log this when we're
! 		         * XXX - running with logging enabled. But it's horrid
! 		         */
! 		        code = 0; /* pretend we worked - ick!!! */
  		} else
  		    code = 0;	/* otherwise, pretend things worked */
  	    }
***************
*** 497,511 ****
      if ((code = afs_InitReq(&treq, acred)))
  	return code;
      afs_InitFakeStat(&fakestate);
      code = afs_EvalFakeStat(&avc, &fakestate, &treq);
      if (code) {
! 	afs_PutFakeStat(&fakestate);
! 	return code;
      }
  #ifdef	AFS_OSF_ENV
      if (flag & VNOFLCK) {
! 	afs_PutFakeStat(&fakestate);
! 	return 0;
      }
      if (flag & CLNFLCK) {
  	acmd = LOCK_UN;
--- 513,529 ----
      if ((code = afs_InitReq(&treq, acred)))
  	return code;
      afs_InitFakeStat(&fakestate);
+ 
+     AFS_DISCON_LOCK();
+ 
      code = afs_EvalFakeStat(&avc, &fakestate, &treq);
      if (code) {
! 	goto done;
      }
  #ifdef	AFS_OSF_ENV
      if (flag & VNOFLCK) {
! 	code = 0;
! 	goto done;
      }
      if (flag & CLNFLCK) {
  	acmd = LOCK_UN;
***************
*** 521,535 ****
      if (acmd == F_GETLK) {
  #endif
  	if (af->l_type == F_UNLCK) {
! 	    afs_PutFakeStat(&fakestate);
! 	    return 0;
  	}
  #ifndef	AFS_OSF_ENV		/* getlock is a no-op for osf (for now) */
  	code = HandleGetLock(avc, af, &treq, clid);
  #endif
  	code = afs_CheckCode(code, &treq, 2);	/* defeat buggy AIX optimz */
! 	afs_PutFakeStat(&fakestate);
! 	return code;
      } else if ((acmd == F_SETLK) || (acmd == F_SETLKW)
  #if (defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)) && !defined(AFS_SUN58_ENV)
  	       || (acmd == F_RSETLK) || (acmd == F_RSETLKW)) {
--- 539,552 ----
      if (acmd == F_GETLK) {
  #endif
  	if (af->l_type == F_UNLCK) {
! 	    code = 0;
! 	    goto done;
  	}
  #ifndef	AFS_OSF_ENV		/* getlock is a no-op for osf (for now) */
  	code = HandleGetLock(avc, af, &treq, clid);
  #endif
  	code = afs_CheckCode(code, &treq, 2);	/* defeat buggy AIX optimz */
! 	goto done;
      } else if ((acmd == F_SETLK) || (acmd == F_SETLKW)
  #if (defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)) && !defined(AFS_SUN58_ENV)
  	       || (acmd == F_RSETLK) || (acmd == F_RSETLKW)) {
***************
*** 559,566 ****
       * even when they should block */
      if (af->l_whence != 0 || af->l_start != 0 || af->l_len != 0) {
  	DoLockWarning();
! 	afs_PutFakeStat(&fakestate);
! 	return 0;
      }
      /* otherwise we can turn this into a whole-file flock */
      if (af->l_type == F_RDLCK)
--- 576,583 ----
       * even when they should block */
      if (af->l_whence != 0 || af->l_start != 0 || af->l_len != 0) {
  	DoLockWarning();
! 	code = 0;
! 	goto done;
      }
      /* otherwise we can turn this into a whole-file flock */
      if (af->l_type == F_RDLCK)
***************
*** 589,599 ****
      code = HandleFlock(avc, code, &treq, 0, 0 /*!onlymine */ );
  #endif
      code = afs_CheckCode(code, &treq, 3);	/* defeat AIX -O bug */
!     afs_PutFakeStat(&fakestate);
!     return code;
      }
      afs_PutFakeStat(&fakestate);
!     return EINVAL;
  }
  
  
--- 606,618 ----
      code = HandleFlock(avc, code, &treq, 0, 0 /*!onlymine */ );
  #endif
      code = afs_CheckCode(code, &treq, 3);	/* defeat AIX -O bug */
!     goto done;
      }
+     code = EINVAL;
+ done:
      afs_PutFakeStat(&fakestate);
!     AFS_DISCON_UNLOCK();
!     return code;
  }
  
  
***************
*** 819,824 ****
--- 838,847 ----
      temp = areq->flags & O_NONBLOCK;
      areq->flags |= O_NONBLOCK;
  
+     /* If we're disconnected, lie and say that we've got no locks. Ick */
+     if (AFS_IS_DISCONNECTED)
+         return 0;
+         
      do {
  	tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
  	if (tc) {
***************
*** 889,894 ****
--- 912,920 ----
  	afs_PutFakeStat(&fakestate);
  	return flockDone;
      }
+ 
+     AFS_DISCON_LOCK();
+     
      /* first determine whether this is any sort of vnode */
      if (fd->f_type == DTYPE_VNODE) {
  	/* good, this is a vnode; next see if it is an AFS vnode */
***************
*** 897,902 ****
--- 923,929 ----
  	    /* This is an AFS vnode, so do the work */
  	    code = afs_EvalFakeStat(&tvc, &fakestate, &treq);
  	    if (code) {
+ 		AFS_DISCON_UNLOCK();
  		afs_PutFakeStat(&fakestate);
  		return code;
  	    }
***************
*** 950,955 ****
--- 977,983 ----
  #else
      FP_UNREF(fd);
  #endif
+     AFS_DISCON_UNLOCK();
      afs_PutFakeStat(&fakestate);
      return code;
  #else /* AFS_OSF_ENV */
***************
*** 959,964 ****
--- 987,993 ----
  #else
  	flock();
  #endif
+     AFS_DISCON_UNLOCK();
      afs_PutFakeStat(&fakestate);
      return;
  #endif
Index: openafs/src/afs/VNOPS/afs_vnop_link.c
diff -c openafs/src/afs/VNOPS/afs_vnop_link.c:1.19.8.1 openafs/src/afs/VNOPS/afs_vnop_link.c:1.19.8.1.2.1
*** openafs/src/afs/VNOPS/afs_vnop_link.c:1.19.8.1	Sat Dec  8 12:59:07 2007
--- openafs/src/afs/VNOPS/afs_vnop_link.c	Fri May 23 10:25:35 2008
***************
*** 17,23 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_link.c,v 1.19.8.1 2007/12/08 17:59:07 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 17,23 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_link.c,v 1.19.8.1.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 62,67 ****
--- 62,70 ----
  
      afs_InitFakeStat(&vfakestate);
      afs_InitFakeStat(&dfakestate);
+     
+     AFS_DISCON_LOCK();
+ 
      code = afs_EvalFakeStat(&avc, &vfakestate, &treq);
      if (code)
  	goto done;
***************
*** 89,94 ****
--- 92,102 ----
  	code = EROFS;
  	goto done;
      }
+     
+     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
+         code = ENETDOWN;
+         goto done;
+     }
  
      tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &offset, &len, 1);	/* test for error below */
      ObtainWriteLock(&adp->lock, 145);
***************
*** 161,166 ****
--- 169,175 ----
      code = afs_CheckCode(code, &treq, 24);
      afs_PutFakeStat(&vfakestate);
      afs_PutFakeStat(&dfakestate);
+     AFS_DISCON_UNLOCK();
    done2:
      return code;
  }
Index: openafs/src/afs/VNOPS/afs_vnop_lookup.c
diff -c openafs/src/afs/VNOPS/afs_vnop_lookup.c:1.72.2.6 openafs/src/afs/VNOPS/afs_vnop_lookup.c:1.72.2.6.2.1
*** openafs/src/afs/VNOPS/afs_vnop_lookup.c:1.72.2.6	Tue Apr 15 08:29:39 2008
--- openafs/src/afs/VNOPS/afs_vnop_lookup.c	Fri May 23 10:25:35 2008
***************
*** 18,24 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.72.2.6 2008/04/15 12:29:39 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 18,24 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.72.2.6.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 87,96 ****
  	volnamep = data;
  	tcell = afs_GetCell(cellnum, READ_LOCK);
      } else {
  	return ENODEV;
      }
!     if (!tcell)
  	return ENODEV;
  
      cellidx = tcell->cellIndex;
      mtptCell = tcell->cellNum;	/* The cell for the mountpoint */
--- 87,100 ----
  	volnamep = data;
  	tcell = afs_GetCell(cellnum, READ_LOCK);
      } else {
+ 	/*printf("No cellname %s , or cellnum %d , returning ENODEV\n", 
+ 	       data, cellnum);*/
  	return ENODEV;
      }
!     if (!tcell) {
! 	/*printf("Lookup failed, returning ENODEV\n");*/
  	return ENODEV;
+     }
  
      cellidx = tcell->cellIndex;
      mtptCell = tcell->cellNum;	/* The cell for the mountpoint */
***************
*** 143,150 ****
  	tfid.Fid.Volume = volid;	/* remember BK volume */
  	tfid.Cell = mtptCell;
  	tvp = afs_GetVolume(&tfid, areq, WRITE_LOCK);	/* get the new one */
! 	if (!tvp)
  	    return ENODEV;	/* oops, can't do it */
  	goto done;
      }
  
--- 147,156 ----
  	tfid.Fid.Volume = volid;	/* remember BK volume */
  	tfid.Cell = mtptCell;
  	tvp = afs_GetVolume(&tfid, areq, WRITE_LOCK);	/* get the new one */
! 	if (!tvp) {
! 	    /*printf("afs_GetVolume failed - returning ENODEV");*/
  	    return ENODEV;	/* oops, can't do it */
+ 	}
  	goto done;
      }
  
***************
*** 179,184 ****
--- 185,191 ----
       * ".backup" in it, this will get the volume struct for the RW volume.
       * The RO volume will be prefetched if requested (but not returned).
       */
+     /*printf("Calling GetVolumeByName\n");*/
      tvp = afs_GetVolumeByName(volnamep, mtptCell, prefetch, areq, WRITE_LOCK);
  
      /* If no volume was found in this cell, try the associated linked cell */
***************
*** 207,214 ****
  	osi_FreeSmallSpace(buf);
      }
  
!     if (!tvp)
  	return ENODEV;		/* Couldn't find the volume */
  
      /* Don't cross mountpoint from a BK to a BK volume */
      if ((states & CBackup) && (tvp->states & VBackup)) {
--- 214,223 ----
  	osi_FreeSmallSpace(buf);
      }
  
!     if (!tvp) {
! 	/*printf("Couldn't find the volume\n");*/
  	return ENODEV;		/* Couldn't find the volume */
+     }
  
      /* Don't cross mountpoint from a BK to a BK volume */
      if ((states & CBackup) && (tvp->states & VBackup)) {
***************
*** 1222,1227 ****
--- 1231,1240 ----
      AFS_STATCNT(afs_lookup);
      afs_InitFakeStat(&fakestate);
  
+     AFS_DISCON_LOCK();
+ 
+     /*printf("Looking up %s\n", aname);*/
+     
      if ((code = afs_InitReq(&treq, acred)))
  	goto done;
  
***************
*** 1250,1255 ****
--- 1263,1271 ----
  	code = afs_TryEvalFakeStat(&adp, &fakestate, &treq);
      else
  	code = afs_EvalFakeStat(&adp, &fakestate, &treq);
+ 
+     /*printf("Code is %d\n", code);*/
+     
      if (tryEvalOnly && adp->mvstat == 1)
  	code = ENOENT;
      if (code)
***************
*** 1291,1296 ****
--- 1307,1313 ----
  	    goto done;
  	}
  	/* otherwise we have the fid here, so we use it */
+ 	/*printf("Getting vcache\n");*/
  	tvc = afs_GetVCache(adp->mvid, &treq, NULL, NULL);
  	afs_Trace3(afs_iclSetp, CM_TRACE_GETVCDOTDOT, ICL_TYPE_FID, adp->mvid,
  		   ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32, code);
***************
*** 1550,1556 ****
  	/* prefetch some entries, if the dir is currently open.  The variable
  	 * dirCookie tells us where to start prefetching from.
  	 */
! 	if (AFSDOBULK && adp->opens > 0 && !(adp->states & CForeign)
  	    && !afs_IsDynroot(adp) && !afs_InReadDir(adp)) {
  	    afs_int32 retry;
  	    /* if the entry is not in the cache, or is in the cache,
--- 1567,1574 ----
  	/* prefetch some entries, if the dir is currently open.  The variable
  	 * dirCookie tells us where to start prefetching from.
  	 */
! 	if (!AFS_IS_DISCONNECTED && 
! 	    AFSDOBULK && adp->opens > 0 && !(adp->states & CForeign)
  	    && !afs_IsDynroot(adp) && !afs_InReadDir(adp)) {
  	    afs_int32 retry;
  	    /* if the entry is not in the cache, or is in the cache,
***************
*** 1697,1721 ****
  	 * be located (a Multics "connection failure").  If the volume is
  	 * read-only, we try flushing this entry from the cache and trying
  	 * again. */
! 	if (pass == 0) {
! 	    struct volume *tv;
! 	    tv = afs_GetVolume(&adp->fid, &treq, READ_LOCK);
! 	    if (tv) {
! 		if (tv->states & VRO) {
! 		    pass = 1;	/* try this *once* */
! 		    ObtainWriteLock(&afs_xcbhash, 495);
! 		    afs_DequeueCallback(adp);
! 		    /* re-stat to get later version */
! 		    adp->states &= ~CStatd;
! 		    ReleaseWriteLock(&afs_xcbhash);
! 		    osi_dnlc_purgedp(adp);
  		    afs_PutVolume(tv, READ_LOCK);
! 		    goto redo;
! 		}
! 		afs_PutVolume(tv, READ_LOCK);
  	    }
  	}
- 	code = ENOENT;
      }
  
    done:
--- 1715,1744 ----
  	 * be located (a Multics "connection failure").  If the volume is
  	 * read-only, we try flushing this entry from the cache and trying
  	 * again. */
! 	if (!AFS_IS_DISCONNECTED) {
! 	    if (pass == 0) {
! 	        struct volume *tv;
! 	        tv = afs_GetVolume(&adp->fid, &treq, READ_LOCK);
! 	        if (tv) {
! 		    if (tv->states & VRO) {
! 		        pass = 1;	/* try this *once* */
! 		        ObtainWriteLock(&afs_xcbhash, 495);
! 		        afs_DequeueCallback(adp);
! 		        /* re-stat to get later version */
! 		        adp->states &= ~CStatd;
! 		        ReleaseWriteLock(&afs_xcbhash);
! 		        osi_dnlc_purgedp(adp);
! 		        afs_PutVolume(tv, READ_LOCK);
! 		        goto redo;
! 		    }
  		    afs_PutVolume(tv, READ_LOCK);
! 	        }
  	    }
+ 	    code = ENOENT;
+ 	} else {
+ 	    /*printf("Network down in afs_lookup\n");*/
+ 	    code = ENETDOWN;
  	}
      }
  
    done:
***************
*** 1753,1758 ****
--- 1776,1782 ----
  		code = afs_VerifyVCache(tvc, &treq);
  #else
  		afs_PutFakeStat(&fakestate);
+ 		AFS_DISCON_UNLOCK();
  		return 0;	/* can't have been any errors if hit and !code */
  #endif
  	    }
***************
*** 1769,1773 ****
--- 1793,1798 ----
      }
  
      afs_PutFakeStat(&fakestate);
+     AFS_DISCON_UNLOCK();
      return code;
  }
Index: openafs/src/afs/VNOPS/afs_vnop_open.c
diff -c openafs/src/afs/VNOPS/afs_vnop_open.c:1.11.20.1 openafs/src/afs/VNOPS/afs_vnop_open.c:1.11.20.2
*** openafs/src/afs/VNOPS/afs_vnop_open.c:1.11.20.1	Tue May 20 17:59:40 2008
--- openafs/src/afs/VNOPS/afs_vnop_open.c	Fri May 23 10:25:35 2008
***************
*** 18,24 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_open.c,v 1.11.20.1 2008/05/20 21:59:40 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 18,24 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_open.c,v 1.11.20.2 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 59,70 ****
--- 59,87 ----
      afs_Trace2(afs_iclSetp, CM_TRACE_OPEN, ICL_TYPE_POINTER, tvc,
  	       ICL_TYPE_INT32, aflags);
      afs_InitFakeStat(&fakestate);
+ 
+     AFS_DISCON_LOCK();
+ 
      code = afs_EvalFakeStat(&tvc, &fakestate, &treq);
      if (code)
  	goto done;
      code = afs_VerifyVCache(tvc, &treq);
      if (code)
  	goto done;
+ 
+     ObtainReadLock(&tvc->lock);
+ 
+ #ifdef AFS_DISCON_ENV
+     if (AFS_IS_DISCONNECTED && (afs_DCacheMissingChunks(tvc) != 0)) {
+        ReleaseReadLock(&tvc->lock);
+        /*printf("Network is down in afs_open: missing chunks\n");*/
+        code = ENETDOWN;
+        goto done;
+     }
+ #endif
+ 
+     ReleaseReadLock(&tvc->lock);
+ 
      if (aflags & (FWRITE | FTRUNC))
  	writing = 1;
      else
***************
*** 181,186 ****
--- 198,205 ----
      }	
    done:
      afs_PutFakeStat(&fakestate);
+     AFS_DISCON_UNLOCK();
+ 
      code = afs_CheckCode(code, &treq, 4);	/* avoid AIX -O bug */
  
      afs_Trace2(afs_iclSetp, CM_TRACE_OPEN, ICL_TYPE_POINTER, tvc,
Index: openafs/src/afs/VNOPS/afs_vnop_read.c
diff -c openafs/src/afs/VNOPS/afs_vnop_read.c:1.34.2.2.2.1 openafs/src/afs/VNOPS/afs_vnop_read.c:1.34.2.2.2.2
*** openafs/src/afs/VNOPS/afs_vnop_read.c:1.34.2.2.2.1	Tue May 20 17:59:40 2008
--- openafs/src/afs/VNOPS/afs_vnop_read.c	Fri May 23 10:25:35 2008
***************
*** 19,25 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_read.c,v 1.34.2.2.2.1 2008/05/20 21:59:40 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 19,25 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_read.c,v 1.34.2.2.2.2 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 443,448 ****
--- 443,457 ----
  	ReleaseReadLock(&adc->lock);
  
  	tdc = afs_GetDCache(avc, offset, areq, &j1, &j2, 2);	/* type 2 never returns 0 */
+ #ifdef AFS_DISCON_ENV
+         /*
+          * In disconnected mode, type 2 can return 0 because it doesn't
+          * make any sense to allocate a dcache we can never fill
+          */
+          if (tdc == NULL)
+              return;
+ #endif /* AFS_DISCON_ENV */
+ 
  	ObtainSharedLock(&tdc->mflock, 651);
  	if (!(tdc->mflags & DFFetchReq)) {
  	    /* ask the daemon to do the work */
***************
*** 512,517 ****
--- 521,528 ----
      if (avc && avc->vc_error)
  	return EIO;
  
+     AFS_DISCON_LOCK();
+     
      /* check that we have the latest status info in the vnode cache */
      if ((code = afs_InitReq(&treq, acred)))
  	return code;
***************
*** 522,527 ****
--- 533,539 ----
  	    code = afs_VerifyVCache(avc, &treq);
  	    if (code) {
  		code = afs_CheckCode(code, &treq, 11);	/* failed to get it */
+ 		AFS_DISCON_UNLOCK();
  		return code;
  	    }
  	}
***************
*** 531,536 ****
--- 543,549 ----
  	if (!afs_AccessOK
  	    (avc, PRSFS_READ, &treq,
  	     CHECK_MODE_BITS | CMB_ALLOW_EXEC_AS_READ)) {
+ 	    AFS_DISCON_UNLOCK();
  	    return afs_CheckCode(EACCES, &treq, 12);
  	}
      }
***************
*** 621,626 ****
--- 634,647 ----
  		afs_PutDCache(tdc);	/* before reusing tdc */
  	    }
  	    tdc = afs_GetDCache(avc, filePos, &treq, &offset, &len, 2);
+ #ifdef AFS_DISCON_ENV
+ 	    if (!tdc) {
+ 		/*printf("Network down in afs_read");*/
+ 	        error = ENETDOWN;
+ 	        break;
+ 	    }
+ #endif /* AFS_DISCON_ENV */
+ 
  	    ObtainReadLock(&tdc->lock);
  	    /* now, first try to start transfer, if we'll need the data.  If
  	     * data already coming, we don't need to do this, obviously.  Type
***************
*** 952,957 ****
--- 973,979 ----
  #else
      osi_FreeSmallSpace(tvec);
  #endif
+     AFS_DISCON_UNLOCK();
      error = afs_CheckCode(error, &treq, 13);
      return error;
  }
Index: openafs/src/afs/VNOPS/afs_vnop_readdir.c
diff -c openafs/src/afs/VNOPS/afs_vnop_readdir.c:1.33 openafs/src/afs/VNOPS/afs_vnop_readdir.c:1.33.18.1
*** openafs/src/afs/VNOPS/afs_vnop_readdir.c:1.33	Fri Nov 18 23:33:00 2005
--- openafs/src/afs/VNOPS/afs_vnop_readdir.c	Fri May 23 10:25:35 2008
***************
*** 23,29 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_readdir.c,v 1.33 2005/11/19 04:33:00 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 23,29 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_readdir.c,v 1.33.18.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 648,653 ****
--- 648,656 ----
      }
      /* update the cache entry */
      afs_InitFakeStat(&fakestate);
+ 
+     AFS_DISCON_LOCK();
+ 
      code = afs_EvalFakeStat(&avc, &fakestate, &treq);
      if (code)
  	goto done;
***************
*** 910,915 ****
--- 913,919 ----
  #ifdef	AFS_HPUX_ENV
      osi_FreeSmallSpace((char *)sdirEntry);
  #endif
+     AFS_DISCON_UNLOCK();
      afs_PutFakeStat(&fakestate);
      code = afs_CheckCode(code, &treq, 28);
      return code;
***************
*** 957,967 ****
--- 961,973 ----
  	return code;
      }
      afs_InitFakeStat(&fakestate);
+     AFS_DISCON_LOCK();
      code = afs_EvalFakeStat(&avc, &fakestate, &treq);
      if (code) {
  #ifdef	AFS_HPUX_ENV
  	osi_FreeSmallSpace((char *)sdirEntry);
  #endif
+ 	AFS_DISCON_UNLOCK();
  	afs_PutFakeStat(&fakestate);
  	return code;
      }
***************
*** 1177,1182 ****
--- 1183,1189 ----
  #if	defined(AFS_HPUX_ENV) || defined(AFS_OSF_ENV)
      osi_FreeSmallSpace((char *)sdirEntry);
  #endif
+     AFS_DISCON_UNLOCK();
      afs_PutFakeStat(&fakestate);
      code = afs_CheckCode(code, &treq, 29);
      return code;
Index: openafs/src/afs/VNOPS/afs_vnop_remove.c
diff -c openafs/src/afs/VNOPS/afs_vnop_remove.c:1.52.2.4 openafs/src/afs/VNOPS/afs_vnop_remove.c:1.52.2.4.2.1
*** openafs/src/afs/VNOPS/afs_vnop_remove.c:1.52.2.4	Wed Dec 19 15:57:55 2007
--- openafs/src/afs/VNOPS/afs_vnop_remove.c	Fri May 23 10:25:35 2008
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.52.2.4 2007/12/19 20:57:55 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.52.2.4.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 104,129 ****
  	  register struct vcache *tvc, char *aname, struct AFS_UCRED *acred,
  	  struct vrequest *treqp)
  {
!     register afs_int32 code;
      register struct conn *tc;
      struct AFSFetchStatus OutDirStatus;
      struct AFSVolSync tsync;
      XSTATS_DECLS;
!     do {
! 	tc = afs_Conn(&adp->fid, treqp, SHARED_LOCK);
! 	if (tc) {
! 	    XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_REMOVEFILE);
! 	    RX_AFS_GUNLOCK();
! 	    code =
! 		RXAFS_RemoveFile(tc->id, (struct AFSFid *)&adp->fid.Fid,
! 				 aname, &OutDirStatus, &tsync);
! 	    RX_AFS_GLOCK();
! 	    XSTATS_END_TIME;
! 	} else
! 	    code = -1;
!     } while (afs_Analyze
! 	     (tc, code, &adp->fid, treqp, AFS_STATS_FS_RPCIDX_REMOVEFILE,
! 	      SHARED_LOCK, NULL));
  
      osi_dnlc_remove(adp, aname, tvc);
  
--- 104,132 ----
  	  register struct vcache *tvc, char *aname, struct AFS_UCRED *acred,
  	  struct vrequest *treqp)
  {
!     register afs_int32 code = 0;
      register struct conn *tc;
      struct AFSFetchStatus OutDirStatus;
      struct AFSVolSync tsync;
      XSTATS_DECLS;
!     
!     if (!AFS_IS_DISCONNECTED) {
!         do {
! 	    tc = afs_Conn(&adp->fid, treqp, SHARED_LOCK);
! 	    if (tc) {
! 	        XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_REMOVEFILE);
! 	        RX_AFS_GUNLOCK();
! 	        code =
! 		    RXAFS_RemoveFile(tc->id, (struct AFSFid *)&adp->fid.Fid,
! 		  		     aname, &OutDirStatus, &tsync);
! 	        RX_AFS_GLOCK();
! 	        XSTATS_END_TIME;
! 	    } else
! 	        code = -1;
!         } while (afs_Analyze
! 	         (tc, code, &adp->fid, treqp, AFS_STATS_FS_RPCIDX_REMOVEFILE,
! 	          SHARED_LOCK, NULL));
!     }
  
      osi_dnlc_remove(adp, aname, tvc);
  
***************
*** 304,309 ****
--- 307,322 ----
  	return code;
      }
  
+     /* If we're running disconnected without logging, go no further... */
+     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
+ #ifdef  AFS_OSF_ENV
+         afs_PutVCache(tvc);
+ #endif
+         code = ENETDOWN;
+         afs_PutFakeStat(&fakestate);
+         return code;
+     }
+     
      tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &offset, &len, 1);	/* test for error below */
      ObtainWriteLock(&adp->lock, 142);
      if (tdc)
Index: openafs/src/afs/VNOPS/afs_vnop_rename.c
diff -c openafs/src/afs/VNOPS/afs_vnop_rename.c:1.28.4.1 openafs/src/afs/VNOPS/afs_vnop_rename.c:1.28.4.1.2.1
*** openafs/src/afs/VNOPS/afs_vnop_rename.c:1.28.4.1	Sat Dec  8 12:59:07 2007
--- openafs/src/afs/VNOPS/afs_vnop_rename.c	Fri May 23 10:25:35 2008
***************
*** 18,24 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_rename.c,v 1.28.4.1 2007/12/08 17:59:07 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 18,24 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_rename.c,v 1.28.4.1.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 82,87 ****
--- 82,93 ----
  	    code = 0;
  	    goto done;
  	}
+ 	
+ 	if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
+ 	    code = ENETDOWN;
+ 	    goto done;
+ 	}
+ 	
  	ObtainWriteLock(&andp->lock, 147);
  	tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, areq, &offset, &len, 0);
  	if (!tdc1) {
***************
*** 161,167 ****
  	goto done;
      }
  
-     /* locks are now set, proceed to do the real work */
      do {
  	tc = afs_Conn(&aodp->fid, areq, SHARED_LOCK);
  	if (tc) {
--- 167,172 ----
***************
*** 376,381 ****
--- 381,389 ----
  	return code;
      afs_InitFakeStat(&ofakestate);
      afs_InitFakeStat(&nfakestate);
+ 
+     AFS_DISCON_LOCK();
+     
      code = afs_EvalFakeStat(&aodp, &ofakestate, &treq);
      if (code)
  	goto done;
***************
*** 386,391 ****
--- 394,402 ----
    done:
      afs_PutFakeStat(&ofakestate);
      afs_PutFakeStat(&nfakestate);
+ 
+     AFS_DISCON_UNLOCK();
+     
      code = afs_CheckCode(code, &treq, 25);
      return code;
  }
Index: openafs/src/afs/VNOPS/afs_vnop_symlink.c
diff -c openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.24.4.4 openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.24.4.4.2.1
*** openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.24.4.4	Sat Dec  8 12:59:07 2007
--- openafs/src/afs/VNOPS/afs_vnop_symlink.c	Fri May 23 10:25:35 2008
***************
*** 22,28 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_symlink.c,v 1.24.4.4 2007/12/08 17:59:07 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 22,28 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_symlink.c,v 1.24.4.4.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 76,81 ****
--- 76,84 ----
  	goto done2;
  
      afs_InitFakeStat(&fakestate);
+ 
+     AFS_DISCON_LOCK();
+     
      code = afs_EvalFakeStat(&adp, &fakestate, &treq);
      if (code)
  	goto done;
***************
*** 108,113 ****
--- 111,121 ----
  	goto done;
      }
  
+     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING) {
+         code = ENETDOWN;
+         goto done;
+     }
+     
      InStatus.Mask = AFS_SETMODTIME | AFS_SETMODE;
      InStatus.ClientModTime = osi_Time();
      alen = strlen(atargetName);	/* we want it to include the null */
***************
*** 235,240 ****
--- 243,249 ----
      afs_PutFakeStat(&fakestate);
      if (volp)
  	afs_PutVolume(volp, READ_LOCK);
+     AFS_DISCON_UNLOCK();
      code = afs_CheckCode(code, &treq, 31);
    done2:
      return code;
***************
*** 310,316 ****
  		   ICL_TYPE_POINTER, tdc, ICL_TYPE_OFFSET,
  		   ICL_HANDLE_OFFSET(avc->m.Length));
  	if (!tdc) {
! 	    return EIO;
  	}
  	/* otherwise we have the data loaded, go for it */
  	if (len > 1024) {
--- 319,328 ----
  		   ICL_TYPE_POINTER, tdc, ICL_TYPE_OFFSET,
  		   ICL_HANDLE_OFFSET(avc->m.Length));
  	if (!tdc) {
! 	    if (AFS_IS_DISCONNECTED)
! 	        return ENETDOWN;
! 	    else
! 	        return EIO;
  	}
  	/* otherwise we have the data loaded, go for it */
  	if (len > 1024) {
***************
*** 360,365 ****
--- 372,380 ----
      if ((code = afs_InitReq(&treq, acred)))
  	return code;
      afs_InitFakeStat(&fakestat);
+ 
+     AFS_DISCON_LOCK();
+     
      code = afs_EvalFakeStat(&avc, &fakestat, &treq);
      if (code)
  	goto done;
***************
*** 384,389 ****
--- 399,405 ----
      ReleaseWriteLock(&avc->lock);
    done:
      afs_PutFakeStat(&fakestat);
+     AFS_DISCON_UNLOCK();
      code = afs_CheckCode(code, &treq, 32);
      return code;
  }
Index: openafs/src/afs/VNOPS/afs_vnop_write.c
diff -c openafs/src/afs/VNOPS/afs_vnop_write.c:1.50.2.1 openafs/src/afs/VNOPS/afs_vnop_write.c:1.50.2.1.2.1
*** openafs/src/afs/VNOPS/afs_vnop_write.c:1.50.2.1	Tue Dec  4 15:40:53 2007
--- openafs/src/afs/VNOPS/afs_vnop_write.c	Fri May 23 10:25:35 2008
***************
*** 21,27 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_write.c,v 1.50.2.1 2007/12/04 20:40:53 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_write.c,v 1.50.2.1.2.1 2008/05/23 14:25:35 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 382,387 ****
--- 382,390 ----
      if (avc->vc_error)
  	return avc->vc_error;
  
+     if (AFS_IS_DISCONNECTED && !AFS_IS_LOGGING)
+ 	return ENETDOWN;
+     
      startDate = osi_Time();
      if ((code = afs_InitReq(&treq, acred)))
  	return code;
Index: openafs/src/afsd/afs.rc.darwin
diff -c openafs/src/afsd/afs.rc.darwin:1.8.2.1.2.1 openafs/src/afsd/afs.rc.darwin:1.8.2.1.2.2
*** openafs/src/afsd/afs.rc.darwin:1.8.2.1.2.1	Wed May 21 09:50:34 2008
--- openafs/src/afsd/afs.rc.darwin	Thu May 22 17:04:04 2008
***************
*** 11,16 ****
--- 11,18 ----
  # Updated to match standard service scripts
  # Phil Holland <hollandp@umich.edu> 6/11/04
  
+ PRECACHE="$AFS_PRECACHE"
+ 
  . /etc/rc.common
  
  #
***************
*** 140,146 ****
  	fs sysname $AFS_SYSNAME
      fi
  
!     if [ -n "$AFS_PRECACHE" ] ; then
  	fs precache $AFS_PRECACHE
      fi
  
--- 142,148 ----
  	fs sysname $AFS_SYSNAME
      fi
  
!     if [ ! -z "$PRECACHE" ] ; then
  	fs precache $AFS_PRECACHE
      fi
  
Index: openafs/src/config/NTMakefile.amd64_w2k
diff -c openafs/src/config/NTMakefile.amd64_w2k:1.24.2.41.2.1 openafs/src/config/NTMakefile.amd64_w2k:1.24.2.41.2.2
*** openafs/src/config/NTMakefile.amd64_w2k:1.24.2.41.2.1	Wed May 21 09:39:28 2008
--- openafs/src/config/NTMakefile.amd64_w2k	Fri May 23 10:27:32 2008
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=3700
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=3800
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/NTMakefile.i386_nt40
diff -c openafs/src/config/NTMakefile.i386_nt40:1.84.2.40.2.1 openafs/src/config/NTMakefile.i386_nt40:1.84.2.40.2.2
*** openafs/src/config/NTMakefile.i386_nt40:1.84.2.40.2.1	Wed May 21 09:39:28 2008
--- openafs/src/config/NTMakefile.i386_nt40	Fri May 23 10:27:32 2008
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=3700
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=3800
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/config/NTMakefile.i386_w2k
diff -c openafs/src/config/NTMakefile.i386_w2k:1.23.2.41.2.1 openafs/src/config/NTMakefile.i386_w2k:1.23.2.41.2.2
*** openafs/src/config/NTMakefile.i386_w2k:1.23.2.41.2.1	Wed May 21 09:39:28 2008
--- openafs/src/config/NTMakefile.i386_w2k	Fri May 23 10:27:32 2008
***************
*** 84,90 ****
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=3700
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
--- 84,90 ----
  #define used in WinNT/2000 installation and program version display
  AFSPRODUCT_VER_MAJOR=1
  AFSPRODUCT_VER_MINOR=5
! AFSPRODUCT_VER_PATCH=3800
  AFSPRODUCT_VER_BUILD=0
  
  AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH)
Index: openafs/src/libafs/Makefile.common.in
diff -c openafs/src/libafs/Makefile.common.in:1.24.2.5 openafs/src/libafs/Makefile.common.in:1.24.2.5.2.1
*** openafs/src/libafs/Makefile.common.in:1.24.2.5	Wed May 16 16:58:43 2007
--- openafs/src/libafs/Makefile.common.in	Fri May 23 10:25:35 2008
***************
*** 85,90 ****
--- 85,91 ----
  	afs_daemons.o	\
  	afs_dcache.o \
  	afs_dir.o		\
+ 	afs_disconnected.o	\
  	afs_dynroot.o		\
  	afs_error.o \
  	afs_icl.o \
***************
*** 245,250 ****
--- 246,253 ----
  	$(CRULE_OPT)
  afs_dcache.o: $(TOP_SRC_AFS)/afs_dcache.c
  	$(CRULE_OPT)
+ afs_disconnected.o: $(TOP_SRC_AFS)/afs_disconnected.c
+ 	$(CRULE_OPT)
  afs_dynroot.o: 	$(TOP_SRC_AFS)/afs_dynroot.c
  	$(CRULE_OPT)
  afs_error.o: $(TOP_SRC_AFS)/afs_error.c
Index: openafs/src/libuafs/Makefile.common.in
diff -c openafs/src/libuafs/Makefile.common.in:1.13.4.5 openafs/src/libuafs/Makefile.common.in:1.13.4.5.2.1
*** openafs/src/libuafs/Makefile.common.in:1.13.4.5	Mon Jan 21 13:38:03 2008
--- openafs/src/libuafs/Makefile.common.in	Fri May 23 10:25:36 2008
***************
*** 98,103 ****
--- 98,104 ----
  	$(UOBJ)/afs_daemons.o	\
  	$(UOBJ)/afs_dcache.o \
  	$(UOBJ)/afs_dir.o		\
+ 	$(UOBJ)/afs_disconnected.o	\
  	$(UOBJ)/afs_dynroot.o \
  	$(UOBJ)/afs_icl.o \
  	$(UOBJ)/afs_init.o \
***************
*** 223,228 ****
--- 224,230 ----
  	$(WEBOBJ)/afs_daemons.o \
  	$(WEBOBJ)/afs_dcache.o \
  	$(WEBOBJ)/afs_dir.o \
+ 	$(WEBOBJ)/afs_disconnected.o \
  	$(WEBOBJ)/afs_dynroot.o \
  	$(WEBOBJ)/afs_icl.o \
  	$(WEBOBJ)/afs_init.o \
***************
*** 350,355 ****
--- 352,358 ----
  	$(WEBOBJ)/afs_dcache.o \
  	$(WEBOBJ)/afs_dir.o \
  	$(WEBOBJ)/afs_dynroot.o \
+ 	$(WEBOBJ)/afs_disconnected.o \
  	$(WEBOBJ)/afs_icl.o \
  	$(WEBOBJ)/afs_init.o \
  	$(WEBOBJ)/afs_lock.o \
***************
*** 471,476 ****
--- 474,480 ----
  	$(JUAFS)/afs_dcache.o \
  	$(JUAFS)/afs_dir.o \
  	$(JUAFS)/afs_dynroot.o \
+ 	$(JUAFS)/afs_disconnected.o \
  	$(JUAFS)/afs_icl.o \
  	$(JUAFS)/afs_init.o \
  	$(JUAFS)/afs_lock.o	\
***************
*** 600,605 ****
--- 604,611 ----
  	$(CRULE1)
  $(UOBJ)/afs_dynroot.o: $(TOP_SRC_AFS)/afs_dynroot.c
  	$(CRULE1)
+ $(UOBJ)/afs_disconnected.o: $(TOP_SRC_AFS)/afs_disconnected.c
+ 	$(CRULE1)
  $(UOBJ)/afs_error.o: $(TOP_SRC_AFS)/afs_error.c
  	$(CRULE1)
  $(UOBJ)/afs_init.o: $(TOP_SRC_AFS)/afs_init.c
***************
*** 855,860 ****
--- 861,868 ----
  	$(CRULE2)
  $(WEBOBJ)/afs_dcache.o: $(TOP_SRC_AFS)/afs_dcache.c
  	$(CRULE2)
+ $(WEBOBJ)/afs_disconnected.o: $(TOP_SRC_AFS)/afs_disconnected.c
+ 	$(CRULE2)
  $(WEBOBJ)/afs_dynroot.o: $(TOP_SRC_AFS)/afs_dynroot.c
  	$(CRULE2)
  $(WEBOBJ)/afs_error.o: $(TOP_SRC_AFS)/afs_error.c
***************
*** 1116,1121 ****
--- 1124,1131 ----
  	$(CRULE1)
  $(JUAFS)/afs_dcache.o: $(TOP_SRC_AFS)/afs_dcache.c
  	$(CRULE1)
+ $(JUAFS)/afs_disconnected.o: $(TOP_SRC_AFS)/afs_disconnected.c
+ 	$(CRULE1)
  $(JUAFS)/afs_dynroot.o: $(TOP_SRC_AFS)/afs_dynroot.c
  	$(CRULE1)
  $(JUAFS)/afs_error.o: $(TOP_SRC_AFS)/afs_error.c
Index: openafs/src/rx/rx.c
diff -c openafs/src/rx/rx.c:1.97.2.20.2.3 openafs/src/rx/rx.c:1.97.2.20.2.5
*** openafs/src/rx/rx.c:1.97.2.20.2.3	Tue May 20 17:59:42 2008
--- openafs/src/rx/rx.c	Fri May 23 10:56:02 2008
***************
*** 17,23 ****
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx.c,v 1.97.2.20.2.3 2008/05/20 21:59:42 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/sysincludes.h"
--- 17,23 ----
  #endif
  
  RCSID
!     ("$Header: /cvs/openafs/src/rx/rx.c,v 1.97.2.20.2.5 2008/05/23 14:56:02 shadow Exp $");
  
  #ifdef KERNEL
  #include "afs/sysincludes.h"
***************
*** 3006,3011 ****
--- 3006,3012 ----
  	}
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
  	rxi_ClearTransmitQueue(call, 0);
+ 	rxevent_Cancel(call->keepAliveEvent, call, RX_CALL_REFCOUNT_ALIVE);
  	break;
      default:
  	/* Should not reach here, unless the peer is broken: send an abort
***************
*** 4054,4059 ****
--- 4055,4061 ----
  	&& call->tfirst + call->nSoftAcked >= call->tnext) {
  	call->state = RX_STATE_DALLY;
  	rxi_ClearTransmitQueue(call, 0);
+         rxevent_Cancel(call->keepAliveEvent, call, RX_CALL_REFCOUNT_ALIVE);
      } else if (!queue_IsEmpty(&call->tq)) {
  	rxi_Start(0, call, 0, istack);
      }
***************
*** 4318,4324 ****
      }
  
      rxevent_Cancel(call->resendEvent, call, RX_CALL_REFCOUNT_RESEND);
-     rxevent_Cancel(call->keepAliveEvent, call, RX_CALL_REFCOUNT_ALIVE);
      call->tfirst = call->tnext;
      call->nSoftAcked = 0;
  
--- 4320,4325 ----
***************
*** 4359,4365 ****
  #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
  
      rxevent_Cancel(call->resendEvent, call, RX_CALL_REFCOUNT_RESEND);
-     rxevent_Cancel(call->keepAliveEvent, call, RX_CALL_REFCOUNT_ALIVE);
      call->tfirst = call->tnext;	/* implicitly acknowledge all data already sent */
      call->nSoftAcked = 0;
  
--- 4360,4365 ----
Index: openafs/src/venus/fs.c
diff -c openafs/src/venus/fs.c:1.30.2.13.2.2 openafs/src/venus/fs.c:1.30.2.13.2.3
*** openafs/src/venus/fs.c:1.30.2.13.2.2	Tue May 20 18:22:04 2008
--- openafs/src/venus/fs.c	Fri May 23 10:25:32 2008
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/fs.c,v 1.30.2.13.2.2 2008/05/20 22:22:04 shadow Exp $");
  
  #include <afs/afs_args.h>
  #include <rx/xdr.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/venus/fs.c,v 1.30.2.13.2.3 2008/05/23 14:25:32 shadow Exp $");
  
  #include <afs/afs_args.h>
  #include <rx/xdr.h>
***************
*** 3305,3313 ****
  
  #ifdef AFS_DISCON_ENV
  static char *modenames[] = {
!     "discon",
!     "fetchonly",
!     "partial",
      "nat",
      "full",
      NULL
--- 3305,3313 ----
  
  #ifdef AFS_DISCON_ENV
  static char *modenames[] = {
!     "readonly",
!     "fetchonly", /* Not currently supported */
!     "partial",   /* Not currently supported */
      "nat",
      "full",
      NULL
***************
*** 3678,3684 ****
  #ifdef AFS_DISCON_ENV
      ts = cmd_CreateSyntax("discon", DisconCmd, NULL,
  			  "disconnection mode");
!     cmd_AddParm(ts, "-mode", CMD_SINGLE, CMD_OPTIONAL, "nat | full");
  #endif
  
      ts = cmd_CreateSyntax("nukenfscreds", NukeNFSCredsCmd, NULL, "nuke credentials for NFS client");
--- 3678,3684 ----
  #ifdef AFS_DISCON_ENV
      ts = cmd_CreateSyntax("discon", DisconCmd, NULL,
  			  "disconnection mode");
!     cmd_AddParm(ts, "-mode", CMD_SINGLE, CMD_OPTIONAL, "readonly | nat | full");
  #endif
  
      ts = cmd_CreateSyntax("nukenfscreds", NukeNFSCredsCmd, NULL, "nuke credentials for NFS client");
Index: openafs/src/volser/vos.c
diff -c openafs/src/volser/vos.c:1.55.2.16 openafs/src/volser/vos.c:1.55.2.16.2.1
*** openafs/src/volser/vos.c:1.55.2.16	Mon Apr 14 16:25:52 2008
--- openafs/src/volser/vos.c	Wed May 21 23:52:01 2008
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vos.c,v 1.55.2.16 2008/04/14 20:25:52 shadow Exp $");
  
  #include <sys/types.h>
  #include <string.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vos.c,v 1.55.2.16.2.1 2008/05/22 03:52:01 shadow Exp $");
  
  #include <sys/types.h>
  #include <string.h>
***************
*** 1455,1465 ****
  }				/*XVolumeStats */
  
  static void
! VolumeStats(pntr, entry, server, part, voltype)
!      volintInfo *pntr;
!      struct nvldbentry *entry;
!      int voltype;
!      afs_int32 server, part;
  {
      int totalOK, totalNotOK, totalBusy;
  
--- 1455,1462 ----
  }				/*XVolumeStats */
  
  static void
! VolumeStats_int(volintInfo *pntr, struct nvldbentry *entry, afs_int32 server, 
! 	     afs_int32 part, int voltype)
  {
      int totalOK, totalNotOK, totalBusy;
  
***************
*** 1641,1647 ****
  		EnumerateEntry(&entry);
  	    } else
  #endif /* FULL_LISTVOL_SWITCH */
! 		VolumeStats(pntr, &entry, aserver, apart, voltype);
  
  	    if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
  		/* The VLDB says there is no backup volume yet we found one on disk */
--- 1638,1644 ----
  		EnumerateEntry(&entry);
  	    } else
  #endif /* FULL_LISTVOL_SWITCH */
! 		VolumeStats_int(pntr, &entry, aserver, apart, voltype);
  
  	    if ((voltype == BACKVOL) && !(entry.flags & BACK_EXISTS)) {
  		/* The VLDB says there is no backup volume yet we found one on disk */
Index: openafs/src/volser/vsprocs.c
diff -c openafs/src/volser/vsprocs.c:1.38.2.18 openafs/src/volser/vsprocs.c:1.38.2.18.2.1
*** openafs/src/volser/vsprocs.c:1.38.2.18	Thu Apr 24 18:45:47 2008
--- openafs/src/volser/vsprocs.c	Wed May 21 16:16:39 2008
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.38.2.18 2008/04/24 22:45:47 shadow Exp $");
  
  #include <stdio.h>
  #include <sys/types.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/volser/vsprocs.c,v 1.38.2.18.2.1 2008/05/21 20:16:39 shadow Exp $");
  
  #include <stdio.h>
  #include <sys/types.h>
***************
*** 5571,5577 ****
  
  	    entry.serverNumber[idx] = aserver;
  	    entry.serverPartition[idx] = apart;
! 	    entry.serverFlags[idx] = ITSRWVOL;
  
  	    modified++;
  	}
--- 5571,5577 ----
  
  	    entry.serverNumber[idx] = aserver;
  	    entry.serverPartition[idx] = apart;
! 	    entry.serverFlags[idx] = ITSBACKVOL;
  
  	    modified++;
  	}
