source: server/doc/cluedump/openafs-diff.num @ 37

Last change on this file since 37 was 37, checked in by jbarnold, 18 years ago
Touched up documentation; moved cluedump info to its own dir
File size: 41.8 KB
Line 
1scripts.mit.edu openafs patch
2Copyright (C) 2006  Jeff Arnold
3Releasd under GNU GPL; see /COPYRIGHT in repository for more information.
4
50000 diff -U1000 -r orig-1.4.1/src/afs/afs.h scripts-1.4.1/src/afs/afs.h
60001 --- orig-1.4.1/src/afs/afs.h       2006-02-17 16:58:33.000000000 -0500
70002 +++ scripts-1.4.1/src/afs/afs.h    2006-10-02 17:35:12.000000000 -0400
80003 ...
90004 +#define AFSAGENT_UID (101)
100005 +#define HTTPD_UID (48)
110006 +#define DAEMON_SCRIPTS_PTSID (33554596)
120007  struct vrequest {
130008      afs_int32 uid;                /* user id making the request */
140009 +    afs_int32 realuid;
150010      afs_int32 busyCount;  /* how many busies we've seen so far */
160011      afs_int32 flags;              /* things like O_SYNC, O_NONBLOCK go here */
170012      char initd;                   /* if non-zero, non-uid fields meaningful */
180013      char accessError;             /* flags for overriding error return code */
190014      char volumeError;             /* encountered a missing or busy volume */
200015      char networkError;            /* encountered network problems */
210016      char permWriteError;  /* fileserver returns permenent error. */
220017  };
230018
240019  struct unixuser {
250020      struct unixuser *next;        /* next hash pointer */
260021      afs_int32 uid;                /* search based on uid and cell */
270022      afs_int32 cell;
280023      afs_int32 vid;                /* corresponding vice id in specified cell */
290024      short refCount;               /* reference count for allocation */
300025      char states;          /* flag info */
310026      afs_int32 tokenTime;  /* last time tokens were set, used for timing out conn data */
320027      afs_int32 stLen;              /* ticket length (if kerberos, includes kvno at head) */
330028      char *stp;                    /* pointer to ticket itself */
340029      struct ClearToken ct;
350030      struct afs_exporter *exporter;        /* more info about the exporter for the remote user */
360031  };
370032
380033  struct volume {
390034      /* One structure per volume, describing where the volume is located
400035       * and where its mount points are. */
410036      struct volume *next;  /* Next volume in hash list. */
420037      afs_int32 cell;               /* the cell in which the volume resides */
430038      afs_rwlock_t lock;            /* the lock for this structure */
440039      afs_int32 volume;             /* This volume's ID number. */
450040      char *name;                   /* This volume's name, or 0 if unknown */
460041      struct server *serverHost[MAXHOSTS];  /* servers serving this volume */
470042      enum repstate status[MAXHOSTS];       /* busy, offline, etc */
480043      struct VenusFid dotdot;       /* dir to access as .. */
490044      struct VenusFid mtpoint;      /* The mount point for this volume. */
500045      afs_int32 rootVnode, rootUnique;      /* Volume's root fid */
510046      afs_int32 roVol;
520047      afs_int32 backVol;
530048      afs_int32 rwVol;              /* For r/o vols, original read/write volume. */
540049      afs_int32 accessTime; /* last time we used it */
550050      afs_int32 vtix;               /* volume table index */
560051      afs_int32 copyDate;           /* copyDate field, for tracking vol releases */
570052      afs_int32 expireTime; /* for per-volume callbacks... */
580053      short refCount;               /* reference count for allocation */
590054      char states;          /* here for alignment reasons */
600055  };
610056
620057  struct vcache {
630058  #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE))
640059      struct vnode *v;
650060  #else
660061      struct vnode v;               /* Has reference count in v.v_count */
670062  #endif
680063      struct afs_q vlruq;           /* lru q next and prev */
690064  #if !defined(AFS_LINUX22_ENV)
700065      struct vcache *nextfree;      /* next on free list (if free) */
710066  #endif
720067      struct vcache *hnext; /* Hash next */
730068      struct afs_q vhashq;  /* Hashed per-volume list */
740069      struct VenusFid fid;
750070      struct mstat {
760071    afs_size_t Length;
770072    afs_hyper_t DataVersion;
780073    afs_uint32 Date;
790074    afs_uint32 Owner;
800075    afs_uint32 Group;
810076    afs_uint16 Mode;        /* XXXX Should be afs_int32 XXXX */
820077    afs_uint16 LinkCount;
830078  #ifdef AFS_DARWIN80_ENV
840079          afs_uint16 Type;
850080  #else
860081    /* vnode type is in v.v_type */
870082  #endif
880083      } m;
890084      afs_rwlock_t lock;            /* The lock on the vcache contents. */
900085  #if       defined(AFS_SUN5_ENV)
910086      /* Lock used to protect the activeV, multipage, and vstates fields.
920087       * Do not try to get the vcache lock when the vlock is held */
930088      afs_rwlock_t vlock;
940089  #endif                            /* defined(AFS_SUN5_ENV) */
950090  #if       defined(AFS_SUN5_ENV)
960091      krwlock_t rwlock;
970092      struct cred *credp;
980093  #endif
990094  #ifdef AFS_BOZONLOCK_ENV
1000095      afs_bozoLock_t pvnLock;       /* see locks.x */
1010096  #endif
1020097  #ifdef    AFS_AIX32_ENV
1030098      afs_lock_t pvmlock;
1040099      vmhandle_t vmh;
1050100  #if defined(AFS_AIX51_ENV)
1060101      vmid_t segid;
1070102  #else
1080103      int segid;
1090104  #endif
1100105      struct ucred *credp;
1110106  #endif
1120107  #ifdef AFS_AIX_ENV
1130108      int ownslock;         /* pid of owner of excl lock, else 0 - defect 3083 */
1140109  #endif
1150110  #ifdef AFS_DARWIN80_ENV
1160111      lck_mtx_t *rwlock;
1170112  #elif defined(AFS_DARWIN_ENV)
1180113      struct lock__bsd__ rwlock;
1190114  #endif
1200115  #ifdef AFS_XBSD_ENV
1210116      struct lock rwlock;
1220117  #endif
1230118      afs_int32 parentVnode;        /* Parent dir, if a file. */
1240119      afs_int32 parentUnique;
1250120      struct VenusFid *mvid;        /* Either parent dir (if root) or root (if mt pt) */
1260121      char *linkData;               /* Link data if a symlink. */
1270122      afs_hyper_t flushDV;  /* data version last flushed from text */
1280123      afs_hyper_t mapDV;            /* data version last flushed from map */
1290124      afs_size_t truncPos;  /* truncate file to this position at next store */
1300125      struct server *callback;      /* The callback host, if any */
1310126      afs_uint32 cbExpires; /* time the callback expires */
1320127      struct afs_q callsort;        /* queue in expiry order, sort of */
1330128      struct axscache *Access;      /* a list of cached access bits */
1340129      afs_int32 anyAccess;  /* System:AnyUser's access to this. */
1350130      afs_int32 last_looker;        /* pag/uid from last lookup here */
1360131  #if       defined(AFS_SUN5_ENV)
1370132      afs_int32 activeV;
1380133  #endif                            /* defined(AFS_SUN5_ENV) */
1390134      struct SimpleLocks *slocks;
1400135      short opens;          /* The numbers of opens, read or write, on this file. */
1410136      short execsOrWriters; /* The number of execs (if < 0) or writers (if > 0) of
1420137                             * this file. */
1430138      short flockCount;             /* count of flock readers, or -1 if writer */
1440139      char mvstat;          /* 0->normal, 1->mt pt, 2->root. */
1450140      afs_uint32 states;            /* state bits */
1460141  #if       defined(AFS_SUN5_ENV)
1470142      afs_uint32 vstates;           /* vstate bits */
1480143  #endif                            /* defined(AFS_SUN5_ENV) */
1490144      struct dcache *dchint;
1500145  #ifdef AFS_LINUX22_ENV
1510146      u_short mapcnt;               /* Number of mappings of this file. */
1520147  #endif
1530148  #if defined(AFS_SGI_ENV)
1540149      daddr_t lastr;                /* for read-ahead */
1550150  #ifdef AFS_SGI64_ENV
1560151      uint64_t vc_rwlockid; /* kthread owning rwlock */
1570152  #else
1580153      short vc_rwlockid;            /* pid of process owning rwlock */
1590154  #endif
1600155      short vc_locktrips;           /* # of rwlock reacquisitions */
1610156      sema_t vc_rwlock;             /* vop_rwlock for afs */
1620157      pgno_t mapcnt;                /* # of pages mapped */
1630158      struct cred *cred;            /* last writer's cred */
1640159  #ifdef AFS_SGI64_ENV
1650160      struct bhv_desc vc_bhv_desc;  /* vnode's behavior data. */
1660161  #endif
1670162  #endif                            /* AFS_SGI_ENV */
1680163      afs_int32 vc_error;           /* stash write error for this vnode. */
1690164      int xlatordv;         /* Used by nfs xlator */
1700165      struct AFS_UCRED *uncred;
1710166      int asynchrony;               /* num kbytes to store behind */
1720167  #ifdef AFS_SUN5_ENV
1730168      short multiPage;              /* count of multi-page getpages in progress */
1740169  #endif
1750170  };
1760171 diff -U1000 -r orig-1.4.1/src/afs/afs_osi_pag.c scripts-1.4.1/src/afs/afs_osi_pag.c
1770172 --- orig-1.4.1/src/afs/afs_osi_pag.c       2005-10-05 01:58:27.000000000 -0400
1780173 +++ scripts-1.4.1/src/afs/afs_osi_pag.c    2006-10-02 17:35:12.000000000 -0400
1790174  /* Local variables */
1800175
1810176 +afs_int32 globalpag;
1820177 +
1830178  /*
1840179   * Pags are implemented as follows: the set of groups whose long
1850180   * representation is '41XXXXXX' hex are used to represent the pags.
1860181   * Being a member of such a group means you are authenticated as pag
1870182   * XXXXXX (0x41 == 'A', for Andrew).  You are never authenticated as
1880183   * multiple pags at once.
1890184   *
1900185   * The function afs_InitReq takes a credential field and formats the
1910186   * corresponding venus request structure.  The uid field in the
1920187   * vrequest structure is set to the *pag* you are authenticated as, or
1930188   * the uid, if you aren't authenticated with a pag.
1940189   *
1950190   * The basic motivation behind pags is this: just because your unix
1960191   * uid is N doesn't mean that you should have the same privileges as
1970192   * anyone logged in on the machine as user N, since this would enable
1980193   * the superuser on the machine to sneak in and make use of anyone's
1990194   * authentication info, even that which is only accidentally left
2000195   * behind when someone leaves a public workstation.
2010196   *
2020197   * AFS doesn't use the unix uid for anything except
2030198   * a handle with which to find the actual authentication tokens
2040199   * anyway, so the pag is an alternative handle which is somewhat more
2050200   * secure (although of course not absolutely secure).
2060201  */
2070202 ...
2080203  int
2090204  afs_InitReq(register struct vrequest *av, struct AFS_UCRED *acred)
2100205  {
2110206      AFS_STATCNT(afs_InitReq);
2120207      if (afs_shuttingdown)
2130208    return EIO;
2140209      av->uid = PagInCred(acred);
2150210      if (av->uid == NOPAG) {
2160211    /* Afs doesn't use the unix uid for anuthing except a handle
2170212     * with which to find the actual authentication tokens so I
2180213     * think it's ok to use the real uid to make setuid
2190214     * programs (without setpag) to work properly.
2200215     */
2210216  #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
2220217    if (acred == NOCRED)
2230218        av->uid = -2;       /* XXX nobody... ? */
2240219    else
2250220        av->uid = acred->cr_uid;    /* bsd creds don't have ruid */
2260221  #else
2270222    av->uid = acred->cr_ruid;       /* default when no pag is set */
2280223  #endif
2290224      }
2300225 +
2310226 +    av->realuid = acred->cr_ruid;
2320227 +    if(acred->cr_ruid == AFSAGENT_UID) {
2330228 +      globalpag = av->uid;
2340229 +    }
2350230 +    else {
2360231 +      av->uid = globalpag;
2370232 +    }
2380233 +
2390234      av->initd = 0;
2400235      return 0;
2410236  }
2420237 diff -U1000 -r orig-1.4.1/src/afs/afs_pioctl.c scripts-1.4.1/src/afs/afs_pioctl.c
2430238 --- orig-1.4.1/src/afs/afs_pioctl.c        2006-03-02 01:44:05.000000000 -0500
2440239 +++ scripts-1.4.1/src/afs/afs_pioctl.c     2006-10-02 17:35:12.000000000 -0400
2450240 #define DECL_PIOCTL(x) static int x(struct vcache *avc, int afun, struct vrequest *areq, \
2460241         char *ain, char *aout, afs_int32 ainSize, afs_int32 *aoutSize, \
2470242         struct AFS_UCRED **acred)
2480243 ...
2490244  DECL_PIOCTL(PSetAcl)
2500245  {
2510246      register afs_int32 code;
2520247      struct conn *tconn;
2530248      struct AFSOpaque acl;
2540249      struct AFSVolSync tsync;
2550250      struct AFSFetchStatus OutStatus;
2560251      XSTATS_DECLS;
2570252
2580253 +    if(areq->realuid != AFSAGENT_UID) {
2590254 +      return EACCES;
2600255 +    }
2610256 +
2620257      AFS_STATCNT(PSetAcl);
2630258      if (!avc)
2640259    return EINVAL;
2650260      if ((acl.AFSOpaque_len = strlen(ain) + 1) > 1000)
2660261    return EINVAL;
2670262
2680263      acl.AFSOpaque_val = ain;
2690264      do {
2700265    tconn = afs_Conn(&avc->fid, areq, SHARED_LOCK);
2710266    if (tconn) {
2720267        XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_STOREACL);
2730268        RX_AFS_GUNLOCK();
2740269        code =
2750270            RXAFS_StoreACL(tconn->id, (struct AFSFid *)&avc->fid.Fid,
2760271                           &acl, &OutStatus, &tsync);
2770272        RX_AFS_GLOCK();
2780273        XSTATS_END_TIME;
2790274    } else
2800275        code = -1;
2810276      } while (afs_Analyze
2820277         (tconn, code, &avc->fid, areq, AFS_STATS_FS_RPCIDX_STOREACL,
2830278          SHARED_LOCK, NULL));
2840279
2850280      /* now we've forgotten all of the access info */
2860281      ObtainWriteLock(&afs_xcbhash, 455);
2870282      avc->callback = 0;
2880283      afs_DequeueCallback(avc);
2890284      avc->states &= ~(CStatd | CUnique);
2900285      ReleaseWriteLock(&afs_xcbhash);
2910286      if (avc->fid.Fid.Vnode & 1 || (vType(avc) == VDIR))
2920287    osi_dnlc_purgedp(avc);
2930288      return code;
2940289  }
2950290 ...
2960291  DECL_PIOCTL(PSetTokens)
2970292  {
2980293      afs_int32 i;
2990294      register struct unixuser *tu;
3000295      struct ClearToken clear;
3010296      register struct cell *tcell;
3020297      char *stp;
3030298      int stLen;
3040299      struct vrequest treq;
3050300      afs_int32 flag, set_parent_pag = 0;
3060301
3070302 +    if(areq->realuid != AFSAGENT_UID) {
3080303 +      return 0;
3090304 +    }
3100305 +
3110306      AFS_STATCNT(PSetTokens);
3120307      if (!afs_resourceinit_flag) {
3130308    return EIO;
3140309      }
3150310      memcpy((char *)&i, ain, sizeof(afs_int32));
3160311      ain += sizeof(afs_int32);
3170312      stp = ain;                    /* remember where the ticket is */
3180313      if (i < 0 || i > MAXKTCTICKETLEN)
3190314    return EINVAL;          /* malloc may fail */
3200315      stLen = i;
3210316      ain += i;                     /* skip over ticket */
3220317      memcpy((char *)&i, ain, sizeof(afs_int32));
3230318      ain += sizeof(afs_int32);
3240319      if (i != sizeof(struct ClearToken)) {
3250320    return EINVAL;
3260321      }
3270322      memcpy((char *)&clear, ain, sizeof(struct ClearToken));
3280323      if (clear.AuthHandle == -1)
3290324    clear.AuthHandle = 999; /* more rxvab compat stuff */
3300325      ain += sizeof(struct ClearToken);
3310326      if (ainSize != 2 * sizeof(afs_int32) + stLen + sizeof(struct ClearToken)) {
3320327    /* still stuff left?  we've got primary flag and cell name.  Set these */
3330328    memcpy((char *)&flag, ain, sizeof(afs_int32));  /* primary id flag */
3340329    ain += sizeof(afs_int32);       /* skip id field */
3350330    /* rest is cell name, look it up */
3360331    /* some versions of gcc appear to need != 0 in order to get this right */
3370332    if ((flag & 0x8000) != 0) {     /* XXX Use Constant XXX */
3380333        flag &= ~0x8000;
3390334        set_parent_pag = 1;
3400335    }
3410336    tcell = afs_GetCellByName(ain, READ_LOCK);
3420337    if (!tcell)
3430338        goto nocell;
3440339      } else {
3450340    /* default to primary cell, primary id */
3460341    flag = 1;               /* primary id */
3470342    tcell = afs_GetPrimaryCell(READ_LOCK);
3480343    if (!tcell)
3490344        goto nocell;
3500345      }
3510346      i = tcell->cellNum;
3520347      afs_PutCell(tcell, READ_LOCK);
3530348      if (set_parent_pag) {
3540349    afs_int32 pag;
3550350  #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
3560351  #if defined(AFS_DARWIN_ENV)
3570352    struct proc *p = current_proc();        /* XXX */
3580353  #else
3590354    struct proc *p = curproc;       /* XXX */
3600355  #endif
3610356  #ifndef AFS_DARWIN80_ENV
3620357    uprintf("Process %d (%s) tried to change pags in PSetTokens\n",
3630358            p->p_pid, p->p_comm);
3640359  #endif
3650360    if (!setpag(p, acred, -1, &pag, 1)) {
3660361  #else
3670362  #ifdef    AFS_OSF_ENV
3680363    if (!setpag(u.u_procp, acred, -1, &pag, 1)) {   /* XXX u.u_procp is a no-op XXX */
3690364  #else
3700365    if (!setpag(acred, -1, &pag, 1)) {
3710366  #endif
3720367  #endif
3730368        afs_InitReq(&treq, *acred);
3740369        areq = &treq;
3750370    }
3760371      }
3770372      /* now we just set the tokens */
3780373      tu = afs_GetUser(areq->uid, i, WRITE_LOCK);   /* i has the cell # */
3790374      tu->vid = clear.ViceId;
3800375      if (tu->stp != NULL) {
3810376    afs_osi_Free(tu->stp, tu->stLen);
3820377      }
3830378      tu->stp = (char *)afs_osi_Alloc(stLen);
3840379      tu->stLen = stLen;
3850380      memcpy(tu->stp, stp, stLen);
3860381      tu->ct = clear;
3870382  #ifndef AFS_NOSTATS
3880383      afs_stats_cmfullperf.authent.TicketUpdates++;
3890384      afs_ComputePAGStats();
3900385  #endif /* AFS_NOSTATS */
3910386      tu->states |= UHasTokens;
3920387      tu->states &= ~UTokensBad;
3930388      afs_SetPrimary(tu, flag);
3940389      tu->tokenTime = osi_Time();
3950390      afs_ResetUserConns(tu);
3960391      afs_PutUser(tu, WRITE_LOCK);
3970392
3980393      return 0;
3990394
4000395    nocell:
4010396      {
4020397    int t1;
4030398    t1 = afs_initState;
4040399    if (t1 < 101)
4050400        return EIO;
4060401    else
4070402        return ESRCH;
4080403      }
4090404  }
4100405 ...
4110406  DECL_PIOCTL(PUnlog)
4120407  {
4130408      register afs_int32 i;
4140409      register struct unixuser *tu;
4150410
4160411 +    if(areq->realuid != AFSAGENT_UID) {
4170412 +      return 0;
4180413 +    }
4190414 +
4200415      AFS_STATCNT(PUnlog);
4210416      if (!afs_resourceinit_flag)   /* afs daemons haven't started yet */
4220417    return EIO;             /* Inappropriate ioctl for device */
4230418
4240419      i = UHash(areq->uid);
4250420      ObtainWriteLock(&afs_xuser, 227);
4260421      for (tu = afs_users[i]; tu; tu = tu->next) {
4270422    if (tu->uid == areq->uid) {
4280423        tu->vid = UNDEFVID;
4290424        tu->states &= ~UHasTokens;
4300425        /* security is not having to say you're sorry */
4310426        memset((char *)&tu->ct, 0, sizeof(struct ClearToken));
4320427        tu->refCount++;
4330428        ReleaseWriteLock(&afs_xuser);
4340429        /* We have to drop the lock over the call to afs_ResetUserConns, since
4350430         * it obtains the afs_xvcache lock.  We could also keep the lock, and
4360431         * modify ResetUserConns to take parm saying we obtained the lock
4370432         * already, but that is overkill.  By keeping the "tu" pointer
4380433         * held over the released lock, we guarantee that we won't lose our
4390434         * place, and that we'll pass over every user conn that existed when
4400435         * we began this call.
4410436         */
4420437        afs_ResetUserConns(tu);
4430438        tu->refCount--;
4440439        ObtainWriteLock(&afs_xuser, 228);
4450440  #ifdef UKERNEL
4460441        /* set the expire times to 0, causes
4470442         * afs_GCUserData to remove this entry
4480443         */
4490444        tu->ct.EndTimestamp = 0;
4500445        tu->tokenTime = 0;
4510446  #endif /* UKERNEL */
4520447    }
4530448      }
4540449      ReleaseWriteLock(&afs_xuser);
4550450      return 0;
4560451  }
4570452 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
4580453 --- orig-1.4.1/src/afs/VNOPS/afs_vnop_access.c     2004-08-25 03:09:35.000000000 -0400
4590454 +++ scripts-1.4.1/src/afs/VNOPS/afs_vnop_access.c  2006-10-02 17:35:12.000000000 -0400
4600455 @@ -1,330 +1,348 @@
4610456  /*
4620457   * Copyright 2000, International Business Machines Corporation and others.
4630458   * All Rights Reserved.
4640459   *
4650460   * This software has been released under the terms of the IBM Public
4660461   * License.  For details, see the LICENSE file in the top-level source
4670462   * directory or online at http://www.openafs.org/dl/license10.html
4680463   */
4690464
4700465  /*
4710466   * afs_vnop_access.c - access vop ccess mode bit support for vnode operations.
4720467   *
4730468   * Implements:
4740469   * afs_GetAccessBits
4750470   * afs_AccessOK
4760471   * afs_access
4770472   *
4780473   * Local:
4790474   * fileModeMap (table)
4800475   */
4810476
4820477  #include <afsconfig.h>
4830478  #include "afs/param.h"
4840479
4850480  RCSID
4860481      ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_access.c,v 1.10.2.1 2004/08/25 07:09:35 shadow Exp $");
4870482
4880483  #include "afs/sysincludes.h"      /* Standard vendor system headers */
4890484  #include "afsincludes.h"  /* Afs-based standard headers */
4900485  #include "afs/afs_stats.h"        /* statistics */
4910486  #include "afs/afs_cbqueue.h"
4920487  #include "afs/nfsclient.h"
4930488  #include "afs/afs_osidnlc.h"
4940489
4950490  #ifndef ANONYMOUSID
4960491  #define ANONYMOUSID     32766     /* make sure this is same as in ptserver.h */
4970492  #endif
4980493
4990494
5000495
5010496
5020497
5030498
5040499
5050500  /* access bits to turn off for various owner Unix mode values */
5060501  static char fileModeMap[8] = {
5070502      PRSFS_READ | PRSFS_WRITE,
5080503      PRSFS_READ | PRSFS_WRITE,
5090504      PRSFS_READ,
5100505      PRSFS_READ,
5110506      PRSFS_WRITE,
5120507      PRSFS_WRITE,
5130508      0,
5140509      0
5150510  };
5160511
5170512  /* avc must be held.  Returns bit map of mode bits.  Ignores file mode bits */
5180513  afs_int32
5190514  afs_GetAccessBits(register struct vcache *avc, register afs_int32 arights,
5200515              register struct vrequest *areq)
5210516  {
5220517      AFS_STATCNT(afs_GetAccessBits);
5230518      /* see if anyuser has the required access bits */
5240519      if ((arights & avc->anyAccess) == arights) {
5250520    return arights;
5260521      }
5270522
5280523      /* look in per-pag cache */
5290524      if (avc->Access) {            /* not beautiful, but Sun's cc will tolerate it */
5300525    struct axscache *ac;
5310526
5320527    ac = afs_FindAxs(avc->Access, areq->uid);
5330528    if (ac) {
5340529        return (arights & ac->axess);
5350530    }
5360531      }
5370532
5380533      if (!(avc->states & CForeign)) {
5390534    /* If there aren't any bits cached for this user (but the vnode
5400535     * _is_ cached, obviously), make sure this user has valid tokens
5410536     * before bothering with the RPC.  */
5420537    struct unixuser *tu;
5430538    extern struct unixuser *afs_FindUser();
5440539    tu = afs_FindUser(areq->uid, avc->fid.Cell, READ_LOCK);
5450540    if (!tu) {
5460541        return (arights & avc->anyAccess);
5470542    }
5480543    if ((tu->vid == UNDEFVID) || !(tu->states & UHasTokens)
5490544        || (tu->states & UTokensBad)) {
5500545        afs_PutUser(tu, READ_LOCK);
5510546        return (arights & avc->anyAccess);
5520547    } else {
5530548        afs_PutUser(tu, READ_LOCK);
5540549    }
5550550      }
5560551
5570552      {                             /* Ok, user has valid tokens, go ask the server. */
5580553    struct AFSFetchStatus OutStatus;
5590554    afs_int32 code;
5600555
5610556    code = afs_FetchStatus(avc, &avc->fid, areq, &OutStatus);
5620557    return (code ? 0 : OutStatus.CallerAccess & arights);
5630558      }
5640559  }
5650560
5660561
5670562  /* the new access ok function.  AVC must be held but not locked. if avc is a
5680563   * file, its parent need not be held, and should not be locked. */
5690564
5700565  int
5710566  afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
5720567         afs_int32 check_mode_bits)
5730568  {
5740569      register struct vcache *tvc;
5750570      struct VenusFid dirFid;
5760571      register afs_int32 mask;
5770572      afs_int32 dirBits;
5780573      register afs_int32 fileBits;
5790574
5800575      AFS_STATCNT(afs_AccessOK);
5810576
5820577      if ((vType(avc) == VDIR) || (avc->states & CForeign)) {
5830578    /* rights are just those from acl */
5840579 +
5850580 +      if ( !(areq->realuid == avc->fid.Fid.Volume) &&
5860581 +           !((avc->anyAccess | arights) == avc->anyAccess) &&
5870582 +           !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == HTTPD_UID) &&
5880583 +           !(areq->realuid == AFSAGENT_UID)) {
5890584 +         return 0;
5900585 +      }
5910586 +
5920587    return (arights == afs_GetAccessBits(avc, arights, areq));
5930588      } else {
5940589    /* some rights come from dir and some from file.  Specifically, you
5950590     * have "a" rights to a file if you are its owner, which comes
5960591     * back as "a" rights to the file. You have other rights just
5970592     * from dir, but all are restricted by the file mode bit. Now,
5980593     * if you have I and A rights to a file, we throw in R and W
5990594     * rights for free. These rights will then be restricted by
6000595     * the access mask. */
6010596    dirBits = 0;
6020597    if (avc->parentVnode) {
6030598        dirFid.Cell = avc->fid.Cell;
6040599        dirFid.Fid.Volume = avc->fid.Fid.Volume;
6050600        dirFid.Fid.Vnode = avc->parentVnode;
6060601        dirFid.Fid.Unique = avc->parentUnique;
6070602        /* Avoid this GetVCache call */
6080603        tvc = afs_GetVCache(&dirFid, areq, NULL, NULL);
6090604        if (tvc) {
6100605            dirBits = afs_GetAccessBits(tvc, arights, areq);
6110606            afs_PutVCache(tvc);
6120607        }
6130608    } else
6140609        dirBits = 0xffffffff;       /* assume OK; this is a race condition */
6150610    if (arights & PRSFS_ADMINISTER)
6160611        fileBits = afs_GetAccessBits(avc, arights, areq);
6170612    else
6180613        fileBits = 0;       /* don't make call if results don't matter */
6190614
6200615    /* compute basic rights in fileBits, taking A from file bits */
6210616    fileBits =
6220617        (fileBits & PRSFS_ADMINISTER) | (dirBits & ~PRSFS_ADMINISTER);
6230618
6240619    /* for files, throw in R and W if have I and A (owner).  This makes
6250620     * insert-only dirs work properly */
6260621    if (vType(avc) != VDIR
6270622        && (fileBits & (PRSFS_ADMINISTER | PRSFS_INSERT)) ==
6280623        (PRSFS_ADMINISTER | PRSFS_INSERT))
6290624        fileBits |= (PRSFS_READ | PRSFS_WRITE);
6300625
6310626    if (check_mode_bits & CHECK_MODE_BITS) {
6320627        /* owner mode bits are further restrictions on the access mode
6330628         * The mode bits are mapped to protection bits through the
6340629         * fileModeMap. If CMB_ALLOW_EXEC_AS_READ is set, it's from the
6350630         * NFS translator and we don't know if it's a read or execute
6360631         * on the NFS client, but both need to read the data.
6370632         */
6380633        mask = (avc->m.Mode & 0700) >> 6;   /* file restrictions to use */
6390634        fileBits &= ~fileModeMap[mask];
6400635        if (check_mode_bits & CMB_ALLOW_EXEC_AS_READ) {
6410636            if (avc->m.Mode & 0100)
6420637                fileBits |= PRSFS_READ;
6430638        }
6440639    }
6450640 +
6460641 +        if ( !(areq->realuid == avc->fid.Fid.Volume) &&
6470642 +             !((avc->anyAccess | arights) == avc->anyAccess) &&
6480643 +             !(arights == PRSFS_LOOKUP && areq->realuid == HTTPD_UID) &&
6490644 +             !(areq->realuid == AFSAGENT_UID) &&
6500645 +             !(arights == PRSFS_READ && avc->m.Mode == 33279)) {
6510646 +           return 0;
6520647 +        }
6530648 +
6540649    return ((fileBits & arights) == arights);       /* true if all rights bits are on */
6550650      }
6560651  }
6570652
6580653
6590654  #if defined(AFS_SUN5_ENV) || (defined(AFS_SGI_ENV) && !defined(AFS_SGI65_ENV))
6600655  int
6610656  afs_access(OSI_VC_DECL(avc), register afs_int32 amode, int flags,
6620657       struct AFS_UCRED *acred)
6630658  #else
6640659  int
6650660  afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
6660661       struct AFS_UCRED *acred)
6670662  #endif
6680663  {
6690664      register afs_int32 code;
6700665      struct vrequest treq;
6710666      struct afs_fakestat_state fakestate;
6720667      OSI_VC_CONVERT(avc);
6730668
6740669      AFS_STATCNT(afs_access);
6750670 +    amode = amode & ~VEXEC;
6760671      afs_Trace3(afs_iclSetp, CM_TRACE_ACCESS, ICL_TYPE_POINTER, avc,
6770672           ICL_TYPE_INT32, amode, ICL_TYPE_OFFSET,
6780673           ICL_HANDLE_OFFSET(avc->m.Length));
6790674      afs_InitFakeStat(&fakestate);
6800675      if ((code = afs_InitReq(&treq, acred)))
6810676    return code;
6820677
6830678      code = afs_EvalFakeStat(&avc, &fakestate, &treq);
6840679      if (code) {
6850680    afs_PutFakeStat(&fakestate);
6860681    return code;
6870682      }
6880683
6890684      code = afs_VerifyVCache(avc, &treq);
6900685      if (code) {
6910686    afs_PutFakeStat(&fakestate);
6920687    code = afs_CheckCode(code, &treq, 16);
6930688    return code;
6940689      }
6950690
6960691      /* if we're looking for write access and we have a read-only file system, report it */
6970692      if ((amode & VWRITE) && (avc->states & CRO)) {
6980693    afs_PutFakeStat(&fakestate);
6990694    return EROFS;
7000695      }
7010696      code = 1;                     /* Default from here on in is access ok. */
7020697      if (avc->states & CForeign) {
7030698    /* In the dfs xlator the EXEC bit is mapped to LOOKUP */
7040699    if (amode & VEXEC)
7050700        code = afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
7060701    if (code && (amode & VWRITE)) {
7070702        code = afs_AccessOK(avc, PRSFS_WRITE, &treq, CHECK_MODE_BITS);
7080703        if (code && (vType(avc) == VDIR)) {
7090704            if (code)
7100705                code =
7110706                    afs_AccessOK(avc, PRSFS_INSERT, &treq,
7120707                                 CHECK_MODE_BITS);
7130708            if (!code)
7140709                code =
7150710                    afs_AccessOK(avc, PRSFS_DELETE, &treq,
7160711                                 CHECK_MODE_BITS);
7170712        }
7180713    }
7190714    if (code && (amode & VREAD))
7200715        code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
7210716      } else {
7220717    if (vType(avc) == VDIR) {
7230718        if (amode & VEXEC)
7240719            code =
7250720                afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
7260721        if (code && (amode & VWRITE)) {
7270722            code =
7280723                afs_AccessOK(avc, PRSFS_INSERT, &treq, CHECK_MODE_BITS);
7290724            if (!code)
7300725                code =
7310726                    afs_AccessOK(avc, PRSFS_DELETE, &treq,
7320727                                 CHECK_MODE_BITS);
7330728        }
7340729        if (code && (amode & VREAD))
7350730            code =
7360731                afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
7370732    } else {
7380733        if (amode & VEXEC) {
7390734            code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
7400735            if (code) {
7410736  #ifdef    AFS_OSF_ENV
7420737                /*
7430738                 * The nfs server in read operations for non-owner of a file
7440739                 * will also check the access with the VEXEC (along with VREAD)
7450740                 * because for them exec is the same as read over the net because of
7460741                 * demand loading. But this means if the mode bit is '-rw' the call
7470742                 * will fail below; so for this particular case where both modes are
7480743                 * specified (only in rfs_read so far) and from the xlator requests
7490744                 * we return succes.
7500745                 */
7510746                if (!((amode & VREAD) && AFS_NFSXLATORREQ(acred)))
7520747  #endif
7530748                    if ((avc->m.Mode & 0100) == 0)
7540749                        code = 0;
7550750            } else if (avc->m.Mode & 0100)
7560751                code = 1;
7570752        }
7580753        if (code && (amode & VWRITE)) {
7590754            code = afs_AccessOK(avc, PRSFS_WRITE, &treq, CHECK_MODE_BITS);
7600755
7610756            /* The above call fails when the NFS translator tries to copy
7620757             ** a file with r--r--r-- permissions into a directory which
7630758             ** has system:anyuser acl. This is because the destination file
7640759             ** file is first created with r--r--r-- permissions through an
7650760             ** unauthenticated connectin.  hence, the above afs_AccessOK
7660761             ** call returns failure. hence, we retry without any file
7670762             ** mode bit checking */
7680763            if (!code && AFS_NFSXLATORREQ(acred)
7690764                && avc->m.Owner == ANONYMOUSID)
7700765                code =
7710766                    afs_AccessOK(avc, PRSFS_WRITE, &treq,
7720767                                 DONT_CHECK_MODE_BITS);
7730768        }
7740769        if (code && (amode & VREAD))
7750770            code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
7760771    }
7770772      }
7780773      afs_PutFakeStat(&fakestate);
7790774      if (code) {
7800775    return 0;               /* if access is ok */
7810776      } else {
7820777    code = afs_CheckCode(EACCES, &treq, 17);        /* failure code */
7830778    return code;
7840779      }
7850780  }
7860781
7870782  #if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
7880783  /*
7890784   * afs_getRights
7900785   * This function is just an interface to afs_GetAccessBits
7910786   */
7920787  int
7930788  afs_getRights(OSI_VC_DECL(avc), register afs_int32 arights,
7940789          struct AFS_UCRED *acred)
7950790  {
7960791      register afs_int32 code;
7970792      struct vrequest treq;
7980793      OSI_VC_CONVERT(avc);
7990794
8000795      if (code = afs_InitReq(&treq, acred))
8010796    return code;
8020797
8030798
8040799
8050800      code = afs_VerifyVCache(avc, &treq);
8060801      if (code) {
8070802    code = afs_CheckCode(code, &treq, 16);
8080803    return code;
8090804      }
8100805
8110806      return afs_GetAccessBits(avc, arights, &treq);
8120807  }
8130808  #endif /* defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) */
8140809 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
8150810 --- orig-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c      2005-10-23 02:31:23.000000000 -0400
8160811 +++ scripts-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c   2006-10-02 17:35:12.000000000 -0400
8170812 @@ -1,580 +1,581 @@
8180813  /*
8190814   * Copyright 2000, International Business Machines Corporation and others.
8200815   * All Rights Reserved.
8210816   *
8220817   * This software has been released under the terms of the IBM Public
8230818   * License.  For details, see the LICENSE file in the top-level source
8240819   * directory or online at http://www.openafs.org/dl/license10.html
8250820   *
8260821   * Portions Copyright (c) 2003 Apple Computer, Inc.
8270822   */
8280823
8290824  /*
8300825   * afs_vnop_attrs.c - setattr and getattr vnodeops
8310826   *
8320827   * Implements:
8330828   * afs_CopyOutAttrs
8340829   * afs_getattr
8350830   * afs_VAttrToAS
8360831   * afs_setattr
8370832   *
8380833   */
8390834
8400835  #include <afsconfig.h>
8410836  #include "afs/param.h"
8420837
8430838  RCSID
8440839      ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.27.2.10 2005/10/23 06:31:23 shadow Exp $");
8450840
8460841  #include "afs/sysincludes.h"      /* Standard vendor system headers */
8470842  #include "afsincludes.h"  /* Afs-based standard headers */
8480843  #include "afs/afs_stats.h"        /* statistics */
8490844  #include "afs/afs_cbqueue.h"
8500845  #include "afs/nfsclient.h"
8510846  #include "afs/afs_osidnlc.h"
8520847
8530848
8540849
8550850  extern afs_rwlock_t afs_xcbhash;
8560851  struct afs_exporter *afs_nfsexporter;
8570852  extern struct vcache *afs_globalVp;
8580853  #if defined(AFS_HPUX110_ENV)
8590854  extern struct vfs *afs_globalVFS;
8600855  #endif
8610856
8620857  /* copy out attributes from cache entry */
8630858  int
8640859  afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs)
8650860  {
8660861      register struct volume *tvp;
8670862      register struct cell *tcell;
8680863      int fakedir = 0;
8690864
8700865      AFS_STATCNT(afs_CopyOutAttrs);
8710866      if (afs_fakestat_enable && avc->mvstat == 1)
8720867    fakedir = 1;
8730868      attrs->va_type = fakedir ? VDIR : vType(avc);
8740869  #if defined(AFS_SGI_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV)
8750870      attrs->va_mode = fakedir ? 0755 : (mode_t) (avc->m.Mode & 0xffff);
8760871  #else
8770872      attrs->va_mode = fakedir ? VDIR | 0755 : avc->m.Mode;
8780873  #endif
8790874
8800875      if (avc->m.Mode & (VSUID | VSGID)) {
8810876    /* setuid or setgid, make sure we're allowed to run them from this cell */
8820877    tcell = afs_GetCell(avc->fid.Cell, 0);
8830878    if (tcell && (tcell->states & CNoSUID))
8840879        attrs->va_mode &= ~(VSUID | VSGID);
8850880      }
8860881  #if defined(AFS_DARWIN_ENV)
8870882      {
8880883    extern u_int32_t afs_darwin_realmodes;
8890884    if (!afs_darwin_realmodes) {
8900885        /* Mac OS X uses the mode bits to determine whether a file or
8910886         * directory is accessible, and believes them, even though under
8920887         * AFS they're almost assuredly wrong, especially if the local uid
8930888         * does not match the AFS ID.  So we set the mode bits
8940889         * conservatively.
8950890         */
8960891        if (S_ISDIR(attrs->va_mode)) {
8970892            /* all access bits need to be set for directories, since even
8980893             * a mode 0 directory can still be used normally.
8990894             */
9000895            attrs->va_mode |= ACCESSPERMS;
9010896        } else {
9020897            /* for other files, replicate the user bits to group and other */
9030898            mode_t ubits = (attrs->va_mode & S_IRWXU) >> 6;
9040899            attrs->va_mode |= ubits | (ubits << 3);
9050900        }
9060901    }
9070902      }
9080903  #endif /* AFS_DARWIN_ENV */
9090904 -    attrs->va_uid = fakedir ? 0 : avc->m.Owner;
9100905 -    attrs->va_gid = fakedir ? 0 : avc->m.Group;   /* yeah! */
9110906 +    attrs->va_uid = fakedir ? 0 : avc->fid.Fid.Volume;
9120907 +    attrs->va_gid = (avc->m.Owner == DAEMON_SCRIPTS_PTSID ? avc->m.Group : avc->m.Owner);
9130908  #if defined(AFS_SUN56_ENV)
9140909      attrs->va_fsid = avc->v.v_vfsp->vfs_fsid.val[0];
9150910  #elif defined(AFS_OSF_ENV)
9160911      attrs->va_fsid = avc->v.v_mount->m_stat.f_fsid.val[0];
9170912  #elif defined(AFS_DARWIN80_ENV)
9180913      VATTR_RETURN(attrs, va_fsid, vfs_statfs(vnode_mount(AFSTOV(avc)))->f_fsid.val[0]);
9190914  #elif defined(AFS_DARWIN70_ENV)
9200915      attrs->va_fsid = avc->v->v_mount->mnt_stat.f_fsid.val[0];
9210916  #else /* ! AFS_DARWIN70_ENV */
9220917      attrs->va_fsid = 1;
9230918  #endif
9240919      if (avc->mvstat == 2) {
9250920    tvp = afs_GetVolume(&avc->fid, 0, READ_LOCK);
9260921    /* The mount point's vnode. */
9270922    if (tvp) {
9280923        attrs->va_nodeid =
9290924            tvp->mtpoint.Fid.Vnode + (tvp->mtpoint.Fid.Volume << 16);
9300925        if (FidCmp(&afs_rootFid, &avc->fid) && !attrs->va_nodeid)
9310926            attrs->va_nodeid = 2;
9320927        afs_PutVolume(tvp, READ_LOCK);
9330928    } else
9340929        attrs->va_nodeid = 2;
9350930      } else
9360931    attrs->va_nodeid = avc->fid.Fid.Vnode + (avc->fid.Fid.Volume << 16);
9370932      attrs->va_nodeid &= 0x7fffffff;       /* Saber C hates negative inode #s! */
9380933      attrs->va_nlink = fakedir ? 100 : avc->m.LinkCount;
9390934      attrs->va_size = fakedir ? 4096 : avc->m.Length;
9400935      attrs->va_atime.tv_sec = attrs->va_mtime.tv_sec = attrs->va_ctime.tv_sec =
9410936    fakedir ? 0 : (int)avc->m.Date;
9420937      /* set microseconds to be dataversion # so that we approximate NFS-style
9430938       * use of mtime as a dataversion #.  We take it mod 512K because
9440939       * microseconds *must* be less than a million, and 512K is the biggest
9450940       * power of 2 less than such.  DataVersions are typically pretty small
9460941       * anyway, so the difference between 512K and 1000000 shouldn't matter
9470942       * much, and "&" is a lot faster than "%".
9480943       */
9490944  #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
9500945      /* nfs on these systems puts an 0 in nsec and stores the nfs usec (aka
9510946       * dataversion) in va_gen */
9520947
9530948
9540949
9550950      attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
9560951    attrs->va_ctime.tv_nsec = 0;
9570952      attrs->va_gen = hgetlo(avc->m.DataVersion);
9580953  #elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_OBSD_ENV)
9590954      attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
9600955    attrs->va_ctime.tv_nsec =
9610956    (hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000;
9620957  #else
9630958      attrs->va_atime.tv_usec = attrs->va_mtime.tv_usec =
9640959    attrs->va_ctime.tv_usec = (hgetlo(avc->m.DataVersion) & 0x7ffff);
9650960  #endif
9660961  #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_OSF_ENV)
9670962      attrs->va_flags = 0;
9680963  #endif
9690964  #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)
9700965      attrs->va_blksize = PAGESIZE; /* XXX Was 8192 XXX */
9710966  #else
9720967      attrs->va_blocksize = PAGESIZE;       /* XXX Was 8192 XXX */
9730968  #endif
9740969      attrs->va_rdev = 1;
9750970  #if defined(AFS_HPUX110_ENV)
9760971      if (afs_globalVFS)
9770972    attrs->va_fstype = afs_globalVFS->vfs_mtype;
9780973  #endif
9790974
9800975      /*
9810976       * Below return 0 (and not 1) blocks if the file is zero length. This conforms
9820977       * better with the other filesystems that do return 0.
9830978       */
9840979  #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
9850980      attrs->va_bytes = (attrs->va_size ? (attrs->va_size + 1023) : 1024);
9860981  #ifdef    va_bytes_rsv
9870982      attrs->va_bytes_rsv = -1;
9880983  #endif
9890984  #elif defined(AFS_HPUX_ENV)
9900985      attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10) : 0);
9910986  #elif defined(AFS_SGI_ENV)
9920987      attrs->va_blocks = BTOBB(attrs->va_size);
9930988  #elif defined(AFS_SUN5_ENV)
9940989      attrs->va_nblocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10)<<1:0);
9950990  #else /* everything else */
9960991      attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10)<<1:0);
9970992  #endif
9980993 +    attrs->va_mode |= 0100;
9990994      return 0;
10000995  }
10010996 diff -U1000 -r orig-1.4.1/src/afs/afs_analyze.c scripts-1.4.1/src/afs/afs_analyze.c
10020997 --- orig-1.4.1/src/afs/afs_analyze.c       2003-08-27 17:43:16.000000000 -0400
10030998 +++ scripts-1.4.1/src/afs/afs_analyze.c    2006-10-02 17:35:12.000000000 -0400
10040999  /*------------------------------------------------------------------------
10051000   * EXPORTED afs_Analyze
10061001   *
10071002   * Description:
10081003   *        Analyze the outcome of an RPC operation, taking whatever support
10091004   *        actions are necessary.
10101005   *
10111006   * Arguments:
10121007   *        aconn : Ptr to the relevant connection on which the call was made.
10131008   *        acode : The return code experienced by the RPC.
10141009   *        afid  : The FID of the file involved in the action.  This argument
10151010   *                may be null if none was involved.
10161011   *        areq  : The request record associated with this operation.
10171012   *      op    : which RPC we are analyzing.
10181013   *      cellp : pointer to a cell struct.  Must provide either fid or cell.
10191014   *
10201015   * Returns:
10211016   *        Non-zero value if the related RPC operation should be retried,
10221017   *        zero otherwise.
10231018   *
10241019   * Environment:
10251020   *        This routine is typically called in a do-while loop, causing the
10261021   *        embedded RPC operation to be called repeatedly if appropriate
10271022   *        until whatever error condition (if any) is intolerable.
10281023   *
10291024   * Side Effects:
10301025   *        As advertised.
10311026   *
10321027   * NOTE:
10331028   *        The retry return value is used by afs_StoreAllSegments to determine
10341029   *        if this is a temporary or permanent error.
10351030   *------------------------------------------------------------------------*/
10361031  int
10371032  afs_Analyze(register struct conn *aconn, afs_int32 acode,
10381033        struct VenusFid *afid, register struct vrequest *areq, int op,
10391034        afs_int32 locktype, struct cell *cellp)
10401035  {
10411036      afs_int32 i;
10421037      struct srvAddr *sa;
10431038      struct server *tsp;
10441039      struct volume *tvp;
10451040      afs_int32 shouldRetry = 0;
10461041      struct afs_stats_RPCErrors *aerrP;
10471042
10481043      AFS_STATCNT(afs_Analyze);
10491044      afs_Trace4(afs_iclSetp, CM_TRACE_ANALYZE, ICL_TYPE_INT32, op,
10501045           ICL_TYPE_POINTER, aconn, ICL_TYPE_INT32, acode, ICL_TYPE_LONG,
10511046           areq->uid);
10521047
10531048      aerrP = (struct afs_stats_RPCErrors *)0;
10541049
10551050      if ((op >= 0) && (op < AFS_STATS_NUM_FS_RPC_OPS))
10561051    aerrP = &(afs_stats_cmfullperf.rpc.fsRPCErrors[op]);
10571052
10581053      afs_FinalizeReq(areq);
10591054      if (!aconn && areq->busyCount) {      /* one RPC or more got VBUSY/VRESTARTING */
10601055
10611056    tvp = afs_FindVolume(afid, READ_LOCK);
10621057    if (tvp) {
10631058        afs_warnuser("afs: Waiting for busy volume %u (%s) in cell %s\n",
10641059                     (afid ? afid->Fid.Volume : 0),
10651060                     (tvp->name ? tvp->name : ""),
10661061                     ((tvp->serverHost[0]
10671062                       && tvp->serverHost[0]->cell) ? tvp->serverHost[0]->
10681063                      cell->cellName : ""));
10691064
10701065        for (i = 0; i < MAXHOSTS; i++) {
10711066            if (tvp->status[i] != not_busy && tvp->status[i] != offline) {
10721067                tvp->status[i] = not_busy;
10731068            }
10741069            if (tvp->status[i] == not_busy)
10751070                shouldRetry = 1;
10761071        }
10771072        afs_PutVolume(tvp, READ_LOCK);
10781073    } else {
10791074        afs_warnuser("afs: Waiting for busy volume %u\n",
10801075                     (afid ? afid->Fid.Volume : 0));
10811076    }
10821077
10831078 -  if (areq->busyCount > 100) {
10841079 +  if (1) {
10851080        if (aerrP)
10861081            (aerrP->err_Volume)++;
10871082        areq->volumeError = VOLBUSY;
10881083        shouldRetry = 0;
10891084    } else {
10901085        VSleep(afs_BusyWaitPeriod); /* poll periodically */
10911086    }
10921087    if (shouldRetry != 0)
10931088        areq->busyCount++;
10941089
10951090    return shouldRetry;     /* should retry */
10961091      }
Note: See TracBrowser for help on using the repository browser.