afs: Use common cleanup code for lockctl EINVAL
[openafs.git] / src / afs / VNOPS / afs_vnop_flock.c
index 931a72c..37e58ed 100644 (file)
@@ -47,21 +47,11 @@ lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
     proc_t *procp = ttoproc(curthread);
 
     if (slp) {
-# ifdef AFS_SUN53_ENV
        slp->sysid = 0;
        slp->pid = procp->p_pid;
-# else
-       slp->sysid = procp->p_sysid;
-       slp->pid = procp->p_epid;
-# endif
     } else {
-# ifdef AFS_SUN53_ENV
        flock->l_sysid = 0;
        flock->l_pid = procp->p_pid;
-# else
-       flock->l_sysid = procp->p_sysid;
-       flock->l_pid = procp->p_epid;
-# endif
     }
 }
 #elif defined(AFS_SGI_ENV)
@@ -271,6 +261,8 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
 #endif
     ObtainWriteLock(&avc->lock, 118);
     if (acom & LOCK_UN) {
+       int stored_segments = 0;
+     retry_unlock:
 
 /* defect 3083 */
 
@@ -317,7 +309,14 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
                }
            }
        } else if (avc->flockCount == -1) {
-           afs_StoreAllSegments(avc, areq, AFS_SYNC | AFS_VMSYNC);     /* fsync file early */
+           if (!stored_segments) {
+               afs_StoreAllSegments(avc, areq, AFS_SYNC | AFS_VMSYNC); /* fsync file early */
+               /* afs_StoreAllSegments can drop and reacquire the write lock
+                * on avc and GLOCK, so the flocks may be completely different
+                * now. Go back and perform all checks again. */
+                stored_segments = 1;
+                goto retry_unlock;
+           }
            avc->flockCount = 0;
            /* And remove the (only) exclusive lock entry from the list... */
            osi_FreeSmallSpace(avc->slocks);
@@ -325,19 +324,20 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
        }
        if (avc->flockCount == 0) {
            if (!AFS_IS_DISCONNECTED) {
+               struct rx_connection *rxconn;
                do {
-                   tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+                   tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
                    if (tc) {
                        XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
                        RX_AFS_GUNLOCK();
-                       code = RXAFS_ReleaseLock(tc->id, (struct AFSFid *)
+                       code = RXAFS_ReleaseLock(rxconn, (struct AFSFid *)
                                                 &avc->f.fid.Fid, &tsync);
                        RX_AFS_GLOCK();
                        XSTATS_END_TIME;
                    } else
                    code = -1;
                } while (afs_Analyze
-                        (tc, code, &avc->f.fid, areq,
+                        (tc, rxconn, code, &avc->f.fid, areq,
                          AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK, NULL));
            } else {
                /*printf("Network is dooooooowwwwwwwnnnnnnn\n");*/
@@ -383,14 +383,15 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
                }
                if (!code && avc->flockCount == 0) {
                    if (!AFS_IS_DISCONNECTED) {
+                       struct rx_connection *rxconn;
                        do {
-                           tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+                           tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
                            if (tc) {
                                XSTATS_START_TIME
                                    (AFS_STATS_FS_RPCIDX_RELEASELOCK);
                                RX_AFS_GUNLOCK();
                                code =
-                                   RXAFS_ReleaseLock(tc->id,
+                                   RXAFS_ReleaseLock(rxconn,
                                                      (struct AFSFid *)&avc->
                                                      f.fid.Fid, &tsync);
                                RX_AFS_GLOCK();
@@ -398,7 +399,7 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
                            } else
                                code = -1;
                        } while (afs_Analyze
-                                (tc, code, &avc->f.fid, areq,
+                                (tc, rxconn, code, &avc->f.fid, areq,
                                  AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK,
                                  NULL));
                    }
@@ -421,15 +422,16 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
                 * we've already checked for compatibility), we shouldn't send
                 * the call through to the server again */
                if (avc->flockCount == 0) {
+                   struct rx_connection *rxconn;
                    /* 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->f.fid, areq, SHARED_LOCK);
+                           tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
                            if (tc) {
                                XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SETLOCK);
                                RX_AFS_GUNLOCK();
-                               code = RXAFS_SetLock(tc->id, (struct AFSFid *)
+                               code = RXAFS_SetLock(rxconn, (struct AFSFid *)
                                                     &avc->f.fid.Fid, lockType,
                                                     &tsync);
                                RX_AFS_GLOCK();
@@ -437,7 +439,7 @@ HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
                            } else
                                code = -1;
                        } while (afs_Analyze
-                                (tc, code, &avc->f.fid, areq,
+                                (tc, rxconn, code, &avc->f.fid, areq,
                                  AFS_STATS_FS_RPCIDX_SETLOCK, SHARED_LOCK,
                                  NULL));
                        if ((lockType == LockWrite) && (code == VREADONLY))
@@ -568,7 +570,7 @@ int afs_lockctl(struct vcache * avc, struct AFS_FLOCK * af, int acmd,
     if (code) {
        goto done;
     }
-#if (defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)) && !defined(AFS_SUN58_ENV)
+#if defined(AFS_SGI_ENV)
     if ((acmd == F_GETLK) || (acmd == F_RGETLK)) {
 #else
     if (acmd == F_GETLK) {
@@ -581,7 +583,7 @@ int afs_lockctl(struct vcache * avc, struct AFS_FLOCK * af, int acmd,
        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)
+#if defined(AFS_SGI_ENV)
               || (acmd == F_RSETLK) || (acmd == F_RSETLKW)) {
 #else
        ) {
@@ -604,11 +606,11 @@ int afs_lockctl(struct vcache * avc, struct AFS_FLOCK * af, int acmd,
     else if (af->l_type == F_UNLCK)
        code = LOCK_UN;
     else {
-       afs_PutFakeStat(&fakestate);
-       return EINVAL;          /* unknown lock type */
+       code = EINVAL;          /* unknown lock type */
+       goto done;
     }
     if (((acmd == F_SETLK)
-#if    (defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)) && !defined(AFS_SUN58_ENV)
+#if    defined(AFS_SGI_ENV)
         || (acmd == F_RSETLK)
 #endif
        ) && code != LOCK_UN)
@@ -849,6 +851,7 @@ GetFlockCount(struct vcache *avc, struct vrequest *areq)
     struct AFSFetchStatus OutStatus;
     struct AFSCallBack CallBack;
     struct AFSVolSync tsync;
+    struct rx_connection *rxconn;
     int temp;
     XSTATS_DECLS;
     temp = areq->flags & O_NONBLOCK;
@@ -859,19 +862,19 @@ GetFlockCount(struct vcache *avc, struct vrequest *areq)
         return 0;
         
     do {
-       tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
+       tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
        if (tc) {
            XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHSTATUS);
            RX_AFS_GUNLOCK();
            code =
-               RXAFS_FetchStatus(tc->id, (struct AFSFid *)&avc->f.fid.Fid,
+               RXAFS_FetchStatus(rxconn, (struct AFSFid *)&avc->f.fid.Fid,
                                  &OutStatus, &CallBack, &tsync);
            RX_AFS_GLOCK();
            XSTATS_END_TIME;
        } else
            code = -1;
     } while (afs_Analyze
-            (tc, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_FETCHSTATUS,
+            (tc, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_FETCHSTATUS,
              SHARED_LOCK, NULL));
 
     if (temp)