linux-configure-support-mandrake-kernel-patches-20011023
[openafs.git] / src / afs / afs_vcache.c
index b7b3819..205feff 100644 (file)
@@ -35,8 +35,8 @@
  * shutdown_vcache
  *
  */
-#include "../afs/param.h"       /*Should be always first*/
 #include <afsconfig.h>
+#include "../afs/param.h"
 
 RCSID("$Header$");
 
@@ -213,7 +213,7 @@ int afs_FlushVCache(struct vcache *avc, int *slept)
     /* This should put it back on the vnode free list since usecount is 1 */
     afs_vcount--;
     vSetType(avc, VREG);
-    if (avc->vrefCount > 0) {
+    if (VREFCOUNT(avc) > 0) {
         VN_UNLOCK((struct vnode *)avc);
         AFS_RELE((struct vnode *)avc);
     } else {
@@ -568,6 +568,10 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
         int vmax = 2 * afs_cacheStats;
         int vn = VCACHE_FREE;
 
+         AFS_GUNLOCK();
+        shrink_dcache_sb(afs_globalVFS);
+        AFS_GLOCK();
+
         i = 0;
         for(tq = VLRU.prev; tq != &VLRU && vn > 0; tq = uq) {
            tvc = QTOV(tq);
@@ -582,7 +586,7 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
            if (tvc == afs_globalVp)
                continue;
 
-           if ( tvc->vrefCount && tvc->opens == 0 ) {
+           if ( VREFCOUNT(tvc) && tvc->opens == 0 ) {
                struct inode *ip = (struct inode*)tvc;
                if (list_empty(&ip->i_dentry)) {
                    vn --;
@@ -656,10 +660,10 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
                 refpanic ("Exceeded pool of AFS vnodes(VLRU cycle?)");
            else if (QNext(uq) != tq)
                 refpanic ("VLRU inconsistent");
-           else if (tvc->vrefCount < 1) 
+           else if (VREFCOUNT(tvc) < 1) 
                 refpanic ("refcnt 0 on VLRU");
 
-           if ( tvc->vrefCount == 1   &&   tvc->opens == 0 
+           if ( VREFCOUNT(tvc) == 1   &&   tvc->opens == 0 
                && (tvc->states & CUnlinkedDel) == 0) {
                code = afs_FlushVCache(tvc, &fv_slept);
                if (code == 0) {
@@ -711,7 +715,7 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
 
 #ifdef AFS_DARWIN_ENV
           if (tvc->opens == 0 && ((tvc->states & CUnlinkedDel) == 0) &&
-                tvc->vrefCount == 1 && UBCINFOEXISTS(&tvc->v)) {
+                VREFCOUNT(tvc) == 1 && UBCINFOEXISTS(&tvc->v)) {
                osi_VM_TryReclaim(tvc, &fv_slept);
                if (fv_slept) {
                   uq = VLRU.prev;
@@ -720,7 +724,7 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
                }
             }
 #endif
-          if (tvc->vrefCount == 0 && tvc->opens == 0
+          if (VREFCOUNT(tvc) == 0 && tvc->opens == 0
               && (tvc->states & CUnlinkedDel) == 0) {
                code = afs_FlushVCache(tvc, &fv_slept);
                if (code == 0) {
@@ -752,7 +756,7 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
 #endif /* AFS_MACH_ENV */
 #if defined(AFS_SGI_ENV)
        { char name[METER_NAMSZ];
-       bzero(tvc, sizeof(struct vcache));
+       memset(tvc, 0, sizeof(struct vcache));
        tvc->v.v_number = ++afsvnumbers;
        tvc->vc_rwlockid = OSI_NO_LOCKID;
        initnsema(&tvc->vc_rwlock, 1, makesname(name, "vrw", tvc->v.v_number));
@@ -777,7 +781,7 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
 #endif /* AFS_MACH_ENV */
 
 #if !defined(AFS_SGI_ENV) && !defined(AFS_OSF_ENV)
-    bzero((char *)tvc, sizeof(struct vcache));
+    memset((char *)tvc, 0, sizeof(struct vcache));
 #else
     tvc->uncred = 0;
 #endif
@@ -815,7 +819,7 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
     /* Hold it for the LRU (should make count 2) */
     VN_HOLD((struct vnode *)tvc);
 #else  /* AFS_OSF_ENV */
-    tvc->vrefCount = 1;        /* us */
+    VREFCOUNT_SET(tvc, 1);     /* us */
 #endif /* AFS_OSF_ENV */
 #ifdef AFS_AIX32_ENV
     LOCK_INIT(&tvc->pvmlock, "vcache pvmlock");
@@ -851,10 +855,10 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
 #ifdef AFS_AIX_ENV
     /* Don't forget to free the gnode space */
     tvc->v.v_gnode = gnodepnt = (struct gnode *) osi_AllocSmallSpace(sizeof(struct gnode));
-    bzero((char *)gnodepnt, sizeof(struct gnode));
+    memset((char *)gnodepnt, 0, sizeof(struct gnode));
 #endif
 #ifdef AFS_SGI64_ENV
-    bzero((void*)&(tvc->vc_bhv_desc), sizeof(tvc->vc_bhv_desc));
+    memset((void*)&(tvc->vc_bhv_desc), 0, sizeof(tvc->vc_bhv_desc));
     bhv_desc_init(&(tvc->vc_bhv_desc), tvc, tvc, &Afs_vnodeops);
 #ifdef AFS_SGI65_ENV
     vn_bhv_head_init(&(tvc->v.v_bh), "afsvp");
@@ -951,12 +955,18 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
        sema_init(&ip->i_zombie, 1);
        init_waitqueue_head(&ip->i_wait);
        spin_lock_init(&ip->i_data.i_shared_lock);
+#ifdef STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK
+       spin_lock_init(&ip->i_data.page_lock);
+#endif
        INIT_LIST_HEAD(&ip->i_data.clean_pages);
        INIT_LIST_HEAD(&ip->i_data.dirty_pages);
        INIT_LIST_HEAD(&ip->i_data.locked_pages);
        INIT_LIST_HEAD(&ip->i_dirty_buffers);
        ip->i_data.host = (void*) ip;
        ip->i_mapping = &ip->i_data;
+#ifdef STRUCT_INODE_HAS_I_TRUNCATE_SEM
+       init_rwsem(&ip->i_truncate_sem);
+#endif
 #else
        sema_init(&ip->i_atomic_write, 1);
        init_waitqueue(&ip->i_wait);
@@ -971,8 +981,8 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp,
 #endif
     tvc->h1.dchint = 0;
     osi_dnlc_purgedp(tvc);  /* this may be overkill */
-    bzero((char *)&(tvc->quick),sizeof(struct vtodc));
-    bzero((char *)&(tvc->callsort),sizeof(struct afs_q));
+    memset((char *)&(tvc->quick), 0, sizeof(struct vtodc));
+    memset((char *)&(tvc->callsort), 0, sizeof(struct afs_q));
     tvc->slocks = (struct SimpleLocks *)0;
     i = VCHash(afid);
 
@@ -1078,7 +1088,7 @@ afs_FlushActiveVcaches(doflocks)
                /*
                 * That's because if we come in via the CUnlinkedDel bit state path we'll be have 0 refcnt
                 */
-               osi_Assert(tvc->vrefCount > 0);
+               osi_Assert(VREFCOUNT(tvc) > 0);
                AFS_RWLOCK((vnode_t *)tvc, VRWLOCK_WRITE);
 #endif
                ObtainWriteLock(&tvc->lock,52);
@@ -1133,7 +1143,7 @@ afs_FlushActiveVcaches(doflocks)
                AFS_FAST_RELE(tvc);
                if (didCore) {
 #ifdef AFS_GFS_ENV
-                   tvc->vrefCount--;
+                   VREFCOUNT_DEC(tvc);
 #else
                    AFS_RELE((struct vnode *)tvc);
 #endif
@@ -1142,7 +1152,7 @@ afs_FlushActiveVcaches(doflocks)
                }
            }          
 #ifdef AFS_DARWIN_ENV
-            if (tvc->vrefCount == 1 && UBCINFOEXISTS(&tvc->v)) {
+            if (VREFCOUNT(tvc) == 1 && UBCINFOEXISTS(&tvc->v)) {
                if (tvc->opens) panic("flushactive open, hasubc, but refcnt 1");
                osi_VM_TryReclaim(tvc,0);
            }
@@ -1680,8 +1690,15 @@ loop:
     /* stat the file */
     afs_RemoveVCB(afid);
     {
-    struct AFSFetchStatus OutStatus;
-    code = afs_FetchStatus(tvc, afid, areq, &OutStatus);
+       struct AFSFetchStatus OutStatus;
+
+       if (afs_DynrootNewVnode(tvc, &OutStatus)) {
+           afs_ProcessFS(tvc, &OutStatus, areq);
+           tvc->states |= CStatd | CUnique;
+           code = 0;
+       } else {
+           code = afs_FetchStatus(tvc, afid, areq, &OutStatus);
+       }
     }
 
     if (code) {
@@ -2599,7 +2616,7 @@ void afs_vcacheInit(int astatSize)
 #if    !defined(AFS_OSF_ENV)
     /* Allocate and thread the struct vcache entries */
     tvp = (struct vcache *) afs_osi_Alloc(astatSize * sizeof(struct vcache));
-    bzero((char *)tvp, sizeof(struct vcache)*astatSize);
+    memset((char *)tvp, 0, sizeof(struct vcache)*astatSize);
 
     Initial_freeVCList = tvp;
     freeVCList = &(tvp[0]);
@@ -2691,7 +2708,7 @@ void shutdown_vcache(void)
                    vms_delete(tvc->segid);
                    AFS_GLOCK();
                    tvc->segid = tvc->vmh = NULL;
-                   if (tvc->vrefCount) osi_Panic("flushVcache: vm race");
+                   if (VREFCOUNT(tvc)) osi_Panic("flushVcache: vm race");
                }
                if (tvc->credp) {
                    crfree(tvc->credp);