fix-linux-atomic-t-lossage-by-macroizing-vnode-refcounts-20011008
authorNickolai Zeldovich <kolya@mit.edu>
Mon, 8 Oct 2001 23:15:24 +0000 (23:15 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 8 Oct 2001 23:15:24 +0000 (23:15 +0000)
convert to macros for dealing with vnode refcounts
deal with linux 2.4 atomic_t in the process

src/afs/LINUX/osi_vfs.hin
src/afs/LINUX/osi_vm.c
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/VNOPS/afs_vnop_remove.c
src/afs/VNOPS/afs_vnop_write.c
src/afs/afs.h
src/afs/afs_callback.c
src/afs/afs_pioctl.c
src/afs/afs_util.c
src/afs/afs_vcache.c

index 99d8e3f..ee0588b 100644 (file)
@@ -57,7 +57,11 @@ enum vcexcl { EXCL, NONEXCL } ;
 #define FSYNC O_SYNC
 
 #define VTOI(V)  ((struct inode*)V)
+#ifdef AFS_LINUX24_ENV
+#define VN_HOLD(V) atomic_inc(&((vnode_t*)V)->i_count)
+#else
 #define VN_HOLD(V) ((vnode_t*)V)->i_count++;
+#endif
 #define VN_RELE(V) osi_iput((struct inode *)V);
 #define VFS_STATFS(V, S) ((V)->s_op->statfs)((V), (S), sizeof(*(S)))
 
index bf487a7..71831df 100644 (file)
@@ -43,7 +43,7 @@ int osi_VM_FlushVCache(struct vcache *avc, int *slept)
 {
     struct inode *ip = (struct inode*)avc;
 
-    if (avc->vrefCount != 0)
+    if (VREFCOUNT(avc) != 0)
        return EBUSY;
 
     if (avc->opens != 0)
index b81570c..4ff3158 100644 (file)
@@ -969,7 +969,7 @@ afs_lookup(adp, aname, avcp, acred)
        *avcp = tvc;
        code = (tvc ? 0 : ENOENT);
        hit = 1;
-       if (tvc && !tvc->vrefCount) {
+       if (tvc && !VREFCOUNT(tvc)) {
            osi_Panic("TT1");
        }
        if (code) {
@@ -1005,7 +1005,7 @@ afs_lookup(adp, aname, avcp, acred)
        code = 0;
        *avcp = tvc = adp;
        hit = 1;
-       if (adp && !adp->vrefCount) {
+       if (adp && !VREFCOUNT(adp)) {
            osi_Panic("TT2");
        }
        goto done;
@@ -1251,7 +1251,7 @@ afs_lookup(adp, aname, avcp, acred)
            }
        }
        *avcp = tvc;
-       if (tvc && !tvc->vrefCount) {
+       if (tvc && !VREFCOUNT(tvc)) {
            osi_Panic("TT3");
        }
        code = 0;
index 0ad500c..c3df294 100644 (file)
@@ -317,12 +317,12 @@ tagain:
     osi_dnlc_remove ( adp, aname, tvc);
     if (tvc) afs_symhint_inval(tvc);
 
-    Tadp1 = adp; Tadpr = adp->vrefCount; Ttvc = tvc; Tnam = aname; Tnam1 = 0;
-    if (tvc) Ttvcr = tvc->vrefCount;
+    Tadp1 = adp; Tadpr = VREFCOUNT(adp); Ttvc = tvc; Tnam = aname; Tnam1 = 0;
+    if (tvc) Ttvcr = VREFCOUNT(tvc);
 #ifdef AFS_AIX_ENV
-    if (tvc && (tvc->vrefCount > 2) && tvc->opens > 0 && !(tvc->states & CUnlinked)) {
+    if (tvc && (VREFCOUNT(tvc) > 2) && tvc->opens > 0 && !(tvc->states & CUnlinked)) {
 #else
-    if (tvc && (tvc->vrefCount > 1) && tvc->opens > 0 && !(tvc->states & CUnlinked)) {
+    if (tvc && (VREFCOUNT(tvc) > 1) && tvc->opens > 0 && !(tvc->states & CUnlinked)) {
 #endif
        char *unlname = newname();
 
index 55ad6f1..8f8c598 100644 (file)
@@ -909,7 +909,7 @@ afs_close(OSI_VC_ARG(avc), aflags, acred)
        ReleaseWriteLock(&avc->lock);
     }
 #ifdef AFS_OSF_ENV
-    if ((avc->vrefCount <= 2) && (avc->states & CUnlinked)) {
+    if ((VREFCOUNT(avc) <= 2) && (avc->states & CUnlinked)) {
        afs_remunlink(avc, 1);  /* ignore any return code */
     }
 #endif
index 9ed8343..ada55f0 100644 (file)
@@ -522,6 +522,18 @@ struct SimpleLocks {
 #define vrefCount   v.v_usecount
 #endif /* AFS_FBSD_ENV */
 
+#ifdef AFS_LINUX24_ENV
+#define VREFCOUNT(v)           atomic_read(&((vnode_t *) v)->v_count)
+#define VREFCOUNT_SET(v, c)    atomic_set(&((vnode_t *) v)->v_count, c)
+#define VREFCOUNT_DEC(v)       atomic_dec(&((vnode_t *) v)->v_count)
+#define VREFCOUNT_INC(v)       atomic_inc(&((vnode_t *) v)->v_count)
+#else
+#define VREFCOUNT(v)           ((v)->vrefCount)
+#define VREFCOUNT_SET(v, c)    (v)->vrefCount = c;
+#define VREFCOUNT_DEC(v)       (v)->vrefCount--;
+#define VREFCOUNT_INC(v)       (v)->vrefCount++;
+#endif
+
 #define        AFS_MAXDV   0x7fffffff      /* largest dataversion number */
 #define        AFS_NOTRUNC 0x7fffffff      /* largest dataversion number */
 
index c43d92c..193c642 100644 (file)
@@ -157,7 +157,7 @@ int SRXAFSCB_GetCE(a_call, a_index, a_result)
     a_result->DataVersion = hgetlo(tvc->m.DataVersion);
     a_result->callback = afs_data_pointer_to_int32(tvc->callback);             /* XXXX Now a pointer; change it XXXX */
     a_result->cbExpires = tvc->cbExpires;
-    a_result->refCount = tvc->vrefCount;
+    a_result->refCount = VREFCOUNT(tvc);
     a_result->opens = tvc->opens;
     a_result->writers = tvc->execsOrWriters;
     a_result->mvstat = tvc->mvstat;
index fce1b4b..95c07d2 100644 (file)
@@ -2560,13 +2560,13 @@ struct AFS_UCRED *acred;
     for(i = 0; i < VCSIZE; i++) {
        for(tvc = afs_vhashT[i]; tvc; tvc=tvc->hnext) {
            if (tvc->fid.Fid.Volume == volume && tvc->fid.Cell == cell) {
-#if    defined(AFS_SGI_ENV) || defined(AFS_ALPHA_ENV)  || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV)
+#if    defined(AFS_SGI_ENV) || defined(AFS_ALPHA_ENV)  || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
                VN_HOLD((struct vnode *)tvc);
 #else
 #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
                osi_vnhold(tvc, 0);
 #else
-               tvc->vrefCount++;
+               VREFCOUNT_INC(tvc);
 #endif
 #endif
                ReleaseReadLock(&afs_xvcache);
index aa04782..cbdca63 100644 (file)
@@ -180,9 +180,9 @@ void afs_CheckLocks()
        for(i=0;i<VCSIZE;i++) {
            for(tvc = afs_vhashT[i]; tvc; tvc=tvc->hnext) {
 #ifdef AFS_OSF_ENV
-               if (tvc->vrefCount > 1)
+               if (VREFCOUNT(tvc) > 1)
 #else  /* AFS_OSF_ENV */
-               if (tvc->vrefCount)
+               if (VREFCOUNT(tvc))
 #endif
                    afs_warn("Stat cache entry at %x is held\n", tvc);
                if (CheckLock(&tvc->lock))
index 923dc6e..4917b0d 100644 (file)
@@ -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 {
@@ -582,7 +582,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 +656,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 +711,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 +720,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) {
@@ -815,7 +815,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");
@@ -1081,7 +1081,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);
@@ -1136,7 +1136,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
@@ -1145,7 +1145,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);
            }
@@ -2694,7 +2694,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);