From b6a2aae8216822024d1ca844beaf866a02f3cdff Mon Sep 17 00:00:00 2001 From: Jim Rees Date: Mon, 7 Jul 2003 23:09:27 +0000 Subject: [PATCH] openbsd-flock-fix-20030707 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 | 27 +++++++++++++++++---------- src/afs/OBSD/osi_vnodeops.c | 2 ++ src/afs/VNOPS/afs_vnop_flock.c | 22 ++++++++++------------ src/afs/VNOPS/afs_vnop_open.c | 9 +++------ src/afs/VNOPS/afs_vnop_write.c | 19 +++++-------------- src/afs/afs_analyze.c | 1 - src/afs/afs_prototypes.h | 10 +++++++++- 7 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/afs/OBSD/osi_sleep.c b/src/afs/OBSD/osi_sleep.c index 268ad7abb..5780d1d8d 100644 --- a/src/afs/OBSD/osi_sleep.c +++ b/src/afs/OBSD/osi_sleep.c @@ -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; } diff --git a/src/afs/OBSD/osi_vnodeops.c b/src/afs/OBSD/osi_vnodeops.c index 2748bb123..5b315f856 100644 --- a/src/afs/OBSD/osi_vnodeops.c +++ b/src/afs/OBSD/osi_vnodeops.c @@ -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) diff --git a/src/afs/VNOPS/afs_vnop_flock.c b/src/afs/VNOPS/afs_vnop_flock.c index 89f97b415..9a6c659e4 100644 --- a/src/afs/VNOPS/afs_vnop_flock.c +++ b/src/afs/VNOPS/afs_vnop_flock.c @@ -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,20 +549,18 @@ 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); @@ -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)) { diff --git a/src/afs/VNOPS/afs_vnop_open.c b/src/afs/VNOPS/afs_vnop_open.c index 2fcf8ce46..f5624b68e 100644 --- a/src/afs/VNOPS/afs_vnop_open.c +++ b/src/afs/VNOPS/afs_vnop_open.c @@ -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; diff --git a/src/afs/VNOPS/afs_vnop_write.c b/src/afs/VNOPS/afs_vnop_write.c index e943fd44c..387cf6396 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -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,12 +796,8 @@ 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; @@ -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 */ diff --git a/src/afs/afs_analyze.c b/src/afs/afs_analyze.c index 57490edd4..5dcad918c 100644 --- a/src/afs/afs_analyze.c +++ b/src/afs/afs_analyze.c @@ -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; diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index c4fa9a85d..60b81bbcf 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -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(); -- 2.39.5