openbsd-flock-fix-20030707
authorJim Rees <rees@umich.edu>
Mon, 7 Jul 2003 23:09:27 +0000 (23:09 +0000)
committerJim Rees <rees@umich.edu>
Mon, 7 Jul 2003 23:09:27 +0000 (23:09 +0000)
release all locks on last close, not just those for this process
  (not correct but better; needed for posix)
only sleep for remaining time in afs_osi_Wait if woken before timeout
add proto for afs_open

src/afs/OBSD/osi_sleep.c
src/afs/OBSD/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_flock.c
src/afs/VNOPS/afs_vnop_open.c
src/afs/VNOPS/afs_vnop_write.c
src/afs/afs_analyze.c
src/afs/afs_prototypes.h

index 268ad7a..5780d1d 100644 (file)
@@ -66,7 +66,7 @@ void afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
 
     AFS_STATCNT(osi_CancelWait);
     proc = achandle->proc;
-    if (proc == 0)
+    if (proc == NULL)
        return;
     achandle->proc = NULL;
     wakeup(&waitV);
@@ -78,30 +78,37 @@ void afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
  */
 int afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
 {
-    int code = 0;
-    afs_int32 endTime;
-    int timo = (ams * afs_hz) / 1000 + 1;
+    int timo, code = 0;
+    struct timeval atv, endTime;
 
     AFS_STATCNT(osi_Wait);
-    endTime = osi_Time() + (ams / 1000);
+
+    atv.tv_sec = ams / 1000;
+    atv.tv_usec = (ams % 1000) * 1000;
+    timeradd(&atv, &time, &endTime);
+
     if (ahandle)
        ahandle->proc = (caddr_t) curproc;
     AFS_ASSERT_GLOCK();
     AFS_GUNLOCK();
+
     do {
+       timersub(&endTime, &time, &atv);
+       timo = atv.tv_sec * hz + atv.tv_usec * hz / 1000000 + 1;
        if (aintok) {
-           code = tsleep(&waitV, PCATCH | PVFS, "afs_osi_Wait", timo);
-           if (code)   /* if interrupted, return EINTR */
-               code = EINTR;
+           code = tsleep(&waitV, PCATCH | PVFS, "afs_W1", timo);
+           if (code)
+               code = (code == EWOULDBLOCK) ? 0 : EINTR;
        } else
-           tsleep(&waitV, PVFS, "afs_osi_Wait", timo);
+           tsleep(&waitV, PVFS, "afs_W2", timo);
 
        /* if we were cancelled, quit now */
        if (ahandle && (ahandle->proc == NULL)) {
            /* we've been signalled */
            break;
        }
-    } while (osi_Time() < endTime);
+    } while (timercmp(&time, &endTime, <));
+
     AFS_GLOCK();
     return code;
 }
index 2748bb1..5b315f8 100644 (file)
@@ -213,6 +213,7 @@ int afs_debug;
 #undef VREF
 #define VREF afs_nbsd_ref
 
+#if 0
 extern int afs_lookup();
 extern int afs_open();
 extern int afs_close();
@@ -226,6 +227,7 @@ extern int afs_rmdir();
 extern int afs_symlink();
 extern int afs_readdir();
 extern int afs_readlink();
+#endif
 
 int
 afs_nbsd_lookup(ap)
index 89f97b4..9a6c659 100644 (file)
@@ -415,13 +415,13 @@ int HandleFlock(register struct vcache *avc, int acom,
                break;
            }
            /* now, if we got EWOULDBLOCK, and we're supposed to wait, we do */
-           if(((code == EWOULDBLOCK)||(code == EAGAIN)) && !(acom & LOCK_NB)) {
+           if(((code == EWOULDBLOCK) || (code == EAGAIN)) && !(acom & LOCK_NB)) {
                /* sleep for a second, allowing interrupts */
                ReleaseWriteLock(&avc->lock);
 #if defined(AFS_SGI_ENV)
                AFS_RWUNLOCK((vnode_t *)avc, VRWLOCK_WRITE);
 #endif
-               code = afs_osi_Wait(1000, (struct afs_osi_WaitHandle *) 0, 1);
+               code = afs_osi_Wait(1000, NULL, 1);
 #if defined(AFS_SGI_ENV)
                AFS_RWLOCK((vnode_t *)avc, VRWLOCK_WRITE);
 #endif
@@ -460,14 +460,12 @@ static void DoLockWarning(void)
 #ifdef AFS_OSF_ENV
 afs_lockctl(struct vcache *avc, struct eflock *af, int flag, 
        struct AFS_UCRED *acred, pid_t clid, off_t offset)
-#else
-#if defined(AFS_SGI_ENV) || (defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+#elif defined(AFS_SGI_ENV) || (defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd, struct AFS_UCRED *acred, pid_t clid)
 #else
 u_int clid=0;
 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd, struct AFS_UCRED *acred)
 #endif
-#endif
 {
     struct vrequest treq;
     afs_int32 code;
@@ -551,21 +549,19 @@ afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd, struct AFS_UCRED
        }
        if (((acmd == F_SETLK) 
 #if    (defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV)) && !defined(AFS_SUN58_ENV)
-       || (acmd == F_RSETLK) 
+             || (acmd == F_RSETLK) 
 #endif
        ) && code != LOCK_UN)
            code |= LOCK_NB;    /* non-blocking, s.v.p. */
-#if    defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) 
+#if    (defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)) || defined(AFS_OSF_ENV) 
        code = HandleFlock(avc, code, &treq, clid, 0/*!onlymine*/);
-#else
-#if defined(AFS_SGI_ENV)
+#elif defined(AFS_SGI_ENV)
        AFS_RWLOCK((vnode_t *)avc, VRWLOCK_WRITE);
        code = HandleFlock(avc, code, &treq, clid, 0/*!onlymine*/);
        AFS_RWUNLOCK((vnode_t *)avc, VRWLOCK_WRITE);
 #else
        code = HandleFlock(avc, code, &treq, 0, 0/*!onlymine*/);
 #endif
-#endif
        code = afs_CheckCode(code, &treq, 3); /* defeat AIX -O bug */
        afs_PutFakeStat(&fakestate);
        return code;
@@ -597,8 +593,10 @@ static int HandleGetLock(register struct vcache *avc,
 
     ObtainWriteLock(&avc->lock,122);
     if (avc->flockCount == 0) {
-       /* We don't know ourselves, so ask the server. Unfortunately, we don't know the pid.
-        * Not even the server knows the pid.  Besides, the process with the lock is on another machine
+       /*
+        * We don't know ourselves, so ask the server. Unfortunately, we
+        * don't know the pid.  Not even the server knows the pid.  Besides,
+        * the process with the lock is on another machine
         */
        code = GetFlockCount(avc, areq);
        if (code == 0 || (af->l_type == F_RDLCK && code > 0)) {
index 2fcf8ce..f5624b6 100644 (file)
@@ -32,15 +32,12 @@ RCSID("$Header$");
  * checks are done here, instead they're done by afs_create or afs_access,
  * both called by the vn_open call.
  */
+int
 #ifdef AFS_SGI64_ENV
-afs_open(bhv, avcp, aflags, acred)
-    bhv_desc_t *bhv;
+afs_open(bhv_desc_t *bhv, struct vcache **avcp, afs_int32 aflags, struct AFS_UCRED *acred)
 #else
-afs_open(avcp, aflags, acred)
+afs_open(struct vcache **avcp, afs_int32 aflags, struct AFS_UCRED *acred)
 #endif
-    register struct vcache **avcp;
-    afs_int32 aflags;
-    struct AFS_UCRED *acred; 
 {
     register afs_int32 code;
     struct vrequest treq;
index e943fd4..387cf63 100644 (file)
@@ -788,8 +788,7 @@ off_t offset;
 struct flid *flp;
 #endif
 #endif
-#else /* SGI */
-#if    defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
+#elif  defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
 #ifdef AFS_SUN5_ENV
 afs_close(OSI_VC_ARG(avc), aflags, count, offset, acred)
     offset_t offset;
@@ -797,13 +796,9 @@ afs_close(OSI_VC_ARG(avc), aflags, count, offset, acred)
 afs_close(OSI_VC_ARG(avc), aflags, count, acred)
 #endif
 int count;
-#elif defined(AFS_OBSD_ENV)
-afs_close(OSI_VC_ARG(avc), aflags, acred, aproc)
-    struct proc *aproc;
 #else
 afs_close(OSI_VC_ARG(avc), aflags, acred)
 #endif
-#endif
     OSI_VC_DECL(avc);
     afs_int32 aflags;
     struct AFS_UCRED *acred; 
@@ -838,15 +833,13 @@ afs_close(OSI_VC_ARG(avc), aflags, acred)
        afs_PutFakeStat(&fakestat);
        return 0;
     }
-#else
-#if    defined(AFS_SUN_ENV) || defined(AFS_SGI_ENV)
+#elif  defined(AFS_SUN_ENV) || defined(AFS_SGI_ENV)
     if (count > 1) {
        /* The vfs layer may call this repeatedly with higher "count"; only on the last close (i.e. count = 1) we should actually proceed with the close. */
        afs_PutFakeStat(&fakestat);
        return 0;
     }
 #endif
-#endif
 #ifndef        AFS_SUN5_ENV
 #if defined(AFS_SGI_ENV)
     /* unlock any locks for pid - could be wrong for child .. */
@@ -865,18 +858,16 @@ afs_close(OSI_VC_ARG(avc), aflags, acred)
 #endif /* AFS_SGI65_ENV */
     /* afs_chkpgoob will drop and re-acquire the global lock. */
     afs_chkpgoob(&avc->v, btoc(avc->m.Length));
-#else
+#else /* AFS_SGI_ENV */
     if (avc->flockCount) {             /* Release Lock */
 #if    defined(AFS_OSF_ENV) || defined(AFS_SUN_ENV)
        HandleFlock(avc, LOCK_UN, &treq, u.u_procp->p_pid, 1/*onlymine*/);
-#elif defined(AFS_OBSD_ENV)
-       HandleFlock(avc, LOCK_UN, &treq, aproc->p_pid, 1/*onlymine*/);
 #else
        HandleFlock(avc, LOCK_UN, &treq, 0, 1/*onlymine*/);
 #endif
     }
-#endif
-#endif
+#endif /* AFS_SGI_ENV */
+#endif /* AFS_SUN5_ENV */
     if (aflags & (FWRITE | FTRUNC)) {
        if (afs_BBusy()) {
            /* do it yourself if daemons are all busy */
index 57490ed..5dcad91 100644 (file)
@@ -131,7 +131,6 @@ void init_et_to_sys_error(void) {
     et2sys[(UAENOANO-ERROR_TABLE_BASE_uae)] = ENOANO;
     et2sys[(UAEBADRQC-ERROR_TABLE_BASE_uae)] = EBADRQC;
     et2sys[(UAEBADSLT-ERROR_TABLE_BASE_uae)] = EBADSLT;
-    et2sys[(UAEDEADLK-ERROR_TABLE_BASE_uae)] = EDEADLK;
     et2sys[(UAEBFONT-ERROR_TABLE_BASE_uae)] = EBFONT;
     et2sys[(UAENOSTR-ERROR_TABLE_BASE_uae)] = ENOSTR;
     et2sys[(UAENODATA-ERROR_TABLE_BASE_uae)] = ENODATA;
index c4fa9a8..60b81bb 100644 (file)
@@ -825,6 +825,14 @@ extern int afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *a
 extern int afs_lookup();
 
 
+/* VNOPS/afs_vnop_open.c */
+#ifdef AFS_SGI64_ENV
+extern int afs_open(bhv_desc_t *bhv, struct vcache **avcp, afs_int32 aflags, struct AFS_UCRED *acred);
+#else
+extern int afs_open(struct vcache **avcp, afs_int32 aflags, struct AFS_UCRED *acred);
+#endif
+
+
 /* VNOPS/afs_vnop_read.c */
 extern afs_int32 maxIHint;
 extern afs_int32 nihints;
@@ -838,6 +846,7 @@ extern int afs_UFSRead(register struct vcache *avc, struct uio *auio,
 /* VNOPS/afs_vnop_readdir.c */
 extern int afs_rd_stash_i;
 
+
 /* VNOPS/afs_vnop_remove.c */
 extern int afsremove(register struct vcache *adp, register struct dcache *tdc, 
         register struct vcache *tvc, char *aname, struct AFS_UCRED *acred, 
@@ -867,7 +876,6 @@ extern int afs_DoPartialWrite(register struct vcache *avc, struct vrequest *areq
 extern int afs_closex(register struct file *afd);
 
 /* other VNOPS (please fix these) */
-extern int afs_open();
 extern int afs_close();
 extern int HandleIoctl();
 extern int afs_fsync();