#include <afsconfig.h>
#include "afs/param.h"
-RCSID
- ("$Header$");
#include "afs/sysincludes.h" /* Standard vendor system headers */
#include "afsincludes.h" /* Afs-based standard headers */
static int lockIdcmp2(struct AFS_FLOCK *flock1, struct vcache *vp,
register 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 */
+
+#if defined(AFS_SUN5_ENV)
void
lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
{
-#if defined(AFS_SUN5_ENV)
- register 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_SGI_ENV
- struct proc *procp = OSI_GET_CURRENT_PROCP();
-#else
- struct proc *procp = u.u_procp;
-#endif /* AFS_SGI_ENV */
-#endif
-#endif
-#if defined(AFS_SGI65_ENV)
- flid_t flid;
- get_current_flid(&flid);
-#endif
+ proc_t *procp = ttoproc(curthread);
if (slp) {
-#ifdef AFS_AIX32_ENV
-#ifdef AFS_AIX41_ENV
- slp->sysid = 0;
- slp->pid = getpid();
-#else
- slp->sysid = u.u_sysid;
- slp->pid = u.u_epid;
-#endif
-#else
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
-#ifdef AFS_SUN53_ENV
+# ifdef AFS_SUN53_ENV
slp->sysid = 0;
slp->pid = procp->p_pid;
-#else
+# else
slp->sysid = procp->p_sysid;
slp->pid = procp->p_epid;
-#endif
-#else
-#if defined(AFS_SGI_ENV)
-#ifdef AFS_SGI65_ENV
+# 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)
+void
+lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
+{
+# if defined(AFS_SGI65_ENV)
+ flid_t flid;
+ get_current_flid(&flid);
+# else
+ afs_proc_t *procp = OSI_GET_CURRENT_PROCP();
+# endif
+
+ if (slp) {
+# ifdef AFS_SGI65_ENV
slp->sysid = flid.fl_sysid;
-#else
+# else
slp->sysid = OSI_GET_CURRENT_SYSID();
-#endif
- slp->pid = clid;
-#else
-#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+# endif
slp->pid = clid;
-#else
-#if defined(AFS_LINUX20_ENV) || defined(AFS_HPUX_ENV)
+ } else {
+# ifdef AFS_SGI65_ENV
+ flock->l_sysid = flid.fl_sysid;
+# else
+ flock->l_sysid = OSI_GET_CURRENT_SYSID();
+# endif
+ flock->l_pid = clid;
+ }
+}
+#elif defined(AFS_AIX_ENV)
+void
+lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
+{
+# if !defined(AFS_AIX32_ENV)
+ afs_proc_t *procp = u.u_procp;
+# endif
+
+ if (slp) {
+# if defined(AFS_AIX41_ENV)
+ slp->sysid = 0;
slp->pid = getpid();
-#else
- slp->pid = u.u_procp->p_pid;
-#endif
-#endif
-#endif /* AFS_AIX_ENV */
-#endif /* AFS_AIX32_ENV */
-#endif
+# elif defined(AFS_AIX32_ENV)
+ slp->sysid = u.u_sysid;
+ slp->pid = u.u_epid;
+# else
+ slp->sysid = procp->p_sysid;
+ slp->pid = prcop->p_epid;
+# endif
} else {
-#if defined(AFS_AIX32_ENV)
-#ifdef AFS_AIX41_ENV
+# if defined(AFS_AIX41_ENV)
flock->l_sysid = 0;
flock->l_pid = getpid();
-#else
+# elif defined(AFS_AIX32_ENV)
flock->l_sysid = u.u_sysid;
flock->l_pid = u.u_epid;
-#endif
-#else
-#if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
-#ifdef AFS_SUN53_ENV
- flock->l_sysid = 0;
- flock->l_pid = procp->p_pid;
-#else
+# else
flock->l_sysid = procp->p_sysid;
flock->l_pid = procp->p_epid;
-#endif
-#else
-#if defined(AFS_SGI_ENV)
-#ifdef AFS_SGI65_ENV
- flock->l_sysid = flid.fl_sysid;
-#else
- flock->l_sysid = OSI_GET_CURRENT_SYSID();
-#endif
- flock->l_pid = clid;
-#else
-#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+# endif
+ }
+}
+#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+void
+lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
+{
+ if (slp) {
+ slp->pid = clid;
+ } else {
flock->l_pid = clid;
-#else
-#if defined(AFS_LINUX20_ENV) || defined(AFS_HPUX_ENV)
+ }
+}
+#elif defined(AFS_LINUX20_ENV) || defined(AFS_HPUX_ENV)
+void
+lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
+{
+ if (slp) {
+ slp->pid = getpid();
+ } else {
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)
+{
+ if (slp) {
+ slp->pid = u.u_procp->p_pid;
+ } else {
flock->l_pid = u.u_procp->p_pid;
-#endif
-#endif
-#endif
-#endif /* AFS_AIX_ENV */
-#endif /* AFS_AIX32_ENV */
}
}
+#endif
/* return 1 (true) if specified flock does not match alp (if
* specified), or any of the slp structs (if alp == 0)
#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
- struct proc *procp = curprocp;
-#else /* AFS_SGI64_ENV */
- struct proc *procp = u.u_procp;
+ afs_proc_t *procp = curprocp;
+#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
#endif
HandleFlock(register struct vcache *avc, int acom, struct vrequest *areq,
pid_t clid, int onlymine)
{
- struct conn *tc;
+ struct afs_conn *tc;
struct SimpleLocks *slp, *tlp, **slpp;
afs_int32 code;
struct AFSVolSync tsync;
}
}
} else if (avc->flockCount == -1) {
- afs_StoreAllSegments(avc, areq, AFS_ASYNC); /* fsync file early */
+ afs_StoreAllSegments(avc, areq, AFS_SYNC | AFS_VMSYNC); /* fsync file early */
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) {
do {
- tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
if (tc) {
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
RX_AFS_GUNLOCK();
code = RXAFS_ReleaseLock(tc->id, (struct AFSFid *)
- &avc->fid.Fid, &tsync);
+ &avc->f.fid.Fid, &tsync);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tc, code, &avc->fid, areq,
+ (tc, 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) {
do {
- tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
if (tc) {
XSTATS_START_TIME
(AFS_STATS_FS_RPCIDX_RELEASELOCK);
code =
RXAFS_ReleaseLock(tc->id,
(struct AFSFid *)&avc->
- fid.Fid, &tsync);
+ f.fid.Fid, &tsync);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tc, code, &avc->fid, areq,
+ (tc, code, &avc->f.fid, areq,
AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK,
NULL));
}
lockType = ((acom & LOCK_EX) ? LockWrite : LockRead);
if (!AFS_IS_DISCONNECTED) {
do {
- tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
if (tc) {
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SETLOCK);
RX_AFS_GUNLOCK();
code = RXAFS_SetLock(tc->id, (struct AFSFid *)
- &avc->fid.Fid, lockType,
+ &avc->f.fid.Fid, lockType,
&tsync);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tc, code, &avc->fid, areq,
+ (tc, 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;
+ 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;
-
- /* otherwise, it is time to nag the user */
- lastWarnTime = now;
- afs_warn
- ("afs: byte-range lock/unlock ignored; make sure no one else is running this program.\n");
+ /* check if we've already warned this user recently */
+ if (!((now < lastWarnTime + 120) && (lastWarnPid == pid))) {
+ procname = afs_osi_Alloc(256);
+
+ if (!procname)
+ return;
+
+ /* 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_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_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;
}
-#ifdef AFS_OSF_ENV
-int afs_lockctl(struct vcache * avc, struct eflock * af, int flag,
- struct AFS_UCRED * acred, pid_t clid, off_t offset)
-#elif defined(AFS_SGI_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+#if defined(AFS_SGI_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
int afs_lockctl(struct vcache * avc, struct AFS_FLOCK * af, int acmd,
- struct AFS_UCRED * acred, pid_t clid)
+ afs_ucred_t * acred, pid_t clid)
#else
u_int clid = 0;
int afs_lockctl(struct vcache * avc, struct AFS_FLOCK * af, int acmd,
- struct AFS_UCRED * acred)
+ afs_ucred_t * acred)
#endif
{
struct vrequest treq;
afs_int32 code;
-#ifdef AFS_OSF_ENV
- int acmd = 0;
-#endif
struct afs_fakestat_state fakestate;
AFS_STATCNT(afs_lockctl);
if (code) {
goto done;
}
-#ifdef AFS_OSF_ENV
- if (flag & VNOFLCK) {
- code = 0;
- goto done;
- }
- if (flag & CLNFLCK) {
- acmd = LOCK_UN;
- } else if ((flag & GETFLCK) || (flag & RGETFLCK)) {
- acmd = F_GETLK;
- } else if ((flag & SETFLCK) || (flag & RSETFLCK)) {
- acmd = F_SETLK;
- }
-#endif
#if (defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)) && !defined(AFS_SUN58_ENV)
if ((acmd == F_GETLK) || (acmd == F_RGETLK)) {
#else
code = 0;
goto done;
}
-#ifndef AFS_OSF_ENV /* getlock is a no-op for osf (for now) */
code = HandleGetLock(avc, af, &treq, clid);
-#endif
code = afs_CheckCode(code, &treq, 2); /* defeat buggy AIX optimz */
goto done;
} else if ((acmd == F_SETLK) || (acmd == F_SETLKW)
#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 == 0x7ffffffffffffffe))
+ /* 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;
}
#endif
) && code != LOCK_UN)
code |= LOCK_NB; /* non-blocking, s.v.p. */
-#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)
+#if defined(AFS_DARWIN_ENV)
code = HandleFlock(avc, code, &treq, clid, 0 /*!onlymine */ );
#elif defined(AFS_SGI_ENV)
AFS_RWLOCK((vnode_t *) avc, VRWLOCK_WRITE);
* 2. Asking for write lock, and only the current
* PID has the file read locked.
*/
-#ifndef AFS_OSF_ENV /* getlock is a no-op for osf (for now) */
static int
HandleGetLock(register struct vcache *avc, register struct AFS_FLOCK *af,
register struct vrequest *areq, int clid)
static int
GetFlockCount(struct vcache *avc, struct vrequest *areq)
{
- register struct conn *tc;
+ register struct afs_conn *tc;
register afs_int32 code;
struct AFSFetchStatus OutStatus;
struct AFSCallBack CallBack;
return 0;
do {
- tc = afs_Conn(&avc->fid, areq, SHARED_LOCK);
+ tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK);
if (tc) {
XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHSTATUS);
RX_AFS_GUNLOCK();
code =
- RXAFS_FetchStatus(tc->id, (struct AFSFid *)&avc->fid.Fid,
+ RXAFS_FetchStatus(tc->id, (struct AFSFid *)&avc->f.fid.Fid,
&OutStatus, &CallBack, &tsync);
RX_AFS_GLOCK();
XSTATS_END_TIME;
} else
code = -1;
} while (afs_Analyze
- (tc, code, &avc->fid, areq, AFS_STATS_FS_RPCIDX_FETCHSTATUS,
+ (tc, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_FETCHSTATUS,
SHARED_LOCK, NULL));
if (temp)
return ((int)OutStatus.lockCount);
}
}
-#endif
-
-#if !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV) && !defined(AFS_SGI_ENV) && !defined(UKERNEL) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
-/* Flock not support on System V systems */
-#ifdef AFS_OSF_ENV
-extern struct fileops afs_fileops;
-
-int
-afs_xflock(struct proc *p, void *args, int *retval)
-#else /* AFS_OSF_ENV */
-int
-afs_xflock(void)
-#endif
-{
- int code = 0;
- struct a {
- int fd;
- int com;
- } *uap;
- struct file *fd;
- struct vrequest treq;
- struct vcache *tvc;
- int flockDone;
- struct afs_fakestat_state fakestate;
-
- afs_InitFakeStat(&fakestate);
- AFS_STATCNT(afs_xflock);
- flockDone = 0;
-#ifdef AFS_OSF_ENV
- uap = (struct a *)args;
- getf(&fd, uap->fd, FILE_FLAGS_NULL, &u.u_file_state);
-#else /* AFS_OSF_ENV */
- uap = (struct a *)u.u_ap;
- fd = getf(uap->fd);
-#endif
- if (!fd) {
- afs_PutFakeStat(&fakestate);
- return;
- }
-
- if (flockDone = afs_InitReq(&treq, u.u_cred)) {
- afs_PutFakeStat(&fakestate);
- return flockDone;
- }
-
- AFS_DISCON_LOCK();
-
- /* first determine whether this is any sort of vnode */
- if (fd->f_type == DTYPE_VNODE) {
- /* good, this is a vnode; next see if it is an AFS vnode */
- tvc = VTOAFS(fd->f_data); /* valid, given a vnode */
- if (IsAfsVnode(AFSTOV(tvc))) {
- /* This is an AFS vnode, so do the work */
- code = afs_EvalFakeStat(&tvc, &fakestate, &treq);
- if (code) {
- AFS_DISCON_UNLOCK();
- afs_PutFakeStat(&fakestate);
- return code;
- }
- if ((fd->f_flag & (FEXLOCK | FSHLOCK)) && !(uap->com & LOCK_UN)) {
- /* First, if fd already has lock, release it for relock path */
-#if defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV)
- HandleFlock(tvc, LOCK_UN, &treq, u.u_procp->p_pid,
- 0 /*!onlymine */ );
-#else
- HandleFlock(tvc, LOCK_UN, &treq, 0, 0 /*!onlymine */ );
-#endif
- fd->f_flag &= ~(FEXLOCK | FSHLOCK);
- }
- /* now try the requested operation */
-
-#if defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV)
- code =
- HandleFlock(tvc, uap->com, &treq, u.u_procp->p_pid,
- 0 /*!onlymine */ );
-#else
- code = HandleFlock(tvc, uap->com, &treq, 0, 0 /*!onlymine */ );
-#endif
-#ifndef AFS_OSF_ENV
- u.u_error = code;
-#endif
-
- if (uap->com & LOCK_UN) {
- /* gave up lock */
- fd->f_flag &= ~(FEXLOCK | FSHLOCK);
- } else {
-#ifdef AFS_OSF_ENV
- if (!code) {
-#else /* AFS_OSF_ENV */
- if (!u.u_error) {
-#endif
- if (uap->com & LOCK_SH)
- fd->f_flag |= FSHLOCK;
- else if (uap->com & LOCK_EX)
- fd->f_flag |= FEXLOCK;
- }
- }
- flockDone = 1;
- fd->f_ops = &afs_fileops;
- }
- }
-#ifdef AFS_OSF_ENV
- if (!flockDone)
- code = flock(p, args, retval);
-#ifdef AFS_OSF30_ENV
- FP_UNREF_ALWAYS(fd);
-#else
- FP_UNREF(fd);
-#endif
- AFS_DISCON_UNLOCK();
- afs_PutFakeStat(&fakestate);
- return code;
-#else /* AFS_OSF_ENV */
- if (!flockDone)
- flock();
- AFS_DISCON_UNLOCK();
- afs_PutFakeStat(&fakestate);
- return;
-#endif
-}
-#endif /* !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV) && !defined(UKERNEL) && !defined(AFS_LINUX20_ENV) */