/* Static prototypes */
-static int HandleGetLock(register struct vcache *avc,
- register struct AFS_FLOCK *af,
- register struct vrequest *areq, int clid);
+static int HandleGetLock(struct vcache *avc,
+ struct AFS_FLOCK *af,
+ struct vrequest *areq, int clid);
static int GetFlockCount(struct vcache *avc, struct vrequest *areq);
static int lockIdcmp2(struct AFS_FLOCK *flock1, struct vcache *vp,
- register struct SimpleLocks *alp, int onlymine,
+ struct SimpleLocks *alp, int onlymine,
int clid);
-static void DoLockWarning(void);
+static void DoLockWarning(afs_ucred_t * acred);
/* int clid; * non-zero on SGI, OSF, SunOS, Darwin, xBSD ** XXX ptr type */
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)
flock->l_pid = getpid();
}
}
+#elif defined(UKERNEL)
+void
+lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
+{
+ if (slp) {
+ slp->pid = get_user_struct()->u_procp->p_pid;
+ } else {
+ flock->l_pid = get_user_struct()->u_procp->p_pid;
+ }
+}
#else
void
lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
static int
lockIdcmp2(struct AFS_FLOCK *flock1, struct vcache *vp,
- register struct SimpleLocks *alp, int onlymine, int clid)
+ struct SimpleLocks *alp, int onlymine, int clid)
{
- register struct SimpleLocks *slp;
+ struct SimpleLocks *slp;
#if defined(AFS_SUN5_ENV)
- register proc_t *procp = ttoproc(curthread);
+ proc_t *procp = ttoproc(curthread);
#else
#if !defined(AFS_AIX41_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_SGI65_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
#ifdef AFS_SGI64_ENV
afs_proc_t *procp = curprocp;
-#else /* AFS_SGI64_ENV */
+#elif defined(UKERNEL)
+ afs_proc_t *procp = get_user_struct()->u_procp;
+#else
afs_proc_t *procp = u.u_procp;
#endif /* AFS_SGI64_ENV */
#endif
*/
/* clid - nonzero on sgi sunos osf1 only */
int
-HandleFlock(register struct vcache *avc, int acom, struct vrequest *areq,
+HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
pid_t clid, int onlymine)
{
struct afs_conn *tc;
#endif
ObtainWriteLock(&avc->lock, 118);
if (acom & LOCK_UN) {
+ int stored_segments = 0;
+ retry_unlock:
/* defect 3083 */
}
}
} else if (avc->flockCount == -1) {
- afs_StoreAllSegments(avc, areq, AFS_ASYNC); /* 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);
}
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");*/
}
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();
} 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 if (avc->flockCount == -1 && (acom & LOCK_EX)) {
if (lockIdcmp2(&flock, avc, NULL, 1, clid)) {
code = EWOULDBLOCK;
- } else
+ } else {
code = 0;
+ /* We've just re-grabbed an exclusive lock, so we don't
+ * need to contact the fileserver, and we don't need to
+ * add the lock to avc->slocks (since we already have a
+ * lock there). So, we are done. */
+ break;
+ }
}
if (code == 0) {
/* compatible here, decide if needs to go to file server. If
* 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();
} 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))
+ code = EBADF; /* per POSIX; VREADONLY == EROFS */
} else
/* XXX - Should probably try and log this when we're
* XXX - running with logging enabled. But it's horrid
/* warn a user that a lock has been ignored */
afs_int32 lastWarnTime = 0; /* this is used elsewhere */
+static afs_int32 lastWarnPid = 0;
static void
-DoLockWarning(void)
+DoLockWarning(afs_ucred_t * acred)
{
- register afs_int32 now;
+ afs_int32 now;
+ pid_t pid = MyPidxx2Pid(MyPidxx);
+ char *procname;
+
now = osi_Time();
AFS_STATCNT(DoLockWarning);
- /* check if we've already warned someone recently */
- if (now < lastWarnTime + 120)
- return;
+ /* check if we've already warned this user recently */
+ if (!((now < lastWarnTime + 120) && (lastWarnPid == pid))) {
+ procname = afs_osi_Alloc(256);
+
+ if (!procname)
+ return;
- /* otherwise, it is time to nag the user */
- lastWarnTime = now;
+ /* Copies process name to allocated procname, see osi_machdeps for details of macro */
+ osi_procname(procname, 256);
+ procname[255] = '\0';
+
+ /* otherwise, it is time to nag the user */
+ lastWarnTime = now;
+ lastWarnPid = pid;
#ifdef AFS_LINUX26_ENV
- afs_warn
- ("afs: byte-range locks only enforced for processes on this machine.\n");
+ afs_warnuser
+ ("afs: byte-range locks only enforced for processes on this machine (pid %d (%s), user %ld).\n", pid, procname, (long)afs_cr_uid(acred));
#else
- afs_warn
- ("afs: byte-range lock/unlock ignored; make sure no one else is running this program.\n");
+ afs_warnuser
+ ("afs: byte-range lock/unlock ignored; make sure no one else is running this program (pid %d (%s), user %ld).\n", pid, procname, afs_cr_uid(acred));
#endif
+ afs_osi_Free(procname, 256);
+ }
+ return;
}
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) {
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
) {
#endif
- /* this next check is safer when left out, but more applications work
- * with it in. However, they fail in race conditions. The question is
- * what to do for people who don't have source to their application;
- * this way at least, they can get work done */
-#ifdef AFS_LINUX24_ENV
- if (af->l_len == OFFSET_MAX)
- af->l_len = 0; /* since some systems indicate it as EOF */
-#else
- if (af->l_len == 0x7fffffff)
- af->l_len = 0; /* since some systems indicate it as EOF */
-#ifdef AFS_LINUX_64BIT_KERNEL
- if (af->l_len == LONG_MAX)
- af->l_len = 0; /* since some systems indicate it as EOF */
-#endif
-#endif
- /* Java VMs ask for l_len=(long)-1 regardless of OS/CPU; bottom 32 bits
- * sometimes get masked off by OS */
- if ((sizeof(af->l_len) == 8) && (af->l_len == 0x7ffffffffffffffeLL))
+ /* Java VMs ask for l_len=(long)-1 regardless of OS/CPU */
+ if ((sizeof(af->l_len) == 8) && (af->l_len == 0x7fffffffffffffffLL))
af->l_len = 0;
/* next line makes byte range locks always succeed,
* even when they should block */
if (af->l_whence != 0 || af->l_start != 0 || af->l_len != 0) {
- DoLockWarning();
+ DoLockWarning(acred);
code = 0;
goto done;
}
return EINVAL; /* unknown lock type */
}
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)
* PID has the file read locked.
*/
static int
-HandleGetLock(register struct vcache *avc, register struct AFS_FLOCK *af,
- register struct vrequest *areq, int clid)
+HandleGetLock(struct vcache *avc, struct AFS_FLOCK *af,
+ struct vrequest *areq, int clid)
{
- register afs_int32 code;
+ afs_int32 code;
struct AFS_FLOCK flock;
lockIdSet(&flock, NULL, clid);
static int
GetFlockCount(struct vcache *avc, struct vrequest *areq)
{
- register struct afs_conn *tc;
- register afs_int32 code;
+ struct afs_conn *tc;
+ afs_int32 code;
struct AFSFetchStatus OutStatus;
struct AFSCallBack CallBack;
struct AFSVolSync tsync;
+ struct rx_connection *rxconn;
int temp;
XSTATS_DECLS;
temp = areq->flags & O_NONBLOCK;
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)