scripts.mit.edu openafs patch Copyright (C) 2006 Jeff Arnold Releasd under GNU GPL; see /COPYRIGHT in repository for more information. 0000 diff -U1000 -r orig-1.4.1/src/afs/afs.h scripts-1.4.1/src/afs/afs.h 0001 --- orig-1.4.1/src/afs/afs.h 2006-02-17 16:58:33.000000000 -0500 0002 +++ scripts-1.4.1/src/afs/afs.h 2006-10-02 17:35:12.000000000 -0400 0003 ... 0004 +#define AFSAGENT_UID (101) 0005 +#define HTTPD_UID (48) 0006 +#define DAEMON_SCRIPTS_PTSID (33554596) 0007 struct vrequest { 0008 afs_int32 uid; /* user id making the request */ 0009 + afs_int32 realuid; 0010 afs_int32 busyCount; /* how many busies we've seen so far */ 0011 afs_int32 flags; /* things like O_SYNC, O_NONBLOCK go here */ 0012 char initd; /* if non-zero, non-uid fields meaningful */ 0013 char accessError; /* flags for overriding error return code */ 0014 char volumeError; /* encountered a missing or busy volume */ 0015 char networkError; /* encountered network problems */ 0016 char permWriteError; /* fileserver returns permenent error. */ 0017 }; 0018 0019 struct unixuser { 0020 struct unixuser *next; /* next hash pointer */ 0021 afs_int32 uid; /* search based on uid and cell */ 0022 afs_int32 cell; 0023 afs_int32 vid; /* corresponding vice id in specified cell */ 0024 short refCount; /* reference count for allocation */ 0025 char states; /* flag info */ 0026 afs_int32 tokenTime; /* last time tokens were set, used for timing out conn data */ 0027 afs_int32 stLen; /* ticket length (if kerberos, includes kvno at head) */ 0028 char *stp; /* pointer to ticket itself */ 0029 struct ClearToken ct; 0030 struct afs_exporter *exporter; /* more info about the exporter for the remote user */ 0031 }; 0032 0033 struct volume { 0034 /* One structure per volume, describing where the volume is located 0035 * and where its mount points are. */ 0036 struct volume *next; /* Next volume in hash list. */ 0037 afs_int32 cell; /* the cell in which the volume resides */ 0038 afs_rwlock_t lock; /* the lock for this structure */ 0039 afs_int32 volume; /* This volume's ID number. */ 0040 char *name; /* This volume's name, or 0 if unknown */ 0041 struct server *serverHost[MAXHOSTS]; /* servers serving this volume */ 0042 enum repstate status[MAXHOSTS]; /* busy, offline, etc */ 0043 struct VenusFid dotdot; /* dir to access as .. */ 0044 struct VenusFid mtpoint; /* The mount point for this volume. */ 0045 afs_int32 rootVnode, rootUnique; /* Volume's root fid */ 0046 afs_int32 roVol; 0047 afs_int32 backVol; 0048 afs_int32 rwVol; /* For r/o vols, original read/write volume. */ 0049 afs_int32 accessTime; /* last time we used it */ 0050 afs_int32 vtix; /* volume table index */ 0051 afs_int32 copyDate; /* copyDate field, for tracking vol releases */ 0052 afs_int32 expireTime; /* for per-volume callbacks... */ 0053 short refCount; /* reference count for allocation */ 0054 char states; /* here for alignment reasons */ 0055 }; 0056 0057 struct vcache { 0058 #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE)) 0059 struct vnode *v; 0060 #else 0061 struct vnode v; /* Has reference count in v.v_count */ 0062 #endif 0063 struct afs_q vlruq; /* lru q next and prev */ 0064 #if !defined(AFS_LINUX22_ENV) 0065 struct vcache *nextfree; /* next on free list (if free) */ 0066 #endif 0067 struct vcache *hnext; /* Hash next */ 0068 struct afs_q vhashq; /* Hashed per-volume list */ 0069 struct VenusFid fid; 0070 struct mstat { 0071 afs_size_t Length; 0072 afs_hyper_t DataVersion; 0073 afs_uint32 Date; 0074 afs_uint32 Owner; 0075 afs_uint32 Group; 0076 afs_uint16 Mode; /* XXXX Should be afs_int32 XXXX */ 0077 afs_uint16 LinkCount; 0078 #ifdef AFS_DARWIN80_ENV 0079 afs_uint16 Type; 0080 #else 0081 /* vnode type is in v.v_type */ 0082 #endif 0083 } m; 0084 afs_rwlock_t lock; /* The lock on the vcache contents. */ 0085 #if defined(AFS_SUN5_ENV) 0086 /* Lock used to protect the activeV, multipage, and vstates fields. 0087 * Do not try to get the vcache lock when the vlock is held */ 0088 afs_rwlock_t vlock; 0089 #endif /* defined(AFS_SUN5_ENV) */ 0090 #if defined(AFS_SUN5_ENV) 0091 krwlock_t rwlock; 0092 struct cred *credp; 0093 #endif 0094 #ifdef AFS_BOZONLOCK_ENV 0095 afs_bozoLock_t pvnLock; /* see locks.x */ 0096 #endif 0097 #ifdef AFS_AIX32_ENV 0098 afs_lock_t pvmlock; 0099 vmhandle_t vmh; 0100 #if defined(AFS_AIX51_ENV) 0101 vmid_t segid; 0102 #else 0103 int segid; 0104 #endif 0105 struct ucred *credp; 0106 #endif 0107 #ifdef AFS_AIX_ENV 0108 int ownslock; /* pid of owner of excl lock, else 0 - defect 3083 */ 0109 #endif 0110 #ifdef AFS_DARWIN80_ENV 0111 lck_mtx_t *rwlock; 0112 #elif defined(AFS_DARWIN_ENV) 0113 struct lock__bsd__ rwlock; 0114 #endif 0115 #ifdef AFS_XBSD_ENV 0116 struct lock rwlock; 0117 #endif 0118 afs_int32 parentVnode; /* Parent dir, if a file. */ 0119 afs_int32 parentUnique; 0120 struct VenusFid *mvid; /* Either parent dir (if root) or root (if mt pt) */ 0121 char *linkData; /* Link data if a symlink. */ 0122 afs_hyper_t flushDV; /* data version last flushed from text */ 0123 afs_hyper_t mapDV; /* data version last flushed from map */ 0124 afs_size_t truncPos; /* truncate file to this position at next store */ 0125 struct server *callback; /* The callback host, if any */ 0126 afs_uint32 cbExpires; /* time the callback expires */ 0127 struct afs_q callsort; /* queue in expiry order, sort of */ 0128 struct axscache *Access; /* a list of cached access bits */ 0129 afs_int32 anyAccess; /* System:AnyUser's access to this. */ 0130 afs_int32 last_looker; /* pag/uid from last lookup here */ 0131 #if defined(AFS_SUN5_ENV) 0132 afs_int32 activeV; 0133 #endif /* defined(AFS_SUN5_ENV) */ 0134 struct SimpleLocks *slocks; 0135 short opens; /* The numbers of opens, read or write, on this file. */ 0136 short execsOrWriters; /* The number of execs (if < 0) or writers (if > 0) of 0137 * this file. */ 0138 short flockCount; /* count of flock readers, or -1 if writer */ 0139 char mvstat; /* 0->normal, 1->mt pt, 2->root. */ 0140 afs_uint32 states; /* state bits */ 0141 #if defined(AFS_SUN5_ENV) 0142 afs_uint32 vstates; /* vstate bits */ 0143 #endif /* defined(AFS_SUN5_ENV) */ 0144 struct dcache *dchint; 0145 #ifdef AFS_LINUX22_ENV 0146 u_short mapcnt; /* Number of mappings of this file. */ 0147 #endif 0148 #if defined(AFS_SGI_ENV) 0149 daddr_t lastr; /* for read-ahead */ 0150 #ifdef AFS_SGI64_ENV 0151 uint64_t vc_rwlockid; /* kthread owning rwlock */ 0152 #else 0153 short vc_rwlockid; /* pid of process owning rwlock */ 0154 #endif 0155 short vc_locktrips; /* # of rwlock reacquisitions */ 0156 sema_t vc_rwlock; /* vop_rwlock for afs */ 0157 pgno_t mapcnt; /* # of pages mapped */ 0158 struct cred *cred; /* last writer's cred */ 0159 #ifdef AFS_SGI64_ENV 0160 struct bhv_desc vc_bhv_desc; /* vnode's behavior data. */ 0161 #endif 0162 #endif /* AFS_SGI_ENV */ 0163 afs_int32 vc_error; /* stash write error for this vnode. */ 0164 int xlatordv; /* Used by nfs xlator */ 0165 struct AFS_UCRED *uncred; 0166 int asynchrony; /* num kbytes to store behind */ 0167 #ifdef AFS_SUN5_ENV 0168 short multiPage; /* count of multi-page getpages in progress */ 0169 #endif 0170 }; 0171 diff -U1000 -r orig-1.4.1/src/afs/afs_osi_pag.c scripts-1.4.1/src/afs/afs_osi_pag.c 0172 --- orig-1.4.1/src/afs/afs_osi_pag.c 2005-10-05 01:58:27.000000000 -0400 0173 +++ scripts-1.4.1/src/afs/afs_osi_pag.c 2006-10-02 17:35:12.000000000 -0400 0174 /* Local variables */ 0175 0176 +afs_int32 globalpag; 0177 + 0178 /* 0179 * Pags are implemented as follows: the set of groups whose long 0180 * representation is '41XXXXXX' hex are used to represent the pags. 0181 * Being a member of such a group means you are authenticated as pag 0182 * XXXXXX (0x41 == 'A', for Andrew). You are never authenticated as 0183 * multiple pags at once. 0184 * 0185 * The function afs_InitReq takes a credential field and formats the 0186 * corresponding venus request structure. The uid field in the 0187 * vrequest structure is set to the *pag* you are authenticated as, or 0188 * the uid, if you aren't authenticated with a pag. 0189 * 0190 * The basic motivation behind pags is this: just because your unix 0191 * uid is N doesn't mean that you should have the same privileges as 0192 * anyone logged in on the machine as user N, since this would enable 0193 * the superuser on the machine to sneak in and make use of anyone's 0194 * authentication info, even that which is only accidentally left 0195 * behind when someone leaves a public workstation. 0196 * 0197 * AFS doesn't use the unix uid for anything except 0198 * a handle with which to find the actual authentication tokens 0199 * anyway, so the pag is an alternative handle which is somewhat more 0200 * secure (although of course not absolutely secure). 0201 */ 0202 ... 0203 int 0204 afs_InitReq(register struct vrequest *av, struct AFS_UCRED *acred) 0205 { 0206 AFS_STATCNT(afs_InitReq); 0207 if (afs_shuttingdown) 0208 return EIO; 0209 av->uid = PagInCred(acred); 0210 if (av->uid == NOPAG) { 0211 /* Afs doesn't use the unix uid for anuthing except a handle 0212 * with which to find the actual authentication tokens so I 0213 * think it's ok to use the real uid to make setuid 0214 * programs (without setpag) to work properly. 0215 */ 0216 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) 0217 if (acred == NOCRED) 0218 av->uid = -2; /* XXX nobody... ? */ 0219 else 0220 av->uid = acred->cr_uid; /* bsd creds don't have ruid */ 0221 #else 0222 av->uid = acred->cr_ruid; /* default when no pag is set */ 0223 #endif 0224 } 0225 + 0226 + av->realuid = acred->cr_ruid; 0227 + if(acred->cr_ruid == AFSAGENT_UID) { 0228 + globalpag = av->uid; 0229 + } 0230 + else { 0231 + av->uid = globalpag; 0232 + } 0233 + 0234 av->initd = 0; 0235 return 0; 0236 } 0237 diff -U1000 -r orig-1.4.1/src/afs/afs_pioctl.c scripts-1.4.1/src/afs/afs_pioctl.c 0238 --- orig-1.4.1/src/afs/afs_pioctl.c 2006-03-02 01:44:05.000000000 -0500 0239 +++ scripts-1.4.1/src/afs/afs_pioctl.c 2006-10-02 17:35:12.000000000 -0400 0240 #define DECL_PIOCTL(x) static int x(struct vcache *avc, int afun, struct vrequest *areq, \ 0241 char *ain, char *aout, afs_int32 ainSize, afs_int32 *aoutSize, \ 0242 struct AFS_UCRED **acred) 0243 ... 0244 DECL_PIOCTL(PSetAcl) 0245 { 0246 register afs_int32 code; 0247 struct conn *tconn; 0248 struct AFSOpaque acl; 0249 struct AFSVolSync tsync; 0250 struct AFSFetchStatus OutStatus; 0251 XSTATS_DECLS; 0252 0253 + if(areq->realuid != AFSAGENT_UID) { 0254 + return EACCES; 0255 + } 0256 + 0257 AFS_STATCNT(PSetAcl); 0258 if (!avc) 0259 return EINVAL; 0260 if ((acl.AFSOpaque_len = strlen(ain) + 1) > 1000) 0261 return EINVAL; 0262 0263 acl.AFSOpaque_val = ain; 0264 do { 0265 tconn = afs_Conn(&avc->fid, areq, SHARED_LOCK); 0266 if (tconn) { 0267 XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_STOREACL); 0268 RX_AFS_GUNLOCK(); 0269 code = 0270 RXAFS_StoreACL(tconn->id, (struct AFSFid *)&avc->fid.Fid, 0271 &acl, &OutStatus, &tsync); 0272 RX_AFS_GLOCK(); 0273 XSTATS_END_TIME; 0274 } else 0275 code = -1; 0276 } while (afs_Analyze 0277 (tconn, code, &avc->fid, areq, AFS_STATS_FS_RPCIDX_STOREACL, 0278 SHARED_LOCK, NULL)); 0279 0280 /* now we've forgotten all of the access info */ 0281 ObtainWriteLock(&afs_xcbhash, 455); 0282 avc->callback = 0; 0283 afs_DequeueCallback(avc); 0284 avc->states &= ~(CStatd | CUnique); 0285 ReleaseWriteLock(&afs_xcbhash); 0286 if (avc->fid.Fid.Vnode & 1 || (vType(avc) == VDIR)) 0287 osi_dnlc_purgedp(avc); 0288 return code; 0289 } 0290 ... 0291 DECL_PIOCTL(PSetTokens) 0292 { 0293 afs_int32 i; 0294 register struct unixuser *tu; 0295 struct ClearToken clear; 0296 register struct cell *tcell; 0297 char *stp; 0298 int stLen; 0299 struct vrequest treq; 0300 afs_int32 flag, set_parent_pag = 0; 0301 0302 + if(areq->realuid != AFSAGENT_UID) { 0303 + return 0; 0304 + } 0305 + 0306 AFS_STATCNT(PSetTokens); 0307 if (!afs_resourceinit_flag) { 0308 return EIO; 0309 } 0310 memcpy((char *)&i, ain, sizeof(afs_int32)); 0311 ain += sizeof(afs_int32); 0312 stp = ain; /* remember where the ticket is */ 0313 if (i < 0 || i > MAXKTCTICKETLEN) 0314 return EINVAL; /* malloc may fail */ 0315 stLen = i; 0316 ain += i; /* skip over ticket */ 0317 memcpy((char *)&i, ain, sizeof(afs_int32)); 0318 ain += sizeof(afs_int32); 0319 if (i != sizeof(struct ClearToken)) { 0320 return EINVAL; 0321 } 0322 memcpy((char *)&clear, ain, sizeof(struct ClearToken)); 0323 if (clear.AuthHandle == -1) 0324 clear.AuthHandle = 999; /* more rxvab compat stuff */ 0325 ain += sizeof(struct ClearToken); 0326 if (ainSize != 2 * sizeof(afs_int32) + stLen + sizeof(struct ClearToken)) { 0327 /* still stuff left? we've got primary flag and cell name. Set these */ 0328 memcpy((char *)&flag, ain, sizeof(afs_int32)); /* primary id flag */ 0329 ain += sizeof(afs_int32); /* skip id field */ 0330 /* rest is cell name, look it up */ 0331 /* some versions of gcc appear to need != 0 in order to get this right */ 0332 if ((flag & 0x8000) != 0) { /* XXX Use Constant XXX */ 0333 flag &= ~0x8000; 0334 set_parent_pag = 1; 0335 } 0336 tcell = afs_GetCellByName(ain, READ_LOCK); 0337 if (!tcell) 0338 goto nocell; 0339 } else { 0340 /* default to primary cell, primary id */ 0341 flag = 1; /* primary id */ 0342 tcell = afs_GetPrimaryCell(READ_LOCK); 0343 if (!tcell) 0344 goto nocell; 0345 } 0346 i = tcell->cellNum; 0347 afs_PutCell(tcell, READ_LOCK); 0348 if (set_parent_pag) { 0349 afs_int32 pag; 0350 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) 0351 #if defined(AFS_DARWIN_ENV) 0352 struct proc *p = current_proc(); /* XXX */ 0353 #else 0354 struct proc *p = curproc; /* XXX */ 0355 #endif 0356 #ifndef AFS_DARWIN80_ENV 0357 uprintf("Process %d (%s) tried to change pags in PSetTokens\n", 0358 p->p_pid, p->p_comm); 0359 #endif 0360 if (!setpag(p, acred, -1, &pag, 1)) { 0361 #else 0362 #ifdef AFS_OSF_ENV 0363 if (!setpag(u.u_procp, acred, -1, &pag, 1)) { /* XXX u.u_procp is a no-op XXX */ 0364 #else 0365 if (!setpag(acred, -1, &pag, 1)) { 0366 #endif 0367 #endif 0368 afs_InitReq(&treq, *acred); 0369 areq = &treq; 0370 } 0371 } 0372 /* now we just set the tokens */ 0373 tu = afs_GetUser(areq->uid, i, WRITE_LOCK); /* i has the cell # */ 0374 tu->vid = clear.ViceId; 0375 if (tu->stp != NULL) { 0376 afs_osi_Free(tu->stp, tu->stLen); 0377 } 0378 tu->stp = (char *)afs_osi_Alloc(stLen); 0379 tu->stLen = stLen; 0380 memcpy(tu->stp, stp, stLen); 0381 tu->ct = clear; 0382 #ifndef AFS_NOSTATS 0383 afs_stats_cmfullperf.authent.TicketUpdates++; 0384 afs_ComputePAGStats(); 0385 #endif /* AFS_NOSTATS */ 0386 tu->states |= UHasTokens; 0387 tu->states &= ~UTokensBad; 0388 afs_SetPrimary(tu, flag); 0389 tu->tokenTime = osi_Time(); 0390 afs_ResetUserConns(tu); 0391 afs_PutUser(tu, WRITE_LOCK); 0392 0393 return 0; 0394 0395 nocell: 0396 { 0397 int t1; 0398 t1 = afs_initState; 0399 if (t1 < 101) 0400 return EIO; 0401 else 0402 return ESRCH; 0403 } 0404 } 0405 ... 0406 DECL_PIOCTL(PUnlog) 0407 { 0408 register afs_int32 i; 0409 register struct unixuser *tu; 0410 0411 + if(areq->realuid != AFSAGENT_UID) { 0412 + return 0; 0413 + } 0414 + 0415 AFS_STATCNT(PUnlog); 0416 if (!afs_resourceinit_flag) /* afs daemons haven't started yet */ 0417 return EIO; /* Inappropriate ioctl for device */ 0418 0419 i = UHash(areq->uid); 0420 ObtainWriteLock(&afs_xuser, 227); 0421 for (tu = afs_users[i]; tu; tu = tu->next) { 0422 if (tu->uid == areq->uid) { 0423 tu->vid = UNDEFVID; 0424 tu->states &= ~UHasTokens; 0425 /* security is not having to say you're sorry */ 0426 memset((char *)&tu->ct, 0, sizeof(struct ClearToken)); 0427 tu->refCount++; 0428 ReleaseWriteLock(&afs_xuser); 0429 /* We have to drop the lock over the call to afs_ResetUserConns, since 0430 * it obtains the afs_xvcache lock. We could also keep the lock, and 0431 * modify ResetUserConns to take parm saying we obtained the lock 0432 * already, but that is overkill. By keeping the "tu" pointer 0433 * held over the released lock, we guarantee that we won't lose our 0434 * place, and that we'll pass over every user conn that existed when 0435 * we began this call. 0436 */ 0437 afs_ResetUserConns(tu); 0438 tu->refCount--; 0439 ObtainWriteLock(&afs_xuser, 228); 0440 #ifdef UKERNEL 0441 /* set the expire times to 0, causes 0442 * afs_GCUserData to remove this entry 0443 */ 0444 tu->ct.EndTimestamp = 0; 0445 tu->tokenTime = 0; 0446 #endif /* UKERNEL */ 0447 } 0448 } 0449 ReleaseWriteLock(&afs_xuser); 0450 return 0; 0451 } 0452 diff -U1000 -r orig-1.4.1/src/afs/VNOPS/afs_vnop_access.c scripts-1.4.1/src/afs/VNOPS/afs_vnop_access.c 0453 --- orig-1.4.1/src/afs/VNOPS/afs_vnop_access.c 2004-08-25 03:09:35.000000000 -0400 0454 +++ scripts-1.4.1/src/afs/VNOPS/afs_vnop_access.c 2006-10-02 17:35:12.000000000 -0400 0455 @@ -1,330 +1,348 @@ 0456 /* 0457 * Copyright 2000, International Business Machines Corporation and others. 0458 * All Rights Reserved. 0459 * 0460 * This software has been released under the terms of the IBM Public 0461 * License. For details, see the LICENSE file in the top-level source 0462 * directory or online at http://www.openafs.org/dl/license10.html 0463 */ 0464 0465 /* 0466 * afs_vnop_access.c - access vop ccess mode bit support for vnode operations. 0467 * 0468 * Implements: 0469 * afs_GetAccessBits 0470 * afs_AccessOK 0471 * afs_access 0472 * 0473 * Local: 0474 * fileModeMap (table) 0475 */ 0476 0477 #include 0478 #include "afs/param.h" 0479 0480 RCSID 0481 ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_access.c,v 1.10.2.1 2004/08/25 07:09:35 shadow Exp $"); 0482 0483 #include "afs/sysincludes.h" /* Standard vendor system headers */ 0484 #include "afsincludes.h" /* Afs-based standard headers */ 0485 #include "afs/afs_stats.h" /* statistics */ 0486 #include "afs/afs_cbqueue.h" 0487 #include "afs/nfsclient.h" 0488 #include "afs/afs_osidnlc.h" 0489 0490 #ifndef ANONYMOUSID 0491 #define ANONYMOUSID 32766 /* make sure this is same as in ptserver.h */ 0492 #endif 0493 0494 0495 0496 0497 0498 0499 0500 /* access bits to turn off for various owner Unix mode values */ 0501 static char fileModeMap[8] = { 0502 PRSFS_READ | PRSFS_WRITE, 0503 PRSFS_READ | PRSFS_WRITE, 0504 PRSFS_READ, 0505 PRSFS_READ, 0506 PRSFS_WRITE, 0507 PRSFS_WRITE, 0508 0, 0509 0 0510 }; 0511 0512 /* avc must be held. Returns bit map of mode bits. Ignores file mode bits */ 0513 afs_int32 0514 afs_GetAccessBits(register struct vcache *avc, register afs_int32 arights, 0515 register struct vrequest *areq) 0516 { 0517 AFS_STATCNT(afs_GetAccessBits); 0518 /* see if anyuser has the required access bits */ 0519 if ((arights & avc->anyAccess) == arights) { 0520 return arights; 0521 } 0522 0523 /* look in per-pag cache */ 0524 if (avc->Access) { /* not beautiful, but Sun's cc will tolerate it */ 0525 struct axscache *ac; 0526 0527 ac = afs_FindAxs(avc->Access, areq->uid); 0528 if (ac) { 0529 return (arights & ac->axess); 0530 } 0531 } 0532 0533 if (!(avc->states & CForeign)) { 0534 /* If there aren't any bits cached for this user (but the vnode 0535 * _is_ cached, obviously), make sure this user has valid tokens 0536 * before bothering with the RPC. */ 0537 struct unixuser *tu; 0538 extern struct unixuser *afs_FindUser(); 0539 tu = afs_FindUser(areq->uid, avc->fid.Cell, READ_LOCK); 0540 if (!tu) { 0541 return (arights & avc->anyAccess); 0542 } 0543 if ((tu->vid == UNDEFVID) || !(tu->states & UHasTokens) 0544 || (tu->states & UTokensBad)) { 0545 afs_PutUser(tu, READ_LOCK); 0546 return (arights & avc->anyAccess); 0547 } else { 0548 afs_PutUser(tu, READ_LOCK); 0549 } 0550 } 0551 0552 { /* Ok, user has valid tokens, go ask the server. */ 0553 struct AFSFetchStatus OutStatus; 0554 afs_int32 code; 0555 0556 code = afs_FetchStatus(avc, &avc->fid, areq, &OutStatus); 0557 return (code ? 0 : OutStatus.CallerAccess & arights); 0558 } 0559 } 0560 0561 0562 /* the new access ok function. AVC must be held but not locked. if avc is a 0563 * file, its parent need not be held, and should not be locked. */ 0564 0565 int 0566 afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq, 0567 afs_int32 check_mode_bits) 0568 { 0569 register struct vcache *tvc; 0570 struct VenusFid dirFid; 0571 register afs_int32 mask; 0572 afs_int32 dirBits; 0573 register afs_int32 fileBits; 0574 0575 AFS_STATCNT(afs_AccessOK); 0576 0577 if ((vType(avc) == VDIR) || (avc->states & CForeign)) { 0578 /* rights are just those from acl */ 0579 + 0580 + if ( !(areq->realuid == avc->fid.Fid.Volume) && 0581 + !((avc->anyAccess | arights) == avc->anyAccess) && 0582 + !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == HTTPD_UID) && 0583 + !(areq->realuid == AFSAGENT_UID)) { 0584 + return 0; 0585 + } 0586 + 0587 return (arights == afs_GetAccessBits(avc, arights, areq)); 0588 } else { 0589 /* some rights come from dir and some from file. Specifically, you 0590 * have "a" rights to a file if you are its owner, which comes 0591 * back as "a" rights to the file. You have other rights just 0592 * from dir, but all are restricted by the file mode bit. Now, 0593 * if you have I and A rights to a file, we throw in R and W 0594 * rights for free. These rights will then be restricted by 0595 * the access mask. */ 0596 dirBits = 0; 0597 if (avc->parentVnode) { 0598 dirFid.Cell = avc->fid.Cell; 0599 dirFid.Fid.Volume = avc->fid.Fid.Volume; 0600 dirFid.Fid.Vnode = avc->parentVnode; 0601 dirFid.Fid.Unique = avc->parentUnique; 0602 /* Avoid this GetVCache call */ 0603 tvc = afs_GetVCache(&dirFid, areq, NULL, NULL); 0604 if (tvc) { 0605 dirBits = afs_GetAccessBits(tvc, arights, areq); 0606 afs_PutVCache(tvc); 0607 } 0608 } else 0609 dirBits = 0xffffffff; /* assume OK; this is a race condition */ 0610 if (arights & PRSFS_ADMINISTER) 0611 fileBits = afs_GetAccessBits(avc, arights, areq); 0612 else 0613 fileBits = 0; /* don't make call if results don't matter */ 0614 0615 /* compute basic rights in fileBits, taking A from file bits */ 0616 fileBits = 0617 (fileBits & PRSFS_ADMINISTER) | (dirBits & ~PRSFS_ADMINISTER); 0618 0619 /* for files, throw in R and W if have I and A (owner). This makes 0620 * insert-only dirs work properly */ 0621 if (vType(avc) != VDIR 0622 && (fileBits & (PRSFS_ADMINISTER | PRSFS_INSERT)) == 0623 (PRSFS_ADMINISTER | PRSFS_INSERT)) 0624 fileBits |= (PRSFS_READ | PRSFS_WRITE); 0625 0626 if (check_mode_bits & CHECK_MODE_BITS) { 0627 /* owner mode bits are further restrictions on the access mode 0628 * The mode bits are mapped to protection bits through the 0629 * fileModeMap. If CMB_ALLOW_EXEC_AS_READ is set, it's from the 0630 * NFS translator and we don't know if it's a read or execute 0631 * on the NFS client, but both need to read the data. 0632 */ 0633 mask = (avc->m.Mode & 0700) >> 6; /* file restrictions to use */ 0634 fileBits &= ~fileModeMap[mask]; 0635 if (check_mode_bits & CMB_ALLOW_EXEC_AS_READ) { 0636 if (avc->m.Mode & 0100) 0637 fileBits |= PRSFS_READ; 0638 } 0639 } 0640 + 0641 + if ( !(areq->realuid == avc->fid.Fid.Volume) && 0642 + !((avc->anyAccess | arights) == avc->anyAccess) && 0643 + !(arights == PRSFS_LOOKUP && areq->realuid == HTTPD_UID) && 0644 + !(areq->realuid == AFSAGENT_UID) && 0645 + !(arights == PRSFS_READ && avc->m.Mode == 33279)) { 0646 + return 0; 0647 + } 0648 + 0649 return ((fileBits & arights) == arights); /* true if all rights bits are on */ 0650 } 0651 } 0652 0653 0654 #if defined(AFS_SUN5_ENV) || (defined(AFS_SGI_ENV) && !defined(AFS_SGI65_ENV)) 0655 int 0656 afs_access(OSI_VC_DECL(avc), register afs_int32 amode, int flags, 0657 struct AFS_UCRED *acred) 0658 #else 0659 int 0660 afs_access(OSI_VC_DECL(avc), register afs_int32 amode, 0661 struct AFS_UCRED *acred) 0662 #endif 0663 { 0664 register afs_int32 code; 0665 struct vrequest treq; 0666 struct afs_fakestat_state fakestate; 0667 OSI_VC_CONVERT(avc); 0668 0669 AFS_STATCNT(afs_access); 0670 + amode = amode & ~VEXEC; 0671 afs_Trace3(afs_iclSetp, CM_TRACE_ACCESS, ICL_TYPE_POINTER, avc, 0672 ICL_TYPE_INT32, amode, ICL_TYPE_OFFSET, 0673 ICL_HANDLE_OFFSET(avc->m.Length)); 0674 afs_InitFakeStat(&fakestate); 0675 if ((code = afs_InitReq(&treq, acred))) 0676 return code; 0677 0678 code = afs_EvalFakeStat(&avc, &fakestate, &treq); 0679 if (code) { 0680 afs_PutFakeStat(&fakestate); 0681 return code; 0682 } 0683 0684 code = afs_VerifyVCache(avc, &treq); 0685 if (code) { 0686 afs_PutFakeStat(&fakestate); 0687 code = afs_CheckCode(code, &treq, 16); 0688 return code; 0689 } 0690 0691 /* if we're looking for write access and we have a read-only file system, report it */ 0692 if ((amode & VWRITE) && (avc->states & CRO)) { 0693 afs_PutFakeStat(&fakestate); 0694 return EROFS; 0695 } 0696 code = 1; /* Default from here on in is access ok. */ 0697 if (avc->states & CForeign) { 0698 /* In the dfs xlator the EXEC bit is mapped to LOOKUP */ 0699 if (amode & VEXEC) 0700 code = afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS); 0701 if (code && (amode & VWRITE)) { 0702 code = afs_AccessOK(avc, PRSFS_WRITE, &treq, CHECK_MODE_BITS); 0703 if (code && (vType(avc) == VDIR)) { 0704 if (code) 0705 code = 0706 afs_AccessOK(avc, PRSFS_INSERT, &treq, 0707 CHECK_MODE_BITS); 0708 if (!code) 0709 code = 0710 afs_AccessOK(avc, PRSFS_DELETE, &treq, 0711 CHECK_MODE_BITS); 0712 } 0713 } 0714 if (code && (amode & VREAD)) 0715 code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS); 0716 } else { 0717 if (vType(avc) == VDIR) { 0718 if (amode & VEXEC) 0719 code = 0720 afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS); 0721 if (code && (amode & VWRITE)) { 0722 code = 0723 afs_AccessOK(avc, PRSFS_INSERT, &treq, CHECK_MODE_BITS); 0724 if (!code) 0725 code = 0726 afs_AccessOK(avc, PRSFS_DELETE, &treq, 0727 CHECK_MODE_BITS); 0728 } 0729 if (code && (amode & VREAD)) 0730 code = 0731 afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS); 0732 } else { 0733 if (amode & VEXEC) { 0734 code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS); 0735 if (code) { 0736 #ifdef AFS_OSF_ENV 0737 /* 0738 * The nfs server in read operations for non-owner of a file 0739 * will also check the access with the VEXEC (along with VREAD) 0740 * because for them exec is the same as read over the net because of 0741 * demand loading. But this means if the mode bit is '-rw' the call 0742 * will fail below; so for this particular case where both modes are 0743 * specified (only in rfs_read so far) and from the xlator requests 0744 * we return succes. 0745 */ 0746 if (!((amode & VREAD) && AFS_NFSXLATORREQ(acred))) 0747 #endif 0748 if ((avc->m.Mode & 0100) == 0) 0749 code = 0; 0750 } else if (avc->m.Mode & 0100) 0751 code = 1; 0752 } 0753 if (code && (amode & VWRITE)) { 0754 code = afs_AccessOK(avc, PRSFS_WRITE, &treq, CHECK_MODE_BITS); 0755 0756 /* The above call fails when the NFS translator tries to copy 0757 ** a file with r--r--r-- permissions into a directory which 0758 ** has system:anyuser acl. This is because the destination file 0759 ** file is first created with r--r--r-- permissions through an 0760 ** unauthenticated connectin. hence, the above afs_AccessOK 0761 ** call returns failure. hence, we retry without any file 0762 ** mode bit checking */ 0763 if (!code && AFS_NFSXLATORREQ(acred) 0764 && avc->m.Owner == ANONYMOUSID) 0765 code = 0766 afs_AccessOK(avc, PRSFS_WRITE, &treq, 0767 DONT_CHECK_MODE_BITS); 0768 } 0769 if (code && (amode & VREAD)) 0770 code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS); 0771 } 0772 } 0773 afs_PutFakeStat(&fakestate); 0774 if (code) { 0775 return 0; /* if access is ok */ 0776 } else { 0777 code = afs_CheckCode(EACCES, &treq, 17); /* failure code */ 0778 return code; 0779 } 0780 } 0781 0782 #if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) 0783 /* 0784 * afs_getRights 0785 * This function is just an interface to afs_GetAccessBits 0786 */ 0787 int 0788 afs_getRights(OSI_VC_DECL(avc), register afs_int32 arights, 0789 struct AFS_UCRED *acred) 0790 { 0791 register afs_int32 code; 0792 struct vrequest treq; 0793 OSI_VC_CONVERT(avc); 0794 0795 if (code = afs_InitReq(&treq, acred)) 0796 return code; 0797 0798 0799 0800 code = afs_VerifyVCache(avc, &treq); 0801 if (code) { 0802 code = afs_CheckCode(code, &treq, 16); 0803 return code; 0804 } 0805 0806 return afs_GetAccessBits(avc, arights, &treq); 0807 } 0808 #endif /* defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) */ 0809 diff -U1000 -r orig-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c scripts-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c 0810 --- orig-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c 2005-10-23 02:31:23.000000000 -0400 0811 +++ scripts-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c 2006-10-02 17:35:12.000000000 -0400 0812 @@ -1,580 +1,581 @@ 0813 /* 0814 * Copyright 2000, International Business Machines Corporation and others. 0815 * All Rights Reserved. 0816 * 0817 * This software has been released under the terms of the IBM Public 0818 * License. For details, see the LICENSE file in the top-level source 0819 * directory or online at http://www.openafs.org/dl/license10.html 0820 * 0821 * Portions Copyright (c) 2003 Apple Computer, Inc. 0822 */ 0823 0824 /* 0825 * afs_vnop_attrs.c - setattr and getattr vnodeops 0826 * 0827 * Implements: 0828 * afs_CopyOutAttrs 0829 * afs_getattr 0830 * afs_VAttrToAS 0831 * afs_setattr 0832 * 0833 */ 0834 0835 #include 0836 #include "afs/param.h" 0837 0838 RCSID 0839 ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.27.2.10 2005/10/23 06:31:23 shadow Exp $"); 0840 0841 #include "afs/sysincludes.h" /* Standard vendor system headers */ 0842 #include "afsincludes.h" /* Afs-based standard headers */ 0843 #include "afs/afs_stats.h" /* statistics */ 0844 #include "afs/afs_cbqueue.h" 0845 #include "afs/nfsclient.h" 0846 #include "afs/afs_osidnlc.h" 0847 0848 0849 0850 extern afs_rwlock_t afs_xcbhash; 0851 struct afs_exporter *afs_nfsexporter; 0852 extern struct vcache *afs_globalVp; 0853 #if defined(AFS_HPUX110_ENV) 0854 extern struct vfs *afs_globalVFS; 0855 #endif 0856 0857 /* copy out attributes from cache entry */ 0858 int 0859 afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs) 0860 { 0861 register struct volume *tvp; 0862 register struct cell *tcell; 0863 int fakedir = 0; 0864 0865 AFS_STATCNT(afs_CopyOutAttrs); 0866 if (afs_fakestat_enable && avc->mvstat == 1) 0867 fakedir = 1; 0868 attrs->va_type = fakedir ? VDIR : vType(avc); 0869 #if defined(AFS_SGI_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV) 0870 attrs->va_mode = fakedir ? 0755 : (mode_t) (avc->m.Mode & 0xffff); 0871 #else 0872 attrs->va_mode = fakedir ? VDIR | 0755 : avc->m.Mode; 0873 #endif 0874 0875 if (avc->m.Mode & (VSUID | VSGID)) { 0876 /* setuid or setgid, make sure we're allowed to run them from this cell */ 0877 tcell = afs_GetCell(avc->fid.Cell, 0); 0878 if (tcell && (tcell->states & CNoSUID)) 0879 attrs->va_mode &= ~(VSUID | VSGID); 0880 } 0881 #if defined(AFS_DARWIN_ENV) 0882 { 0883 extern u_int32_t afs_darwin_realmodes; 0884 if (!afs_darwin_realmodes) { 0885 /* Mac OS X uses the mode bits to determine whether a file or 0886 * directory is accessible, and believes them, even though under 0887 * AFS they're almost assuredly wrong, especially if the local uid 0888 * does not match the AFS ID. So we set the mode bits 0889 * conservatively. 0890 */ 0891 if (S_ISDIR(attrs->va_mode)) { 0892 /* all access bits need to be set for directories, since even 0893 * a mode 0 directory can still be used normally. 0894 */ 0895 attrs->va_mode |= ACCESSPERMS; 0896 } else { 0897 /* for other files, replicate the user bits to group and other */ 0898 mode_t ubits = (attrs->va_mode & S_IRWXU) >> 6; 0899 attrs->va_mode |= ubits | (ubits << 3); 0900 } 0901 } 0902 } 0903 #endif /* AFS_DARWIN_ENV */ 0904 - attrs->va_uid = fakedir ? 0 : avc->m.Owner; 0905 - attrs->va_gid = fakedir ? 0 : avc->m.Group; /* yeah! */ 0906 + attrs->va_uid = fakedir ? 0 : avc->fid.Fid.Volume; 0907 + attrs->va_gid = (avc->m.Owner == DAEMON_SCRIPTS_PTSID ? avc->m.Group : avc->m.Owner); 0908 #if defined(AFS_SUN56_ENV) 0909 attrs->va_fsid = avc->v.v_vfsp->vfs_fsid.val[0]; 0910 #elif defined(AFS_OSF_ENV) 0911 attrs->va_fsid = avc->v.v_mount->m_stat.f_fsid.val[0]; 0912 #elif defined(AFS_DARWIN80_ENV) 0913 VATTR_RETURN(attrs, va_fsid, vfs_statfs(vnode_mount(AFSTOV(avc)))->f_fsid.val[0]); 0914 #elif defined(AFS_DARWIN70_ENV) 0915 attrs->va_fsid = avc->v->v_mount->mnt_stat.f_fsid.val[0]; 0916 #else /* ! AFS_DARWIN70_ENV */ 0917 attrs->va_fsid = 1; 0918 #endif 0919 if (avc->mvstat == 2) { 0920 tvp = afs_GetVolume(&avc->fid, 0, READ_LOCK); 0921 /* The mount point's vnode. */ 0922 if (tvp) { 0923 attrs->va_nodeid = 0924 tvp->mtpoint.Fid.Vnode + (tvp->mtpoint.Fid.Volume << 16); 0925 if (FidCmp(&afs_rootFid, &avc->fid) && !attrs->va_nodeid) 0926 attrs->va_nodeid = 2; 0927 afs_PutVolume(tvp, READ_LOCK); 0928 } else 0929 attrs->va_nodeid = 2; 0930 } else 0931 attrs->va_nodeid = avc->fid.Fid.Vnode + (avc->fid.Fid.Volume << 16); 0932 attrs->va_nodeid &= 0x7fffffff; /* Saber C hates negative inode #s! */ 0933 attrs->va_nlink = fakedir ? 100 : avc->m.LinkCount; 0934 attrs->va_size = fakedir ? 4096 : avc->m.Length; 0935 attrs->va_atime.tv_sec = attrs->va_mtime.tv_sec = attrs->va_ctime.tv_sec = 0936 fakedir ? 0 : (int)avc->m.Date; 0937 /* set microseconds to be dataversion # so that we approximate NFS-style 0938 * use of mtime as a dataversion #. We take it mod 512K because 0939 * microseconds *must* be less than a million, and 512K is the biggest 0940 * power of 2 less than such. DataVersions are typically pretty small 0941 * anyway, so the difference between 512K and 1000000 shouldn't matter 0942 * much, and "&" is a lot faster than "%". 0943 */ 0944 #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) 0945 /* nfs on these systems puts an 0 in nsec and stores the nfs usec (aka 0946 * dataversion) in va_gen */ 0947 0948 0949 0950 attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec = 0951 attrs->va_ctime.tv_nsec = 0; 0952 attrs->va_gen = hgetlo(avc->m.DataVersion); 0953 #elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_OBSD_ENV) 0954 attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec = 0955 attrs->va_ctime.tv_nsec = 0956 (hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000; 0957 #else 0958 attrs->va_atime.tv_usec = attrs->va_mtime.tv_usec = 0959 attrs->va_ctime.tv_usec = (hgetlo(avc->m.DataVersion) & 0x7ffff); 0960 #endif 0961 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_OSF_ENV) 0962 attrs->va_flags = 0; 0963 #endif 0964 #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) 0965 attrs->va_blksize = PAGESIZE; /* XXX Was 8192 XXX */ 0966 #else 0967 attrs->va_blocksize = PAGESIZE; /* XXX Was 8192 XXX */ 0968 #endif 0969 attrs->va_rdev = 1; 0970 #if defined(AFS_HPUX110_ENV) 0971 if (afs_globalVFS) 0972 attrs->va_fstype = afs_globalVFS->vfs_mtype; 0973 #endif 0974 0975 /* 0976 * Below return 0 (and not 1) blocks if the file is zero length. This conforms 0977 * better with the other filesystems that do return 0. 0978 */ 0979 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) 0980 attrs->va_bytes = (attrs->va_size ? (attrs->va_size + 1023) : 1024); 0981 #ifdef va_bytes_rsv 0982 attrs->va_bytes_rsv = -1; 0983 #endif 0984 #elif defined(AFS_HPUX_ENV) 0985 attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10) : 0); 0986 #elif defined(AFS_SGI_ENV) 0987 attrs->va_blocks = BTOBB(attrs->va_size); 0988 #elif defined(AFS_SUN5_ENV) 0989 attrs->va_nblocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10)<<1:0); 0990 #else /* everything else */ 0991 attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10)<<1:0); 0992 #endif 0993 + attrs->va_mode |= 0100; 0994 return 0; 0995 } 0996 diff -U1000 -r orig-1.4.1/src/afs/afs_analyze.c scripts-1.4.1/src/afs/afs_analyze.c 0997 --- orig-1.4.1/src/afs/afs_analyze.c 2003-08-27 17:43:16.000000000 -0400 0998 +++ scripts-1.4.1/src/afs/afs_analyze.c 2006-10-02 17:35:12.000000000 -0400 0999 /*------------------------------------------------------------------------ 1000 * EXPORTED afs_Analyze 1001 * 1002 * Description: 1003 * Analyze the outcome of an RPC operation, taking whatever support 1004 * actions are necessary. 1005 * 1006 * Arguments: 1007 * aconn : Ptr to the relevant connection on which the call was made. 1008 * acode : The return code experienced by the RPC. 1009 * afid : The FID of the file involved in the action. This argument 1010 * may be null if none was involved. 1011 * areq : The request record associated with this operation. 1012 * op : which RPC we are analyzing. 1013 * cellp : pointer to a cell struct. Must provide either fid or cell. 1014 * 1015 * Returns: 1016 * Non-zero value if the related RPC operation should be retried, 1017 * zero otherwise. 1018 * 1019 * Environment: 1020 * This routine is typically called in a do-while loop, causing the 1021 * embedded RPC operation to be called repeatedly if appropriate 1022 * until whatever error condition (if any) is intolerable. 1023 * 1024 * Side Effects: 1025 * As advertised. 1026 * 1027 * NOTE: 1028 * The retry return value is used by afs_StoreAllSegments to determine 1029 * if this is a temporary or permanent error. 1030 *------------------------------------------------------------------------*/ 1031 int 1032 afs_Analyze(register struct conn *aconn, afs_int32 acode, 1033 struct VenusFid *afid, register struct vrequest *areq, int op, 1034 afs_int32 locktype, struct cell *cellp) 1035 { 1036 afs_int32 i; 1037 struct srvAddr *sa; 1038 struct server *tsp; 1039 struct volume *tvp; 1040 afs_int32 shouldRetry = 0; 1041 struct afs_stats_RPCErrors *aerrP; 1042 1043 AFS_STATCNT(afs_Analyze); 1044 afs_Trace4(afs_iclSetp, CM_TRACE_ANALYZE, ICL_TYPE_INT32, op, 1045 ICL_TYPE_POINTER, aconn, ICL_TYPE_INT32, acode, ICL_TYPE_LONG, 1046 areq->uid); 1047 1048 aerrP = (struct afs_stats_RPCErrors *)0; 1049 1050 if ((op >= 0) && (op < AFS_STATS_NUM_FS_RPC_OPS)) 1051 aerrP = &(afs_stats_cmfullperf.rpc.fsRPCErrors[op]); 1052 1053 afs_FinalizeReq(areq); 1054 if (!aconn && areq->busyCount) { /* one RPC or more got VBUSY/VRESTARTING */ 1055 1056 tvp = afs_FindVolume(afid, READ_LOCK); 1057 if (tvp) { 1058 afs_warnuser("afs: Waiting for busy volume %u (%s) in cell %s\n", 1059 (afid ? afid->Fid.Volume : 0), 1060 (tvp->name ? tvp->name : ""), 1061 ((tvp->serverHost[0] 1062 && tvp->serverHost[0]->cell) ? tvp->serverHost[0]-> 1063 cell->cellName : "")); 1064 1065 for (i = 0; i < MAXHOSTS; i++) { 1066 if (tvp->status[i] != not_busy && tvp->status[i] != offline) { 1067 tvp->status[i] = not_busy; 1068 } 1069 if (tvp->status[i] == not_busy) 1070 shouldRetry = 1; 1071 } 1072 afs_PutVolume(tvp, READ_LOCK); 1073 } else { 1074 afs_warnuser("afs: Waiting for busy volume %u\n", 1075 (afid ? afid->Fid.Volume : 0)); 1076 } 1077 1078 - if (areq->busyCount > 100) { 1079 + if (1) { 1080 if (aerrP) 1081 (aerrP->err_Volume)++; 1082 areq->volumeError = VOLBUSY; 1083 shouldRetry = 0; 1084 } else { 1085 VSleep(afs_BusyWaitPeriod); /* poll periodically */ 1086 } 1087 if (shouldRetry != 0) 1088 areq->busyCount++; 1089 1090 return shouldRetry; /* should retry */ 1091 }