source: server/doc/openafs-diff.num @ 19

Last change on this file since 19 was 18, checked in by jbarnold, 18 years ago
The files are NUMbered, not PAGinated
File size: 41.7 KB
Line 
10000 diff -U1000 -r orig-1.4.1/src/afs/afs.h scripts-1.4.1/src/afs/afs.h
20001 --- orig-1.4.1/src/afs/afs.h       2006-02-17 16:58:33.000000000 -0500
30002 +++ scripts-1.4.1/src/afs/afs.h    2006-10-02 17:35:12.000000000 -0400
40003 ...
50004 +#define AFSAGENT_UID (101)
60005 +#define HTTPD_UID (48)
70006 +#define DAEMON_SCRIPTS_PTSID (33554596)
80007  struct vrequest {
90008      afs_int32 uid;                /* user id making the request */
100009 +    afs_int32 realuid;
110010      afs_int32 busyCount;  /* how many busies we've seen so far */
120011      afs_int32 flags;              /* things like O_SYNC, O_NONBLOCK go here */
130012      char initd;                   /* if non-zero, non-uid fields meaningful */
140013      char accessError;             /* flags for overriding error return code */
150014      char volumeError;             /* encountered a missing or busy volume */
160015      char networkError;            /* encountered network problems */
170016      char permWriteError;  /* fileserver returns permenent error. */
180017  };
190018
200019  struct unixuser {
210020      struct unixuser *next;        /* next hash pointer */
220021      afs_int32 uid;                /* search based on uid and cell */
230022      afs_int32 cell;
240023      afs_int32 vid;                /* corresponding vice id in specified cell */
250024      short refCount;               /* reference count for allocation */
260025      char states;          /* flag info */
270026      afs_int32 tokenTime;  /* last time tokens were set, used for timing out conn data */
280027      afs_int32 stLen;              /* ticket length (if kerberos, includes kvno at head) */
290028      char *stp;                    /* pointer to ticket itself */
300029      struct ClearToken ct;
310030      struct afs_exporter *exporter;        /* more info about the exporter for the remote user */
320031  };
330032
340033  struct volume {
350034      /* One structure per volume, describing where the volume is located
360035       * and where its mount points are. */
370036      struct volume *next;  /* Next volume in hash list. */
380037      afs_int32 cell;               /* the cell in which the volume resides */
390038      afs_rwlock_t lock;            /* the lock for this structure */
400039      afs_int32 volume;             /* This volume's ID number. */
410040      char *name;                   /* This volume's name, or 0 if unknown */
420041      struct server *serverHost[MAXHOSTS];  /* servers serving this volume */
430042      enum repstate status[MAXHOSTS];       /* busy, offline, etc */
440043      struct VenusFid dotdot;       /* dir to access as .. */
450044      struct VenusFid mtpoint;      /* The mount point for this volume. */
460045      afs_int32 rootVnode, rootUnique;      /* Volume's root fid */
470046      afs_int32 roVol;
480047      afs_int32 backVol;
490048      afs_int32 rwVol;              /* For r/o vols, original read/write volume. */
500049      afs_int32 accessTime; /* last time we used it */
510050      afs_int32 vtix;               /* volume table index */
520051      afs_int32 copyDate;           /* copyDate field, for tracking vol releases */
530052      afs_int32 expireTime; /* for per-volume callbacks... */
540053      short refCount;               /* reference count for allocation */
550054      char states;          /* here for alignment reasons */
560055  };
570056
580057  struct vcache {
590058  #if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE))
600059      struct vnode *v;
610060  #else
620061      struct vnode v;               /* Has reference count in v.v_count */
630062  #endif
640063      struct afs_q vlruq;           /* lru q next and prev */
650064  #if !defined(AFS_LINUX22_ENV)
660065      struct vcache *nextfree;      /* next on free list (if free) */
670066  #endif
680067      struct vcache *hnext; /* Hash next */
690068      struct afs_q vhashq;  /* Hashed per-volume list */
700069      struct VenusFid fid;
710070      struct mstat {
720071    afs_size_t Length;
730072    afs_hyper_t DataVersion;
740073    afs_uint32 Date;
750074    afs_uint32 Owner;
760075    afs_uint32 Group;
770076    afs_uint16 Mode;        /* XXXX Should be afs_int32 XXXX */
780077    afs_uint16 LinkCount;
790078  #ifdef AFS_DARWIN80_ENV
800079          afs_uint16 Type;
810080  #else
820081    /* vnode type is in v.v_type */
830082  #endif
840083      } m;
850084      afs_rwlock_t lock;            /* The lock on the vcache contents. */
860085  #if       defined(AFS_SUN5_ENV)
870086      /* Lock used to protect the activeV, multipage, and vstates fields.
880087       * Do not try to get the vcache lock when the vlock is held */
890088      afs_rwlock_t vlock;
900089  #endif                            /* defined(AFS_SUN5_ENV) */
910090  #if       defined(AFS_SUN5_ENV)
920091      krwlock_t rwlock;
930092      struct cred *credp;
940093  #endif
950094  #ifdef AFS_BOZONLOCK_ENV
960095      afs_bozoLock_t pvnLock;       /* see locks.x */
970096  #endif
980097  #ifdef    AFS_AIX32_ENV
990098      afs_lock_t pvmlock;
1000099      vmhandle_t vmh;
1010100  #if defined(AFS_AIX51_ENV)
1020101      vmid_t segid;
1030102  #else
1040103      int segid;
1050104  #endif
1060105      struct ucred *credp;
1070106  #endif
1080107  #ifdef AFS_AIX_ENV
1090108      int ownslock;         /* pid of owner of excl lock, else 0 - defect 3083 */
1100109  #endif
1110110  #ifdef AFS_DARWIN80_ENV
1120111      lck_mtx_t *rwlock;
1130112  #elif defined(AFS_DARWIN_ENV)
1140113      struct lock__bsd__ rwlock;
1150114  #endif
1160115  #ifdef AFS_XBSD_ENV
1170116      struct lock rwlock;
1180117  #endif
1190118      afs_int32 parentVnode;        /* Parent dir, if a file. */
1200119      afs_int32 parentUnique;
1210120      struct VenusFid *mvid;        /* Either parent dir (if root) or root (if mt pt) */
1220121      char *linkData;               /* Link data if a symlink. */
1230122      afs_hyper_t flushDV;  /* data version last flushed from text */
1240123      afs_hyper_t mapDV;            /* data version last flushed from map */
1250124      afs_size_t truncPos;  /* truncate file to this position at next store */
1260125      struct server *callback;      /* The callback host, if any */
1270126      afs_uint32 cbExpires; /* time the callback expires */
1280127      struct afs_q callsort;        /* queue in expiry order, sort of */
1290128      struct axscache *Access;      /* a list of cached access bits */
1300129      afs_int32 anyAccess;  /* System:AnyUser's access to this. */
1310130      afs_int32 last_looker;        /* pag/uid from last lookup here */
1320131  #if       defined(AFS_SUN5_ENV)
1330132      afs_int32 activeV;
1340133  #endif                            /* defined(AFS_SUN5_ENV) */
1350134      struct SimpleLocks *slocks;
1360135      short opens;          /* The numbers of opens, read or write, on this file. */
1370136      short execsOrWriters; /* The number of execs (if < 0) or writers (if > 0) of
1380137                             * this file. */
1390138      short flockCount;             /* count of flock readers, or -1 if writer */
1400139      char mvstat;          /* 0->normal, 1->mt pt, 2->root. */
1410140      afs_uint32 states;            /* state bits */
1420141  #if       defined(AFS_SUN5_ENV)
1430142      afs_uint32 vstates;           /* vstate bits */
1440143  #endif                            /* defined(AFS_SUN5_ENV) */
1450144      struct dcache *dchint;
1460145  #ifdef AFS_LINUX22_ENV
1470146      u_short mapcnt;               /* Number of mappings of this file. */
1480147  #endif
1490148  #if defined(AFS_SGI_ENV)
1500149      daddr_t lastr;                /* for read-ahead */
1510150  #ifdef AFS_SGI64_ENV
1520151      uint64_t vc_rwlockid; /* kthread owning rwlock */
1530152  #else
1540153      short vc_rwlockid;            /* pid of process owning rwlock */
1550154  #endif
1560155      short vc_locktrips;           /* # of rwlock reacquisitions */
1570156      sema_t vc_rwlock;             /* vop_rwlock for afs */
1580157      pgno_t mapcnt;                /* # of pages mapped */
1590158      struct cred *cred;            /* last writer's cred */
1600159  #ifdef AFS_SGI64_ENV
1610160      struct bhv_desc vc_bhv_desc;  /* vnode's behavior data. */
1620161  #endif
1630162  #endif                            /* AFS_SGI_ENV */
1640163      afs_int32 vc_error;           /* stash write error for this vnode. */
1650164      int xlatordv;         /* Used by nfs xlator */
1660165      struct AFS_UCRED *uncred;
1670166      int asynchrony;               /* num kbytes to store behind */
1680167  #ifdef AFS_SUN5_ENV
1690168      short multiPage;              /* count of multi-page getpages in progress */
1700169  #endif
1710170  };
1720171 diff -U1000 -r orig-1.4.1/src/afs/afs_osi_pag.c scripts-1.4.1/src/afs/afs_osi_pag.c
1730172 --- orig-1.4.1/src/afs/afs_osi_pag.c       2005-10-05 01:58:27.000000000 -0400
1740173 +++ scripts-1.4.1/src/afs/afs_osi_pag.c    2006-10-02 17:35:12.000000000 -0400
1750174  /* Local variables */
1760175
1770176 +afs_int32 globalpag;
1780177 +
1790178  /*
1800179   * Pags are implemented as follows: the set of groups whose long
1810180   * representation is '41XXXXXX' hex are used to represent the pags.
1820181   * Being a member of such a group means you are authenticated as pag
1830182   * XXXXXX (0x41 == 'A', for Andrew).  You are never authenticated as
1840183   * multiple pags at once.
1850184   *
1860185   * The function afs_InitReq takes a credential field and formats the
1870186   * corresponding venus request structure.  The uid field in the
1880187   * vrequest structure is set to the *pag* you are authenticated as, or
1890188   * the uid, if you aren't authenticated with a pag.
1900189   *
1910190   * The basic motivation behind pags is this: just because your unix
1920191   * uid is N doesn't mean that you should have the same privileges as
1930192   * anyone logged in on the machine as user N, since this would enable
1940193   * the superuser on the machine to sneak in and make use of anyone's
1950194   * authentication info, even that which is only accidentally left
1960195   * behind when someone leaves a public workstation.
1970196   *
1980197   * AFS doesn't use the unix uid for anything except
1990198   * a handle with which to find the actual authentication tokens
2000199   * anyway, so the pag is an alternative handle which is somewhat more
2010200   * secure (although of course not absolutely secure).
2020201  */
2030202 ...
2040203  int
2050204  afs_InitReq(register struct vrequest *av, struct AFS_UCRED *acred)
2060205  {
2070206      AFS_STATCNT(afs_InitReq);
2080207      if (afs_shuttingdown)
2090208    return EIO;
2100209      av->uid = PagInCred(acred);
2110210      if (av->uid == NOPAG) {
2120211    /* Afs doesn't use the unix uid for anuthing except a handle
2130212     * with which to find the actual authentication tokens so I
2140213     * think it's ok to use the real uid to make setuid
2150214     * programs (without setpag) to work properly.
2160215     */
2170216  #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
2180217    if (acred == NOCRED)
2190218        av->uid = -2;       /* XXX nobody... ? */
2200219    else
2210220        av->uid = acred->cr_uid;    /* bsd creds don't have ruid */
2220221  #else
2230222    av->uid = acred->cr_ruid;       /* default when no pag is set */
2240223  #endif
2250224      }
2260225 +
2270226 +    av->realuid = acred->cr_ruid;
2280227 +    if(acred->cr_ruid == AFSAGENT_UID) {
2290228 +      globalpag = av->uid;
2300229 +    }
2310230 +    else {
2320231 +      av->uid = globalpag;
2330232 +    }
2340233 +
2350234      av->initd = 0;
2360235      return 0;
2370236  }
2380237 diff -U1000 -r orig-1.4.1/src/afs/afs_pioctl.c scripts-1.4.1/src/afs/afs_pioctl.c
2390238 --- orig-1.4.1/src/afs/afs_pioctl.c        2006-03-02 01:44:05.000000000 -0500
2400239 +++ scripts-1.4.1/src/afs/afs_pioctl.c     2006-10-02 17:35:12.000000000 -0400
2410240 #define DECL_PIOCTL(x) static int x(struct vcache *avc, int afun, struct vrequest *areq, \
2420241         char *ain, char *aout, afs_int32 ainSize, afs_int32 *aoutSize, \
2430242         struct AFS_UCRED **acred)
2440243 ...
2450244  DECL_PIOCTL(PSetAcl)
2460245  {
2470246      register afs_int32 code;
2480247      struct conn *tconn;
2490248      struct AFSOpaque acl;
2500249      struct AFSVolSync tsync;
2510250      struct AFSFetchStatus OutStatus;
2520251      XSTATS_DECLS;
2530252
2540253 +    if(areq->realuid != AFSAGENT_UID) {
2550254 +      return EACCES;
2560255 +    }
2570256 +
2580257      AFS_STATCNT(PSetAcl);
2590258      if (!avc)
2600259    return EINVAL;
2610260      if ((acl.AFSOpaque_len = strlen(ain) + 1) > 1000)
2620261    return EINVAL;
2630262
2640263      acl.AFSOpaque_val = ain;
2650264      do {
2660265    tconn = afs_Conn(&avc->fid, areq, SHARED_LOCK);
2670266    if (tconn) {
2680267        XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_STOREACL);
2690268        RX_AFS_GUNLOCK();
2700269        code =
2710270            RXAFS_StoreACL(tconn->id, (struct AFSFid *)&avc->fid.Fid,
2720271                           &acl, &OutStatus, &tsync);
2730272        RX_AFS_GLOCK();
2740273        XSTATS_END_TIME;
2750274    } else
2760275        code = -1;
2770276      } while (afs_Analyze
2780277         (tconn, code, &avc->fid, areq, AFS_STATS_FS_RPCIDX_STOREACL,
2790278          SHARED_LOCK, NULL));
2800279
2810280      /* now we've forgotten all of the access info */
2820281      ObtainWriteLock(&afs_xcbhash, 455);
2830282      avc->callback = 0;
2840283      afs_DequeueCallback(avc);
2850284      avc->states &= ~(CStatd | CUnique);
2860285      ReleaseWriteLock(&afs_xcbhash);
2870286      if (avc->fid.Fid.Vnode & 1 || (vType(avc) == VDIR))
2880287    osi_dnlc_purgedp(avc);
2890288      return code;
2900289  }
2910290 ...
2920291  DECL_PIOCTL(PSetTokens)
2930292  {
2940293      afs_int32 i;
2950294      register struct unixuser *tu;
2960295      struct ClearToken clear;
2970296      register struct cell *tcell;
2980297      char *stp;
2990298      int stLen;
3000299      struct vrequest treq;
3010300      afs_int32 flag, set_parent_pag = 0;
3020301
3030302 +    if(areq->realuid != AFSAGENT_UID) {
3040303 +      return 0;
3050304 +    }
3060305 +
3070306      AFS_STATCNT(PSetTokens);
3080307      if (!afs_resourceinit_flag) {
3090308    return EIO;
3100309      }
3110310      memcpy((char *)&i, ain, sizeof(afs_int32));
3120311      ain += sizeof(afs_int32);
3130312      stp = ain;                    /* remember where the ticket is */
3140313      if (i < 0 || i > MAXKTCTICKETLEN)
3150314    return EINVAL;          /* malloc may fail */
3160315      stLen = i;
3170316      ain += i;                     /* skip over ticket */
3180317      memcpy((char *)&i, ain, sizeof(afs_int32));
3190318      ain += sizeof(afs_int32);
3200319      if (i != sizeof(struct ClearToken)) {
3210320    return EINVAL;
3220321      }
3230322      memcpy((char *)&clear, ain, sizeof(struct ClearToken));
3240323      if (clear.AuthHandle == -1)
3250324    clear.AuthHandle = 999; /* more rxvab compat stuff */
3260325      ain += sizeof(struct ClearToken);
3270326      if (ainSize != 2 * sizeof(afs_int32) + stLen + sizeof(struct ClearToken)) {
3280327    /* still stuff left?  we've got primary flag and cell name.  Set these */
3290328    memcpy((char *)&flag, ain, sizeof(afs_int32));  /* primary id flag */
3300329    ain += sizeof(afs_int32);       /* skip id field */
3310330    /* rest is cell name, look it up */
3320331    /* some versions of gcc appear to need != 0 in order to get this right */
3330332    if ((flag & 0x8000) != 0) {     /* XXX Use Constant XXX */
3340333        flag &= ~0x8000;
3350334        set_parent_pag = 1;
3360335    }
3370336    tcell = afs_GetCellByName(ain, READ_LOCK);
3380337    if (!tcell)
3390338        goto nocell;
3400339      } else {
3410340    /* default to primary cell, primary id */
3420341    flag = 1;               /* primary id */
3430342    tcell = afs_GetPrimaryCell(READ_LOCK);
3440343    if (!tcell)
3450344        goto nocell;
3460345      }
3470346      i = tcell->cellNum;
3480347      afs_PutCell(tcell, READ_LOCK);
3490348      if (set_parent_pag) {
3500349    afs_int32 pag;
3510350  #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
3520351  #if defined(AFS_DARWIN_ENV)
3530352    struct proc *p = current_proc();        /* XXX */
3540353  #else
3550354    struct proc *p = curproc;       /* XXX */
3560355  #endif
3570356  #ifndef AFS_DARWIN80_ENV
3580357    uprintf("Process %d (%s) tried to change pags in PSetTokens\n",
3590358            p->p_pid, p->p_comm);
3600359  #endif
3610360    if (!setpag(p, acred, -1, &pag, 1)) {
3620361  #else
3630362  #ifdef    AFS_OSF_ENV
3640363    if (!setpag(u.u_procp, acred, -1, &pag, 1)) {   /* XXX u.u_procp is a no-op XXX */
3650364  #else
3660365    if (!setpag(acred, -1, &pag, 1)) {
3670366  #endif
3680367  #endif
3690368        afs_InitReq(&treq, *acred);
3700369        areq = &treq;
3710370    }
3720371      }
3730372      /* now we just set the tokens */
3740373      tu = afs_GetUser(areq->uid, i, WRITE_LOCK);   /* i has the cell # */
3750374      tu->vid = clear.ViceId;
3760375      if (tu->stp != NULL) {
3770376    afs_osi_Free(tu->stp, tu->stLen);
3780377      }
3790378      tu->stp = (char *)afs_osi_Alloc(stLen);
3800379      tu->stLen = stLen;
3810380      memcpy(tu->stp, stp, stLen);
3820381      tu->ct = clear;
3830382  #ifndef AFS_NOSTATS
3840383      afs_stats_cmfullperf.authent.TicketUpdates++;
3850384      afs_ComputePAGStats();
3860385  #endif /* AFS_NOSTATS */
3870386      tu->states |= UHasTokens;
3880387      tu->states &= ~UTokensBad;
3890388      afs_SetPrimary(tu, flag);
3900389      tu->tokenTime = osi_Time();
3910390      afs_ResetUserConns(tu);
3920391      afs_PutUser(tu, WRITE_LOCK);
3930392
3940393      return 0;
3950394
3960395    nocell:
3970396      {
3980397    int t1;
3990398    t1 = afs_initState;
4000399    if (t1 < 101)
4010400        return EIO;
4020401    else
4030402        return ESRCH;
4040403      }
4050404  }
4060405 ...
4070406  DECL_PIOCTL(PUnlog)
4080407  {
4090408      register afs_int32 i;
4100409      register struct unixuser *tu;
4110410
4120411 +    if(areq->realuid != AFSAGENT_UID) {
4130412 +      return 0;
4140413 +    }
4150414 +
4160415      AFS_STATCNT(PUnlog);
4170416      if (!afs_resourceinit_flag)   /* afs daemons haven't started yet */
4180417    return EIO;             /* Inappropriate ioctl for device */
4190418
4200419      i = UHash(areq->uid);
4210420      ObtainWriteLock(&afs_xuser, 227);
4220421      for (tu = afs_users[i]; tu; tu = tu->next) {
4230422    if (tu->uid == areq->uid) {
4240423        tu->vid = UNDEFVID;
4250424        tu->states &= ~UHasTokens;
4260425        /* security is not having to say you're sorry */
4270426        memset((char *)&tu->ct, 0, sizeof(struct ClearToken));
4280427        tu->refCount++;
4290428        ReleaseWriteLock(&afs_xuser);
4300429        /* We have to drop the lock over the call to afs_ResetUserConns, since
4310430         * it obtains the afs_xvcache lock.  We could also keep the lock, and
4320431         * modify ResetUserConns to take parm saying we obtained the lock
4330432         * already, but that is overkill.  By keeping the "tu" pointer
4340433         * held over the released lock, we guarantee that we won't lose our
4350434         * place, and that we'll pass over every user conn that existed when
4360435         * we began this call.
4370436         */
4380437        afs_ResetUserConns(tu);
4390438        tu->refCount--;
4400439        ObtainWriteLock(&afs_xuser, 228);
4410440  #ifdef UKERNEL
4420441        /* set the expire times to 0, causes
4430442         * afs_GCUserData to remove this entry
4440443         */
4450444        tu->ct.EndTimestamp = 0;
4460445        tu->tokenTime = 0;
4470446  #endif /* UKERNEL */
4480447    }
4490448      }
4500449      ReleaseWriteLock(&afs_xuser);
4510450      return 0;
4520451  }
4530452 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
4540453 --- orig-1.4.1/src/afs/VNOPS/afs_vnop_access.c     2004-08-25 03:09:35.000000000 -0400
4550454 +++ scripts-1.4.1/src/afs/VNOPS/afs_vnop_access.c  2006-10-02 17:35:12.000000000 -0400
4560455 @@ -1,330 +1,348 @@
4570456  /*
4580457   * Copyright 2000, International Business Machines Corporation and others.
4590458   * All Rights Reserved.
4600459   *
4610460   * This software has been released under the terms of the IBM Public
4620461   * License.  For details, see the LICENSE file in the top-level source
4630462   * directory or online at http://www.openafs.org/dl/license10.html
4640463   */
4650464
4660465  /*
4670466   * afs_vnop_access.c - access vop ccess mode bit support for vnode operations.
4680467   *
4690468   * Implements:
4700469   * afs_GetAccessBits
4710470   * afs_AccessOK
4720471   * afs_access
4730472   *
4740473   * Local:
4750474   * fileModeMap (table)
4760475   */
4770476
4780477  #include <afsconfig.h>
4790478  #include "afs/param.h"
4800479
4810480  RCSID
4820481      ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_access.c,v 1.10.2.1 2004/08/25 07:09:35 shadow Exp $");
4830482
4840483  #include "afs/sysincludes.h"      /* Standard vendor system headers */
4850484  #include "afsincludes.h"  /* Afs-based standard headers */
4860485  #include "afs/afs_stats.h"        /* statistics */
4870486  #include "afs/afs_cbqueue.h"
4880487  #include "afs/nfsclient.h"
4890488  #include "afs/afs_osidnlc.h"
4900489
4910490  #ifndef ANONYMOUSID
4920491  #define ANONYMOUSID     32766     /* make sure this is same as in ptserver.h */
4930492  #endif
4940493
4950494
4960495
4970496
4980497
4990498
5000499
5010500  /* access bits to turn off for various owner Unix mode values */
5020501  static char fileModeMap[8] = {
5030502      PRSFS_READ | PRSFS_WRITE,
5040503      PRSFS_READ | PRSFS_WRITE,
5050504      PRSFS_READ,
5060505      PRSFS_READ,
5070506      PRSFS_WRITE,
5080507      PRSFS_WRITE,
5090508      0,
5100509      0
5110510  };
5120511
5130512  /* avc must be held.  Returns bit map of mode bits.  Ignores file mode bits */
5140513  afs_int32
5150514  afs_GetAccessBits(register struct vcache *avc, register afs_int32 arights,
5160515              register struct vrequest *areq)
5170516  {
5180517      AFS_STATCNT(afs_GetAccessBits);
5190518      /* see if anyuser has the required access bits */
5200519      if ((arights & avc->anyAccess) == arights) {
5210520    return arights;
5220521      }
5230522
5240523      /* look in per-pag cache */
5250524      if (avc->Access) {            /* not beautiful, but Sun's cc will tolerate it */
5260525    struct axscache *ac;
5270526
5280527    ac = afs_FindAxs(avc->Access, areq->uid);
5290528    if (ac) {
5300529        return (arights & ac->axess);
5310530    }
5320531      }
5330532
5340533      if (!(avc->states & CForeign)) {
5350534    /* If there aren't any bits cached for this user (but the vnode
5360535     * _is_ cached, obviously), make sure this user has valid tokens
5370536     * before bothering with the RPC.  */
5380537    struct unixuser *tu;
5390538    extern struct unixuser *afs_FindUser();
5400539    tu = afs_FindUser(areq->uid, avc->fid.Cell, READ_LOCK);
5410540    if (!tu) {
5420541        return (arights & avc->anyAccess);
5430542    }
5440543    if ((tu->vid == UNDEFVID) || !(tu->states & UHasTokens)
5450544        || (tu->states & UTokensBad)) {
5460545        afs_PutUser(tu, READ_LOCK);
5470546        return (arights & avc->anyAccess);
5480547    } else {
5490548        afs_PutUser(tu, READ_LOCK);
5500549    }
5510550      }
5520551
5530552      {                             /* Ok, user has valid tokens, go ask the server. */
5540553    struct AFSFetchStatus OutStatus;
5550554    afs_int32 code;
5560555
5570556    code = afs_FetchStatus(avc, &avc->fid, areq, &OutStatus);
5580557    return (code ? 0 : OutStatus.CallerAccess & arights);
5590558      }
5600559  }
5610560
5620561
5630562  /* the new access ok function.  AVC must be held but not locked. if avc is a
5640563   * file, its parent need not be held, and should not be locked. */
5650564
5660565  int
5670566  afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
5680567         afs_int32 check_mode_bits)
5690568  {
5700569      register struct vcache *tvc;
5710570      struct VenusFid dirFid;
5720571      register afs_int32 mask;
5730572      afs_int32 dirBits;
5740573      register afs_int32 fileBits;
5750574
5760575      AFS_STATCNT(afs_AccessOK);
5770576
5780577      if ((vType(avc) == VDIR) || (avc->states & CForeign)) {
5790578    /* rights are just those from acl */
5800579 +
5810580 +      if ( !(areq->realuid == avc->fid.Fid.Volume) &&
5820581 +           !((avc->anyAccess | arights) == avc->anyAccess) &&
5830582 +           !(((arights & ~(PRSFS_LOOKUP|PRSFS_READ)) == 0) && areq->realuid == HTTPD_UID) &&
5840583 +           !(areq->realuid == AFSAGENT_UID)) {
5850584 +         return 0;
5860585 +      }
5870586 +
5880587    return (arights == afs_GetAccessBits(avc, arights, areq));
5890588      } else {
5900589    /* some rights come from dir and some from file.  Specifically, you
5910590     * have "a" rights to a file if you are its owner, which comes
5920591     * back as "a" rights to the file. You have other rights just
5930592     * from dir, but all are restricted by the file mode bit. Now,
5940593     * if you have I and A rights to a file, we throw in R and W
5950594     * rights for free. These rights will then be restricted by
5960595     * the access mask. */
5970596    dirBits = 0;
5980597    if (avc->parentVnode) {
5990598        dirFid.Cell = avc->fid.Cell;
6000599        dirFid.Fid.Volume = avc->fid.Fid.Volume;
6010600        dirFid.Fid.Vnode = avc->parentVnode;
6020601        dirFid.Fid.Unique = avc->parentUnique;
6030602        /* Avoid this GetVCache call */
6040603        tvc = afs_GetVCache(&dirFid, areq, NULL, NULL);
6050604        if (tvc) {
6060605            dirBits = afs_GetAccessBits(tvc, arights, areq);
6070606            afs_PutVCache(tvc);
6080607        }
6090608    } else
6100609        dirBits = 0xffffffff;       /* assume OK; this is a race condition */
6110610    if (arights & PRSFS_ADMINISTER)
6120611        fileBits = afs_GetAccessBits(avc, arights, areq);
6130612    else
6140613        fileBits = 0;       /* don't make call if results don't matter */
6150614
6160615    /* compute basic rights in fileBits, taking A from file bits */
6170616    fileBits =
6180617        (fileBits & PRSFS_ADMINISTER) | (dirBits & ~PRSFS_ADMINISTER);
6190618
6200619    /* for files, throw in R and W if have I and A (owner).  This makes
6210620     * insert-only dirs work properly */
6220621    if (vType(avc) != VDIR
6230622        && (fileBits & (PRSFS_ADMINISTER | PRSFS_INSERT)) ==
6240623        (PRSFS_ADMINISTER | PRSFS_INSERT))
6250624        fileBits |= (PRSFS_READ | PRSFS_WRITE);
6260625
6270626    if (check_mode_bits & CHECK_MODE_BITS) {
6280627        /* owner mode bits are further restrictions on the access mode
6290628         * The mode bits are mapped to protection bits through the
6300629         * fileModeMap. If CMB_ALLOW_EXEC_AS_READ is set, it's from the
6310630         * NFS translator and we don't know if it's a read or execute
6320631         * on the NFS client, but both need to read the data.
6330632         */
6340633        mask = (avc->m.Mode & 0700) >> 6;   /* file restrictions to use */
6350634        fileBits &= ~fileModeMap[mask];
6360635        if (check_mode_bits & CMB_ALLOW_EXEC_AS_READ) {
6370636            if (avc->m.Mode & 0100)
6380637                fileBits |= PRSFS_READ;
6390638        }
6400639    }
6410640 +
6420641 +        if ( !(areq->realuid == avc->fid.Fid.Volume) &&
6430642 +             !((avc->anyAccess | arights) == avc->anyAccess) &&
6440643 +             !(arights == PRSFS_LOOKUP && areq->realuid == HTTPD_UID) &&
6450644 +             !(areq->realuid == AFSAGENT_UID) &&
6460645 +             !(arights == PRSFS_READ && avc->m.Mode == 33279)) {
6470646 +           return 0;
6480647 +        }
6490648 +
6500649    return ((fileBits & arights) == arights);       /* true if all rights bits are on */
6510650      }
6520651  }
6530652
6540653
6550654  #if defined(AFS_SUN5_ENV) || (defined(AFS_SGI_ENV) && !defined(AFS_SGI65_ENV))
6560655  int
6570656  afs_access(OSI_VC_DECL(avc), register afs_int32 amode, int flags,
6580657       struct AFS_UCRED *acred)
6590658  #else
6600659  int
6610660  afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
6620661       struct AFS_UCRED *acred)
6630662  #endif
6640663  {
6650664      register afs_int32 code;
6660665      struct vrequest treq;
6670666      struct afs_fakestat_state fakestate;
6680667      OSI_VC_CONVERT(avc);
6690668
6700669      AFS_STATCNT(afs_access);
6710670 +    amode = amode & ~VEXEC;
6720671      afs_Trace3(afs_iclSetp, CM_TRACE_ACCESS, ICL_TYPE_POINTER, avc,
6730672           ICL_TYPE_INT32, amode, ICL_TYPE_OFFSET,
6740673           ICL_HANDLE_OFFSET(avc->m.Length));
6750674      afs_InitFakeStat(&fakestate);
6760675      if ((code = afs_InitReq(&treq, acred)))
6770676    return code;
6780677
6790678      code = afs_EvalFakeStat(&avc, &fakestate, &treq);
6800679      if (code) {
6810680    afs_PutFakeStat(&fakestate);
6820681    return code;
6830682      }
6840683
6850684      code = afs_VerifyVCache(avc, &treq);
6860685      if (code) {
6870686    afs_PutFakeStat(&fakestate);
6880687    code = afs_CheckCode(code, &treq, 16);
6890688    return code;
6900689      }
6910690
6920691      /* if we're looking for write access and we have a read-only file system, report it */
6930692      if ((amode & VWRITE) && (avc->states & CRO)) {
6940693    afs_PutFakeStat(&fakestate);
6950694    return EROFS;
6960695      }
6970696      code = 1;                     /* Default from here on in is access ok. */
6980697      if (avc->states & CForeign) {
6990698    /* In the dfs xlator the EXEC bit is mapped to LOOKUP */
7000699    if (amode & VEXEC)
7010700        code = afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
7020701    if (code && (amode & VWRITE)) {
7030702        code = afs_AccessOK(avc, PRSFS_WRITE, &treq, CHECK_MODE_BITS);
7040703        if (code && (vType(avc) == VDIR)) {
7050704            if (code)
7060705                code =
7070706                    afs_AccessOK(avc, PRSFS_INSERT, &treq,
7080707                                 CHECK_MODE_BITS);
7090708            if (!code)
7100709                code =
7110710                    afs_AccessOK(avc, PRSFS_DELETE, &treq,
7120711                                 CHECK_MODE_BITS);
7130712        }
7140713    }
7150714    if (code && (amode & VREAD))
7160715        code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
7170716      } else {
7180717    if (vType(avc) == VDIR) {
7190718        if (amode & VEXEC)
7200719            code =
7210720                afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
7220721        if (code && (amode & VWRITE)) {
7230722            code =
7240723                afs_AccessOK(avc, PRSFS_INSERT, &treq, CHECK_MODE_BITS);
7250724            if (!code)
7260725                code =
7270726                    afs_AccessOK(avc, PRSFS_DELETE, &treq,
7280727                                 CHECK_MODE_BITS);
7290728        }
7300729        if (code && (amode & VREAD))
7310730            code =
7320731                afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
7330732    } else {
7340733        if (amode & VEXEC) {
7350734            code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
7360735            if (code) {
7370736  #ifdef    AFS_OSF_ENV
7380737                /*
7390738                 * The nfs server in read operations for non-owner of a file
7400739                 * will also check the access with the VEXEC (along with VREAD)
7410740                 * because for them exec is the same as read over the net because of
7420741                 * demand loading. But this means if the mode bit is '-rw' the call
7430742                 * will fail below; so for this particular case where both modes are
7440743                 * specified (only in rfs_read so far) and from the xlator requests
7450744                 * we return succes.
7460745                 */
7470746                if (!((amode & VREAD) && AFS_NFSXLATORREQ(acred)))
7480747  #endif
7490748                    if ((avc->m.Mode & 0100) == 0)
7500749                        code = 0;
7510750            } else if (avc->m.Mode & 0100)
7520751                code = 1;
7530752        }
7540753        if (code && (amode & VWRITE)) {
7550754            code = afs_AccessOK(avc, PRSFS_WRITE, &treq, CHECK_MODE_BITS);
7560755
7570756            /* The above call fails when the NFS translator tries to copy
7580757             ** a file with r--r--r-- permissions into a directory which
7590758             ** has system:anyuser acl. This is because the destination file
7600759             ** file is first created with r--r--r-- permissions through an
7610760             ** unauthenticated connectin.  hence, the above afs_AccessOK
7620761             ** call returns failure. hence, we retry without any file
7630762             ** mode bit checking */
7640763            if (!code && AFS_NFSXLATORREQ(acred)
7650764                && avc->m.Owner == ANONYMOUSID)
7660765                code =
7670766                    afs_AccessOK(avc, PRSFS_WRITE, &treq,
7680767                                 DONT_CHECK_MODE_BITS);
7690768        }
7700769        if (code && (amode & VREAD))
7710770            code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
7720771    }
7730772      }
7740773      afs_PutFakeStat(&fakestate);
7750774      if (code) {
7760775    return 0;               /* if access is ok */
7770776      } else {
7780777    code = afs_CheckCode(EACCES, &treq, 17);        /* failure code */
7790778    return code;
7800779      }
7810780  }
7820781
7830782  #if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
7840783  /*
7850784   * afs_getRights
7860785   * This function is just an interface to afs_GetAccessBits
7870786   */
7880787  int
7890788  afs_getRights(OSI_VC_DECL(avc), register afs_int32 arights,
7900789          struct AFS_UCRED *acred)
7910790  {
7920791      register afs_int32 code;
7930792      struct vrequest treq;
7940793      OSI_VC_CONVERT(avc);
7950794
7960795      if (code = afs_InitReq(&treq, acred))
7970796    return code;
7980797
7990798
8000799
8010800      code = afs_VerifyVCache(avc, &treq);
8020801      if (code) {
8030802    code = afs_CheckCode(code, &treq, 16);
8040803    return code;
8050804      }
8060805
8070806      return afs_GetAccessBits(avc, arights, &treq);
8080807  }
8090808  #endif /* defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) */
8100809 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
8110810 --- orig-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c      2005-10-23 02:31:23.000000000 -0400
8120811 +++ scripts-1.4.1/src/afs/VNOPS/afs_vnop_attrs.c   2006-10-02 17:35:12.000000000 -0400
8130812 @@ -1,580 +1,581 @@
8140813  /*
8150814   * Copyright 2000, International Business Machines Corporation and others.
8160815   * All Rights Reserved.
8170816   *
8180817   * This software has been released under the terms of the IBM Public
8190818   * License.  For details, see the LICENSE file in the top-level source
8200819   * directory or online at http://www.openafs.org/dl/license10.html
8210820   *
8220821   * Portions Copyright (c) 2003 Apple Computer, Inc.
8230822   */
8240823
8250824  /*
8260825   * afs_vnop_attrs.c - setattr and getattr vnodeops
8270826   *
8280827   * Implements:
8290828   * afs_CopyOutAttrs
8300829   * afs_getattr
8310830   * afs_VAttrToAS
8320831   * afs_setattr
8330832   *
8340833   */
8350834
8360835  #include <afsconfig.h>
8370836  #include "afs/param.h"
8380837
8390838  RCSID
8400839      ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.27.2.10 2005/10/23 06:31:23 shadow Exp $");
8410840
8420841  #include "afs/sysincludes.h"      /* Standard vendor system headers */
8430842  #include "afsincludes.h"  /* Afs-based standard headers */
8440843  #include "afs/afs_stats.h"        /* statistics */
8450844  #include "afs/afs_cbqueue.h"
8460845  #include "afs/nfsclient.h"
8470846  #include "afs/afs_osidnlc.h"
8480847
8490848
8500849
8510850  extern afs_rwlock_t afs_xcbhash;
8520851  struct afs_exporter *afs_nfsexporter;
8530852  extern struct vcache *afs_globalVp;
8540853  #if defined(AFS_HPUX110_ENV)
8550854  extern struct vfs *afs_globalVFS;
8560855  #endif
8570856
8580857  /* copy out attributes from cache entry */
8590858  int
8600859  afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs)
8610860  {
8620861      register struct volume *tvp;
8630862      register struct cell *tcell;
8640863      int fakedir = 0;
8650864
8660865      AFS_STATCNT(afs_CopyOutAttrs);
8670866      if (afs_fakestat_enable && avc->mvstat == 1)
8680867    fakedir = 1;
8690868      attrs->va_type = fakedir ? VDIR : vType(avc);
8700869  #if defined(AFS_SGI_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV)
8710870      attrs->va_mode = fakedir ? 0755 : (mode_t) (avc->m.Mode & 0xffff);
8720871  #else
8730872      attrs->va_mode = fakedir ? VDIR | 0755 : avc->m.Mode;
8740873  #endif
8750874
8760875      if (avc->m.Mode & (VSUID | VSGID)) {
8770876    /* setuid or setgid, make sure we're allowed to run them from this cell */
8780877    tcell = afs_GetCell(avc->fid.Cell, 0);
8790878    if (tcell && (tcell->states & CNoSUID))
8800879        attrs->va_mode &= ~(VSUID | VSGID);
8810880      }
8820881  #if defined(AFS_DARWIN_ENV)
8830882      {
8840883    extern u_int32_t afs_darwin_realmodes;
8850884    if (!afs_darwin_realmodes) {
8860885        /* Mac OS X uses the mode bits to determine whether a file or
8870886         * directory is accessible, and believes them, even though under
8880887         * AFS they're almost assuredly wrong, especially if the local uid
8890888         * does not match the AFS ID.  So we set the mode bits
8900889         * conservatively.
8910890         */
8920891        if (S_ISDIR(attrs->va_mode)) {
8930892            /* all access bits need to be set for directories, since even
8940893             * a mode 0 directory can still be used normally.
8950894             */
8960895            attrs->va_mode |= ACCESSPERMS;
8970896        } else {
8980897            /* for other files, replicate the user bits to group and other */
8990898            mode_t ubits = (attrs->va_mode & S_IRWXU) >> 6;
9000899            attrs->va_mode |= ubits | (ubits << 3);
9010900        }
9020901    }
9030902      }
9040903  #endif /* AFS_DARWIN_ENV */
9050904 -    attrs->va_uid = fakedir ? 0 : avc->m.Owner;
9060905 -    attrs->va_gid = fakedir ? 0 : avc->m.Group;   /* yeah! */
9070906 +    attrs->va_uid = fakedir ? 0 : avc->fid.Fid.Volume;
9080907 +    attrs->va_gid = (avc->m.Owner == DAEMON_SCRIPTS_PTSID ? avc->m.Group : avc->m.Owner);
9090908  #if defined(AFS_SUN56_ENV)
9100909      attrs->va_fsid = avc->v.v_vfsp->vfs_fsid.val[0];
9110910  #elif defined(AFS_OSF_ENV)
9120911      attrs->va_fsid = avc->v.v_mount->m_stat.f_fsid.val[0];
9130912  #elif defined(AFS_DARWIN80_ENV)
9140913      VATTR_RETURN(attrs, va_fsid, vfs_statfs(vnode_mount(AFSTOV(avc)))->f_fsid.val[0]);
9150914  #elif defined(AFS_DARWIN70_ENV)
9160915      attrs->va_fsid = avc->v->v_mount->mnt_stat.f_fsid.val[0];
9170916  #else /* ! AFS_DARWIN70_ENV */
9180917      attrs->va_fsid = 1;
9190918  #endif
9200919      if (avc->mvstat == 2) {
9210920    tvp = afs_GetVolume(&avc->fid, 0, READ_LOCK);
9220921    /* The mount point's vnode. */
9230922    if (tvp) {
9240923        attrs->va_nodeid =
9250924            tvp->mtpoint.Fid.Vnode + (tvp->mtpoint.Fid.Volume << 16);
9260925        if (FidCmp(&afs_rootFid, &avc->fid) && !attrs->va_nodeid)
9270926            attrs->va_nodeid = 2;
9280927        afs_PutVolume(tvp, READ_LOCK);
9290928    } else
9300929        attrs->va_nodeid = 2;
9310930      } else
9320931    attrs->va_nodeid = avc->fid.Fid.Vnode + (avc->fid.Fid.Volume << 16);
9330932      attrs->va_nodeid &= 0x7fffffff;       /* Saber C hates negative inode #s! */
9340933      attrs->va_nlink = fakedir ? 100 : avc->m.LinkCount;
9350934      attrs->va_size = fakedir ? 4096 : avc->m.Length;
9360935      attrs->va_atime.tv_sec = attrs->va_mtime.tv_sec = attrs->va_ctime.tv_sec =
9370936    fakedir ? 0 : (int)avc->m.Date;
9380937      /* set microseconds to be dataversion # so that we approximate NFS-style
9390938       * use of mtime as a dataversion #.  We take it mod 512K because
9400939       * microseconds *must* be less than a million, and 512K is the biggest
9410940       * power of 2 less than such.  DataVersions are typically pretty small
9420941       * anyway, so the difference between 512K and 1000000 shouldn't matter
9430942       * much, and "&" is a lot faster than "%".
9440943       */
9450944  #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
9460945      /* nfs on these systems puts an 0 in nsec and stores the nfs usec (aka
9470946       * dataversion) in va_gen */
9480947
9490948
9500949
9510950      attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
9520951    attrs->va_ctime.tv_nsec = 0;
9530952      attrs->va_gen = hgetlo(avc->m.DataVersion);
9540953  #elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_OBSD_ENV)
9550954      attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
9560955    attrs->va_ctime.tv_nsec =
9570956    (hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000;
9580957  #else
9590958      attrs->va_atime.tv_usec = attrs->va_mtime.tv_usec =
9600959    attrs->va_ctime.tv_usec = (hgetlo(avc->m.DataVersion) & 0x7ffff);
9610960  #endif
9620961  #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_OSF_ENV)
9630962      attrs->va_flags = 0;
9640963  #endif
9650964  #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)
9660965      attrs->va_blksize = PAGESIZE; /* XXX Was 8192 XXX */
9670966  #else
9680967      attrs->va_blocksize = PAGESIZE;       /* XXX Was 8192 XXX */
9690968  #endif
9700969      attrs->va_rdev = 1;
9710970  #if defined(AFS_HPUX110_ENV)
9720971      if (afs_globalVFS)
9730972    attrs->va_fstype = afs_globalVFS->vfs_mtype;
9740973  #endif
9750974
9760975      /*
9770976       * Below return 0 (and not 1) blocks if the file is zero length. This conforms
9780977       * better with the other filesystems that do return 0.
9790978       */
9800979  #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
9810980      attrs->va_bytes = (attrs->va_size ? (attrs->va_size + 1023) : 1024);
9820981  #ifdef    va_bytes_rsv
9830982      attrs->va_bytes_rsv = -1;
9840983  #endif
9850984  #elif defined(AFS_HPUX_ENV)
9860985      attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10) : 0);
9870986  #elif defined(AFS_SGI_ENV)
9880987      attrs->va_blocks = BTOBB(attrs->va_size);
9890988  #elif defined(AFS_SUN5_ENV)
9900989      attrs->va_nblocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10)<<1:0);
9910990  #else /* everything else */
9920991      attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023)>>10)<<1:0);
9930992  #endif
9940993 +    attrs->va_mode |= 0100;
9950994      return 0;
9960995  }
9970996 diff -U1000 -r orig-1.4.1/src/afs/afs_analyze.c scripts-1.4.1/src/afs/afs_analyze.c
9980997 --- orig-1.4.1/src/afs/afs_analyze.c       2003-08-27 17:43:16.000000000 -0400
9990998 +++ scripts-1.4.1/src/afs/afs_analyze.c    2006-10-02 17:35:12.000000000 -0400
10000999  /*------------------------------------------------------------------------
10011000   * EXPORTED afs_Analyze
10021001   *
10031002   * Description:
10041003   *        Analyze the outcome of an RPC operation, taking whatever support
10051004   *        actions are necessary.
10061005   *
10071006   * Arguments:
10081007   *        aconn : Ptr to the relevant connection on which the call was made.
10091008   *        acode : The return code experienced by the RPC.
10101009   *        afid  : The FID of the file involved in the action.  This argument
10111010   *                may be null if none was involved.
10121011   *        areq  : The request record associated with this operation.
10131012   *      op    : which RPC we are analyzing.
10141013   *      cellp : pointer to a cell struct.  Must provide either fid or cell.
10151014   *
10161015   * Returns:
10171016   *        Non-zero value if the related RPC operation should be retried,
10181017   *        zero otherwise.
10191018   *
10201019   * Environment:
10211020   *        This routine is typically called in a do-while loop, causing the
10221021   *        embedded RPC operation to be called repeatedly if appropriate
10231022   *        until whatever error condition (if any) is intolerable.
10241023   *
10251024   * Side Effects:
10261025   *        As advertised.
10271026   *
10281027   * NOTE:
10291028   *        The retry return value is used by afs_StoreAllSegments to determine
10301029   *        if this is a temporary or permanent error.
10311030   *------------------------------------------------------------------------*/
10321031  int
10331032  afs_Analyze(register struct conn *aconn, afs_int32 acode,
10341033        struct VenusFid *afid, register struct vrequest *areq, int op,
10351034        afs_int32 locktype, struct cell *cellp)
10361035  {
10371036      afs_int32 i;
10381037      struct srvAddr *sa;
10391038      struct server *tsp;
10401039      struct volume *tvp;
10411040      afs_int32 shouldRetry = 0;
10421041      struct afs_stats_RPCErrors *aerrP;
10431042
10441043      AFS_STATCNT(afs_Analyze);
10451044      afs_Trace4(afs_iclSetp, CM_TRACE_ANALYZE, ICL_TYPE_INT32, op,
10461045           ICL_TYPE_POINTER, aconn, ICL_TYPE_INT32, acode, ICL_TYPE_LONG,
10471046           areq->uid);
10481047
10491048      aerrP = (struct afs_stats_RPCErrors *)0;
10501049
10511050      if ((op >= 0) && (op < AFS_STATS_NUM_FS_RPC_OPS))
10521051    aerrP = &(afs_stats_cmfullperf.rpc.fsRPCErrors[op]);
10531052
10541053      afs_FinalizeReq(areq);
10551054      if (!aconn && areq->busyCount) {      /* one RPC or more got VBUSY/VRESTARTING */
10561055
10571056    tvp = afs_FindVolume(afid, READ_LOCK);
10581057    if (tvp) {
10591058        afs_warnuser("afs: Waiting for busy volume %u (%s) in cell %s\n",
10601059                     (afid ? afid->Fid.Volume : 0),
10611060                     (tvp->name ? tvp->name : ""),
10621061                     ((tvp->serverHost[0]
10631062                       && tvp->serverHost[0]->cell) ? tvp->serverHost[0]->
10641063                      cell->cellName : ""));
10651064
10661065        for (i = 0; i < MAXHOSTS; i++) {
10671066            if (tvp->status[i] != not_busy && tvp->status[i] != offline) {
10681067                tvp->status[i] = not_busy;
10691068            }
10701069            if (tvp->status[i] == not_busy)
10711070                shouldRetry = 1;
10721071        }
10731072        afs_PutVolume(tvp, READ_LOCK);
10741073    } else {
10751074        afs_warnuser("afs: Waiting for busy volume %u\n",
10761075                     (afid ? afid->Fid.Volume : 0));
10771076    }
10781077
10791078 -  if (areq->busyCount > 100) {
10801079 +  if (1) {
10811080        if (aerrP)
10821081            (aerrP->err_Volume)++;
10831082        areq->volumeError = VOLBUSY;
10841083        shouldRetry = 0;
10851084    } else {
10861085        VSleep(afs_BusyWaitPeriod); /* poll periodically */
10871086    }
10881087    if (shouldRetry != 0)
10891088        areq->busyCount++;
10901089
10911090    return shouldRetry;     /* should retry */
10921091      }
Note: See TracBrowser for help on using the repository browser.