2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
15 #include <afsconfig.h>
16 #include "afs/param.h"
19 #include "afs/sysincludes.h" /* Standard vendor system headers */
20 #include "afsincludes.h" /* Afs-based standard headers */
21 #include "afs/afs_stats.h" /* statistics */
22 #include "afs/afs_cbqueue.h"
23 #include "afs/nfsclient.h"
24 #include "afs/afs_osidnlc.h"
25 #include "afs/unified_afs.h"
31 /* Static prototypes */
32 static int HandleGetLock(struct vcache *avc,
34 struct vrequest *areq, int clid);
35 static int GetFlockCount(struct vcache *avc, struct vrequest *areq);
36 static int lockIdcmp2(struct AFS_FLOCK *flock1, struct vcache *vp,
37 struct SimpleLocks *alp, int onlymine,
39 static void DoLockWarning(afs_ucred_t * acred);
41 /* int clid; * non-zero on SGI, OSF, SunOS, Darwin, xBSD ** XXX ptr type */
43 #if defined(AFS_SUN5_ENV)
45 lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
47 proc_t *procp = ttoproc(curthread);
52 slp->pid = procp->p_pid;
54 slp->sysid = procp->p_sysid;
55 slp->pid = procp->p_epid;
60 flock->l_pid = procp->p_pid;
62 flock->l_sysid = procp->p_sysid;
63 flock->l_pid = procp->p_epid;
67 #elif defined(AFS_SGI_ENV)
69 lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
71 # if defined(AFS_SGI65_ENV)
73 get_current_flid(&flid);
75 afs_proc_t *procp = OSI_GET_CURRENT_PROCP();
80 slp->sysid = flid.fl_sysid;
82 slp->sysid = OSI_GET_CURRENT_SYSID();
87 flock->l_sysid = flid.fl_sysid;
89 flock->l_sysid = OSI_GET_CURRENT_SYSID();
94 #elif defined(AFS_AIX_ENV)
96 lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
98 # if !defined(AFS_AIX32_ENV)
99 afs_proc_t *procp = u.u_procp;
103 # if defined(AFS_AIX41_ENV)
106 # elif defined(AFS_AIX32_ENV)
107 slp->sysid = u.u_sysid;
110 slp->sysid = procp->p_sysid;
111 slp->pid = prcop->p_epid;
114 # if defined(AFS_AIX41_ENV)
116 flock->l_pid = getpid();
117 # elif defined(AFS_AIX32_ENV)
118 flock->l_sysid = u.u_sysid;
119 flock->l_pid = u.u_epid;
121 flock->l_sysid = procp->p_sysid;
122 flock->l_pid = procp->p_epid;
126 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
128 lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
136 #elif defined(AFS_LINUX20_ENV) || defined(AFS_HPUX_ENV)
138 lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
143 flock->l_pid = getpid();
146 #elif defined(UKERNEL)
148 lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
151 slp->pid = get_user_struct()->u_procp->p_pid;
153 flock->l_pid = get_user_struct()->u_procp->p_pid;
158 lockIdSet(struct AFS_FLOCK *flock, struct SimpleLocks *slp, int clid)
161 slp->pid = u.u_procp->p_pid;
163 flock->l_pid = u.u_procp->p_pid;
168 /* return 1 (true) if specified flock does not match alp (if
169 * specified), or any of the slp structs (if alp == 0)
171 /* I'm not sure that the comparsion of flock->pid to p_ppid
172 * is correct. Should that be a comparision of alp (or slp) ->pid
173 * to p_ppid? Especially in the context of the lower loop, where
174 * the repeated comparison doesn't make much sense...
176 /* onlymine - don't match any locks which are held by my parent */
177 /* clid - only irix 6.5 */
180 lockIdcmp2(struct AFS_FLOCK *flock1, struct vcache *vp,
181 struct SimpleLocks *alp, int onlymine, int clid)
183 struct SimpleLocks *slp;
184 #if defined(AFS_SUN5_ENV)
185 proc_t *procp = ttoproc(curthread);
187 #if !defined(AFS_AIX41_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_SGI65_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
189 afs_proc_t *procp = curprocp;
190 #elif defined(UKERNEL)
191 afs_proc_t *procp = get_user_struct()->u_procp;
193 afs_proc_t *procp = u.u_procp;
194 #endif /* AFS_SGI64_ENV */
199 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
200 if (flock1->l_sysid != alp->sysid) {
204 if ((flock1->l_pid == alp->pid) ||
205 #if defined(AFS_AIX41_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_HPUX_ENV)
206 (!onlymine && (flock1->l_pid == getppid()))
208 #if defined(AFS_SGI65_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
209 /* XXX check this. used to be *only* irix for some reason. */
210 (!onlymine && (flock1->l_pid == clid))
212 (!onlymine && (flock1->l_pid == procp->p_ppid))
221 for (slp = vp->slocks; slp; slp = slp->next) {
222 #if defined(AFS_HAVE_FLOCK_SYSID)
223 if (flock1->l_sysid != slp->sysid) {
227 if (flock1->l_pid == slp->pid) {
231 return (1); /* failure */
235 /* we don't send multiple read flocks to the server, but rather just count
236 them up ourselves. Of course, multiple write locks are incompatible.
238 Note that we should always try to release a lock, even if we have
239 a network problem sending the release command through, since often
240 a lock is released on a close call, when the user can't retry anyway.
242 After we remove it from our structure, the lock will no longer be
243 kept alive, and the server should time it out within a few minutes.
245 94.04.13 add "force" parameter. If a child explicitly unlocks a
246 file, I guess we'll permit it. however, we don't want simple,
247 innocent closes by children to unlock files in the parent process.
249 If called when disconnected support is unabled, the discon_lock must
252 /* clid - nonzero on sgi sunos osf1 only */
254 HandleFlock(struct vcache *avc, int acom, struct vrequest *areq,
255 pid_t clid, int onlymine)
258 struct SimpleLocks *slp, *tlp, **slpp;
260 struct AFSVolSync tsync;
262 struct AFS_FLOCK flock;
264 AFS_STATCNT(HandleFlock);
265 code = 0; /* default when we don't make any network calls */
266 lockIdSet(&flock, NULL, clid);
268 #if defined(AFS_SGI_ENV)
269 osi_Assert(valusema(&avc->vc_rwlock) <= 0);
270 osi_Assert(OSI_GET_LOCKID() == avc->vc_rwlockid);
272 ObtainWriteLock(&avc->lock, 118);
273 if (acom & LOCK_UN) {
274 int stored_segments = 0;
280 /* If the lock is held exclusive, then only the owning process
281 * or a child can unlock it. Use pid and ppid because they are
282 * unique identifiers.
284 if ((avc->flockCount < 0) && (getpid() != avc->ownslock)) {
286 if (onlymine || (getppid() != avc->ownslock)) {
288 if (onlymine || (u.u_procp->p_ppid != avc->ownslock)) {
290 ReleaseWriteLock(&avc->lock);
295 if (lockIdcmp2(&flock, avc, NULL, onlymine, clid)) {
296 ReleaseWriteLock(&avc->lock);
302 if (avc->flockCount == 0) {
303 ReleaseWriteLock(&avc->lock);
307 /* unlock the lock */
308 if (avc->flockCount > 0) {
310 for (slp = *slpp; slp;) {
311 if (!lockIdcmp2(&flock, avc, slp, onlymine, clid)) {
313 tlp = *slpp = slp->next;
314 osi_FreeSmallSpace(slp);
321 } else if (avc->flockCount == -1) {
322 if (!stored_segments) {
323 afs_StoreAllSegments(avc, areq, AFS_SYNC | AFS_VMSYNC); /* fsync file early */
324 /* afs_StoreAllSegments can drop and reacquire the write lock
325 * on avc and GLOCK, so the flocks may be completely different
326 * now. Go back and perform all checks again. */
331 /* And remove the (only) exclusive lock entry from the list... */
332 osi_FreeSmallSpace(avc->slocks);
335 if (avc->flockCount == 0) {
336 if (!AFS_IS_DISCONNECTED) {
337 struct rx_connection *rxconn;
339 tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
341 XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
343 code = RXAFS_ReleaseLock(rxconn, (struct AFSFid *)
344 &avc->f.fid.Fid, &tsync);
350 (tc, rxconn, code, &avc->f.fid, areq,
351 AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK, NULL));
353 /*printf("Network is dooooooowwwwwwwnnnnnnn\n");*/
358 while (1) { /* set a new lock */
360 * Upgrading from shared locks to Exclusive and vice versa
361 * is a bit tricky and we don't really support it yet. But
362 * we try to support the common used one which is upgrade
363 * a shared lock to an exclusive for the same process...
365 if ((avc->flockCount > 0 && (acom & LOCK_EX))
366 || (avc->flockCount == -1 && (acom & LOCK_SH))) {
368 * Upgrading from shared locks to an exclusive one:
369 * For now if all the shared locks belong to the
370 * same process then we unlock them on the server
371 * and proceed with the upgrade. Unless we change the
372 * server's locking interface impl we prohibit from
373 * unlocking other processes's shared locks...
374 * Upgrading from an exclusive lock to a shared one:
375 * Again only allowed to be done by the same process.
378 for (slp = *slpp; slp;) {
380 (&flock, avc, slp, 1 /*!onlymine */ , clid)) {
385 tlp = *slpp = slp->next;
386 osi_FreeSmallSpace(slp);
394 if (!code && avc->flockCount == 0) {
395 if (!AFS_IS_DISCONNECTED) {
396 struct rx_connection *rxconn;
398 tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
401 (AFS_STATS_FS_RPCIDX_RELEASELOCK);
404 RXAFS_ReleaseLock(rxconn,
405 (struct AFSFid *)&avc->
412 (tc, rxconn, code, &avc->f.fid, areq,
413 AFS_STATS_FS_RPCIDX_RELEASELOCK, SHARED_LOCK,
417 } else if (avc->flockCount == -1 && (acom & LOCK_EX)) {
418 if (lockIdcmp2(&flock, avc, NULL, 1, clid)) {
422 /* We've just re-grabbed an exclusive lock, so we don't
423 * need to contact the fileserver, and we don't need to
424 * add the lock to avc->slocks (since we already have a
425 * lock there). So, we are done. */
430 /* compatible here, decide if needs to go to file server. If
431 * we've already got the file locked (and thus read-locked, since
432 * we've already checked for compatibility), we shouldn't send
433 * the call through to the server again */
434 if (avc->flockCount == 0) {
435 struct rx_connection *rxconn;
436 /* we're the first on our block, send the call through */
437 lockType = ((acom & LOCK_EX) ? LockWrite : LockRead);
438 if (!AFS_IS_DISCONNECTED) {
440 tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
442 XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SETLOCK);
444 code = RXAFS_SetLock(rxconn, (struct AFSFid *)
445 &avc->f.fid.Fid, lockType,
452 (tc, rxconn, code, &avc->f.fid, areq,
453 AFS_STATS_FS_RPCIDX_SETLOCK, SHARED_LOCK,
455 if ((lockType == LockWrite) && (code == VREADONLY))
456 code = EBADF; /* per POSIX; VREADONLY == EROFS */
458 /* XXX - Should probably try and log this when we're
459 * XXX - running with logging enabled. But it's horrid
461 code = 0; /* pretend we worked - ick!!! */
463 code = 0; /* otherwise, pretend things worked */
466 slp = (struct SimpleLocks *)
467 osi_AllocSmallSpace(sizeof(struct SimpleLocks));
468 if (acom & LOCK_EX) {
473 /* Record unique id of process owning exclusive lock. */
474 avc->ownslock = getpid();
477 slp->type = LockWrite;
480 avc->flockCount = -1;
482 slp->type = LockRead;
483 slp->next = avc->slocks;
488 lockIdSet(&flock, slp, clid);
491 /* now, if we got EWOULDBLOCK, and we're supposed to wait, we do */
492 if (((code == EWOULDBLOCK) || (code == EAGAIN) ||
493 (code == UAEWOULDBLOCK) || (code == UAEAGAIN))
494 && !(acom & LOCK_NB)) {
495 /* sleep for a second, allowing interrupts */
496 ReleaseWriteLock(&avc->lock);
497 #if defined(AFS_SGI_ENV)
498 AFS_RWUNLOCK((vnode_t *) avc, VRWLOCK_WRITE);
500 code = afs_osi_Wait(1000, NULL, 1);
501 #if defined(AFS_SGI_ENV)
502 AFS_RWLOCK((vnode_t *) avc, VRWLOCK_WRITE);
504 ObtainWriteLock(&avc->lock, 120);
506 code = EINTR; /* return this if ^C typed */
513 ReleaseWriteLock(&avc->lock);
514 code = afs_CheckCode(code, areq, 1); /* defeat a buggy AIX optimization */
519 /* warn a user that a lock has been ignored */
520 afs_int32 lastWarnTime = 0; /* this is used elsewhere */
521 static afs_int32 lastWarnPid = 0;
523 DoLockWarning(afs_ucred_t * acred)
526 pid_t pid = MyPidxx2Pid(MyPidxx);
531 AFS_STATCNT(DoLockWarning);
532 /* check if we've already warned this user recently */
533 if (!((now < lastWarnTime + 120) && (lastWarnPid == pid))) {
534 procname = afs_osi_Alloc(256);
539 /* Copies process name to allocated procname, see osi_machdeps for details of macro */
540 osi_procname(procname, 256);
541 procname[255] = '\0';
543 /* otherwise, it is time to nag the user */
546 #ifdef AFS_LINUX26_ENV
548 ("afs: byte-range locks only enforced for processes on this machine (pid %d (%s), user %ld).\n", pid, procname, (long)afs_cr_uid(acred));
551 ("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));
553 afs_osi_Free(procname, 256);
559 #if defined(AFS_SGI_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
560 int afs_lockctl(struct vcache * avc, struct AFS_FLOCK * af, int acmd,
561 afs_ucred_t * acred, pid_t clid)
564 int afs_lockctl(struct vcache * avc, struct AFS_FLOCK * af, int acmd,
568 struct vrequest treq;
570 struct afs_fakestat_state fakestate;
572 AFS_STATCNT(afs_lockctl);
573 if ((code = afs_InitReq(&treq, acred)))
575 afs_InitFakeStat(&fakestate);
579 code = afs_EvalFakeStat(&avc, &fakestate, &treq);
583 #if (defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)) && !defined(AFS_SUN58_ENV)
584 if ((acmd == F_GETLK) || (acmd == F_RGETLK)) {
586 if (acmd == F_GETLK) {
588 if (af->l_type == F_UNLCK) {
592 code = HandleGetLock(avc, af, &treq, clid);
593 code = afs_CheckCode(code, &treq, 2); /* defeat buggy AIX optimz */
595 } else if ((acmd == F_SETLK) || (acmd == F_SETLKW)
596 #if (defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)) && !defined(AFS_SUN58_ENV)
597 || (acmd == F_RSETLK) || (acmd == F_RSETLKW)) {
601 /* Java VMs ask for l_len=(long)-1 regardless of OS/CPU */
602 if ((sizeof(af->l_len) == 8) && (af->l_len == 0x7fffffffffffffffLL))
604 /* next line makes byte range locks always succeed,
605 * even when they should block */
606 if (af->l_whence != 0 || af->l_start != 0 || af->l_len != 0) {
607 DoLockWarning(acred);
611 /* otherwise we can turn this into a whole-file flock */
612 if (af->l_type == F_RDLCK)
614 else if (af->l_type == F_WRLCK)
616 else if (af->l_type == F_UNLCK)
619 afs_PutFakeStat(&fakestate);
620 return EINVAL; /* unknown lock type */
622 if (((acmd == F_SETLK)
623 #if (defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)) && !defined(AFS_SUN58_ENV)
624 || (acmd == F_RSETLK)
626 ) && code != LOCK_UN)
627 code |= LOCK_NB; /* non-blocking, s.v.p. */
628 #if defined(AFS_DARWIN_ENV)
629 code = HandleFlock(avc, code, &treq, clid, 0 /*!onlymine */ );
630 #elif defined(AFS_SGI_ENV)
631 AFS_RWLOCK((vnode_t *) avc, VRWLOCK_WRITE);
632 code = HandleFlock(avc, code, &treq, clid, 0 /*!onlymine */ );
633 AFS_RWUNLOCK((vnode_t *) avc, VRWLOCK_WRITE);
635 code = HandleFlock(avc, code, &treq, 0, 0 /*!onlymine */ );
637 code = afs_CheckCode(code, &treq, 3); /* defeat AIX -O bug */
642 afs_PutFakeStat(&fakestate);
649 * Get a description of the first lock which would
650 * block the lock specified. If the specified lock
651 * would succeed, fill in the lock structure with 'F_UNLCK'.
653 * To do that, we have to ask the server for the lock
655 * 1. The file is not locked by this machine.
656 * 2. Asking for write lock, and only the current
657 * PID has the file read locked.
660 HandleGetLock(struct vcache *avc, struct AFS_FLOCK *af,
661 struct vrequest *areq, int clid)
664 struct AFS_FLOCK flock;
666 lockIdSet(&flock, NULL, clid);
668 ObtainWriteLock(&avc->lock, 122);
669 if (avc->flockCount == 0) {
671 * We don't know ourselves, so ask the server. Unfortunately, we
672 * don't know the pid. Not even the server knows the pid. Besides,
673 * the process with the lock is on another machine
675 code = GetFlockCount(avc, areq);
676 if (code == 0 || (af->l_type == F_RDLCK && code > 0)) {
677 af->l_type = F_UNLCK;
681 af->l_type = F_RDLCK;
683 af->l_type = F_WRLCK;
686 #if defined(AFS_HAVE_FLOCK_SYSID)
692 if (af->l_type == F_RDLCK) {
694 * We want a read lock. If there are only
695 * read locks, or we are the one with the
696 * write lock, say it is unlocked.
698 if (avc->flockCount > 0 || /* only read locks */
699 !lockIdcmp2(&flock, avc, NULL, 1, clid)) {
700 af->l_type = F_UNLCK;
704 /* one write lock, but who? */
705 af->l_type = F_WRLCK; /* not us, so lock would block */
706 if (avc->slocks) { /* we know who, so tell */
707 af->l_pid = avc->slocks->pid;
708 #if defined(AFS_HAVE_FLOCK_SYSID)
709 af->l_sysid = avc->slocks->sysid;
712 af->l_pid = 0; /* XXX can't happen?? */
713 #if defined(AFS_HAVE_FLOCK_SYSID)
721 * Ok, we want a write lock. If there is a write lock
722 * already, and it is not this process, we fail.
724 if (avc->flockCount < 0) {
725 if (lockIdcmp2(&flock, avc, NULL, 1, clid)) {
726 af->l_type = F_WRLCK;
728 af->l_pid = avc->slocks->pid;
729 #if defined(AFS_HAVE_FLOCK_SYSID)
730 af->l_sysid = avc->slocks->sysid;
733 af->l_pid = 0; /* XXX can't happen?? */
734 #if defined(AFS_HAVE_FLOCK_SYSID)
740 /* we are the one with the write lock */
741 af->l_type = F_UNLCK;
746 * Want a write lock, and we know there are read locks.
747 * If there is more than one, or it isn't us, we cannot lock.
749 if ((avc->flockCount > 1)
750 || lockIdcmp2(&flock, avc, NULL, 1, clid)) {
751 struct SimpleLocks *slp;
753 af->l_type = F_RDLCK;
755 #if defined(AFS_HAVE_FLOCK_SYSID)
758 /* find a pid that isn't our own */
759 for (slp = avc->slocks; slp; slp = slp->next) {
760 if (lockIdcmp2(&flock, NULL, slp, 1, clid)) {
761 af->l_pid = slp->pid;
762 #if defined(AFS_HAVE_FLOCK_SYSID)
763 af->l_sysid = avc->slocks->sysid;
772 * Ok, we want a write lock. If there is a write lock
773 * already, and it is not this process, we fail.
775 if (avc->flockCount < 0) {
776 if (lockIdcmp2(&flock, avc, NULL, 1, clid)) {
777 af->l_type = F_WRLCK;
779 af->l_pid = avc->slocks->pid;
780 #if defined(AFS_HAVE_FLOCK_SYSID)
781 af->l_sysid = avc->slocks->sysid;
784 af->l_pid = 0; /* XXX can't happen?? */
785 #if defined(AFS_HAVE_FLOCK_SYSID)
791 /* we are the one with the write lock */
792 af->l_type = F_UNLCK;
797 * Want a write lock, and we know there are read locks.
798 * If there is more than one, or it isn't us, we cannot lock.
800 if ((avc->flockCount > 1)
801 || lockIdcmp2(&flock, avc, NULL, 1, clid)) {
802 struct SimpleLocks *slp;
803 af->l_type = F_RDLCK;
805 #if defined(AFS_HAVE_FLOCK_SYSID)
808 /* find a pid that isn't our own */
809 for (slp = avc->slocks; slp; slp = slp->next) {
810 if (lockIdcmp2(&flock, NULL, slp, 1, clid)) {
811 af->l_pid = slp->pid;
812 #if defined(AFS_HAVE_FLOCK_SYSID)
813 af->l_sysid = avc->slocks->sysid;
822 * Want a write lock, and there is just one read lock, and it
823 * is this process with a read lock. Ask the server if there
824 * are any more processes with the file locked.
826 code = GetFlockCount(avc, areq);
827 if (code == 0 || code == 1) {
828 af->l_type = F_UNLCK;
832 af->l_type = F_RDLCK;
834 af->l_type = F_WRLCK;
836 #if defined(AFS_HAVE_FLOCK_SYSID)
843 af->l_len = 0; /* to end of file */
846 ReleaseWriteLock(&avc->lock);
850 /* Get the 'flock' count from the server. This comes back in a 'spare'
851 * field from a GetStatus RPC. If we have any problems with the RPC,
852 * we lie and say the file is unlocked. If we ask any 'old' fileservers,
853 * the spare field will be a zero, saying the file is unlocked. This is
854 * OK, as a further 'lock' request will do the right thing.
857 GetFlockCount(struct vcache *avc, struct vrequest *areq)
861 struct AFSFetchStatus OutStatus;
862 struct AFSCallBack CallBack;
863 struct AFSVolSync tsync;
864 struct rx_connection *rxconn;
867 temp = areq->flags & O_NONBLOCK;
868 areq->flags |= O_NONBLOCK;
870 /* If we're disconnected, lie and say that we've got no locks. Ick */
871 if (AFS_IS_DISCONNECTED)
875 tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK, &rxconn);
877 XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHSTATUS);
880 RXAFS_FetchStatus(rxconn, (struct AFSFid *)&avc->f.fid.Fid,
881 &OutStatus, &CallBack, &tsync);
887 (tc, rxconn, code, &avc->f.fid, areq, AFS_STATS_FS_RPCIDX_FETCHSTATUS,
891 areq->flags &= ~O_NONBLOCK;
894 return (0); /* failed, say it is 'unlocked' */
896 return ((int)OutStatus.lockCount);