UKERNEL: add uafs_statvfs
[openafs.git] / src / afs / UKERNEL / afs_usrops.c
index 74dcbca..d52655b 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
-
-
 #ifdef UKERNEL
 
 #include "afs/sysincludes.h"   /* Standard vendor system headers */
 #include <net/if.h>
+
 #include "afsincludes.h"       /* Afs-based standard headers */
 #include "afs_usrops.h"
 #include "afs/afs_stats.h"
 #include "afs/auth.h"
 #include "afs/cellconfig.h"
 #include "afs/vice.h"
+#include "afs/kauth.h"
 #include "afs/kautils.h"
 #include "afs/afsutil.h"
 #include "rx/rx_globals.h"
@@ -56,7 +55,7 @@ char afs_LclCellName[64];
 
 struct usr_vnode *afs_FileTable[MAX_OSI_FILES];
 int afs_FileFlags[MAX_OSI_FILES];
-int afs_FileOffsets[MAX_OSI_FILES];
+off_t afs_FileOffsets[MAX_OSI_FILES];
 
 #define MAX_CACHE_LOOPS 4
 
@@ -100,15 +99,13 @@ int missing_CellInfoFile = 1;
 struct afs_cacheParams cparams;        /* params passed to cache manager */
 struct afsconf_dir *afs_cdir;  /* config dir */
 
-static int HandleMTab();
-
 int afs_bufferpages = 100;
 int usr_udpcksum = 0;
 
 usr_key_t afs_global_u_key;
 
-struct usr_proc *afs_global_procp;
-struct usr_ucred *afs_global_ucredp;
+struct usr_proc *afs_global_procp = NULL;
+struct usr_ucred *afs_global_ucredp = NULL;
 struct usr_sysent usr_sysent[200];
 
 #ifdef AFS_USR_OSF_ENV
@@ -141,6 +138,7 @@ pthread_cond_t usr_sleep_cond;
 #endif /* !NETSCAPE_NSAPI */
 
 int call_syscall(long, long, long, long, long, long);
+int fork_syscall(long, long, long, long, long, long);
 
 
 /*
@@ -183,6 +181,7 @@ int
 ufs_brelse(struct usr_vnode *vp, struct usr_buf *bp)
 {
     usr_assert(0);
+    return 0;
 }
 
 /*
@@ -192,12 +191,14 @@ int
 iodone(struct usr_buf *bp)
 {
     usr_assert(0);
+    return 0;
 }
 
 struct usr_file *
 getf(int fd)
 {
     usr_assert(0);
+    return 0;
 }
 
 /*
@@ -233,6 +234,7 @@ int
 usr_flock(void)
 {
     usr_assert(0);
+    return 0;
 }
 
 /*
@@ -243,33 +245,38 @@ int
 usr_ioctl(void)
 {
     usr_assert(0);
+    return 0;
 }
 
 /*
  * We do not support the inode related system calls
  */
 int
-afs_syscall_icreate(void)
+afs_syscall_icreate(long a, long b, long c, long d, long e, long f)
 {
     usr_assert(0);
+    return 0;
 }
 
 int
-afs_syscall_iincdec(void)
+afs_syscall_iincdec(int dev, int inode, int inode_p1, int amount)
 {
     usr_assert(0);
+    return 0;
 }
 
 int
-afs_syscall_iopen(void)
+afs_syscall_iopen(int dev, int inode, int usrmod)
 {
     usr_assert(0);
+    return 0;
 }
 
 int
 afs_syscall_ireadwrite(void)
 {
     usr_assert(0);
+    return 0;
 }
 
 /*
@@ -280,24 +287,28 @@ int
 vno_close(void)
 {
     usr_assert(0);
+    return 0;
 }
 
 int
 vno_ioctl(void)
 {
     usr_assert(0);
+    return 0;
 }
 
 int
 vno_rw(void)
 {
     usr_assert(0);
+    return 0;
 }
 
 int
 vno_select(void)
 {
     usr_assert(0);
+    return 0;
 }
 
 /*
@@ -374,12 +385,14 @@ usr_crfree(struct usr_ucred *credp)
     if (credp->cr_ref == 0) {
        afs_osi_Free((char *)credp, sizeof(struct usr_ucred));
     }
+    return 0;
 }
 
 int
 usr_crhold(struct usr_ucred *credp)
 {
     credp->cr_ref++;
+    return 0;
 }
 
 void
@@ -517,6 +530,13 @@ afs_osi_Wakeup(void *x)
        waitp = waitp->next;
     }
     usr_mutex_unlock(&osi_waitq_lock);
+    return 0;
+}
+
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
+{
+    return afs_osi_Wait(ams, event, aintok);
 }
 
 int
@@ -608,6 +628,7 @@ afs_osi_CheckTimedWaits(void)
        waitp = waitp->timedNext;
     }
     usr_mutex_unlock(&osi_waitq_lock);
+    return 0;
 }
 
 /*
@@ -684,7 +705,7 @@ lookupname(char *fnamep, int segflg, int followlink,
  * open a file given its i-node number
  */
 void *
-osi_UFSOpen(afs_int32 ino)
+osi_UFSOpen(afs_dcache_id_t *ino)
 {
     int rc;
     struct osi_file *fp;
@@ -692,31 +713,30 @@ osi_UFSOpen(afs_int32 ino)
 
     AFS_ASSERT_GLOCK();
 
-    if (ino > n_osi_files) {
-       u.u_error = ENOENT;
+    if (ino->ufs > n_osi_files) {
+       get_user_struct()->u_error = ENOENT;
        return NULL;
     }
 
     AFS_GUNLOCK();
     fp = (struct osi_file *)afs_osi_Alloc(sizeof(struct osi_file));
     usr_assert(fp != NULL);
-    fp->fd = open(osi_file_table[ino - 1].name, O_RDWR | O_CREAT, 0);
+    fp->fd = open(osi_file_table[ino->ufs - 1].name, O_RDWR | O_CREAT, 0);
     if (fp->fd < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        afs_osi_Free((char *)fp, sizeof(struct osi_file));
        AFS_GLOCK();
        return NULL;
     }
     rc = fstat(fp->fd, &st);
     if (rc < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        afs_osi_Free((void *)fp, sizeof(struct osi_file));
        AFS_GLOCK();
        return NULL;
     }
     fp->size = st.st_size;
     fp->offset = 0;
-    fp->inum = ino;
     fp->vnode = (struct usr_vnode *)fp;
 
     AFS_GLOCK();
@@ -733,7 +753,7 @@ osi_UFSClose(struct osi_file *fp)
     AFS_GUNLOCK();
     rc = close(fp->fd);
     if (rc < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        afs_osi_Free((void *)fp, sizeof(struct osi_file));
        AFS_GLOCK();
        return -1;
@@ -753,7 +773,7 @@ osi_UFSTruncate(struct osi_file *fp, afs_int32 len)
     AFS_GUNLOCK();
     rc = ftruncate(fp->fd, len);
     if (rc < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        AFS_GLOCK();
        return -1;
     }
@@ -766,7 +786,6 @@ int
 afs_osi_Read(struct osi_file *fp, int offset, void *buf, afs_int32 len)
 {
     int rc, ret;
-    int code;
     struct stat st;
 
     AFS_ASSERT_GLOCK();
@@ -778,21 +797,21 @@ afs_osi_Read(struct osi_file *fp, int offset, void *buf, afs_int32 len)
        rc = lseek(fp->fd, fp->offset, SEEK_SET);
     }
     if (rc < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        AFS_GLOCK();
        return -1;
     }
     fp->offset = rc;
     ret = read(fp->fd, buf, len);
     if (ret < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        AFS_GLOCK();
        return -1;
     }
     fp->offset += ret;
     rc = fstat(fp->fd, &st);
     if (rc < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        AFS_GLOCK();
        return -1;
     }
@@ -805,7 +824,6 @@ int
 afs_osi_Write(struct osi_file *fp, afs_int32 offset, void *buf, afs_int32 len)
 {
     int rc, ret;
-    int code;
     struct stat st;
 
     AFS_ASSERT_GLOCK();
@@ -817,21 +835,21 @@ afs_osi_Write(struct osi_file *fp, afs_int32 offset, void *buf, afs_int32 len)
        rc = lseek(fp->fd, fp->offset, SEEK_SET);
     }
     if (rc < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        AFS_GLOCK();
        return -1;
     }
     fp->offset = rc;
     ret = write(fp->fd, buf, len);
     if (ret < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        AFS_GLOCK();
        return -1;
     }
     fp->offset += ret;
     rc = fstat(fp->fd, &st);
     if (rc < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        AFS_GLOCK();
        return -1;
     }
@@ -849,7 +867,7 @@ afs_osi_Stat(struct osi_file *fp, struct osi_stat *stp)
     AFS_GUNLOCK();
     rc = fstat(fp->fd, &st);
     if (rc < 0) {
-       u.u_error = errno;
+       get_user_struct()->u_error = errno;
        AFS_GLOCK();
        return -1;
     }
@@ -886,7 +904,7 @@ afs_osi_VOP_RDWR(struct usr_vnode *vnodeP, struct usr_uio *uioP, int rw,
                          uioP->uio_iov[0].iov_len);
     }
     if (rc < 0) {
-       return u.u_error;
+       return get_user_struct()->u_error;
     }
 
     uioP->uio_resid -= rc;
@@ -896,13 +914,6 @@ afs_osi_VOP_RDWR(struct usr_vnode *vnodeP, struct usr_uio *uioP, int rw,
     return 0;
 }
 
-/*
- * Use malloc/free routines with check patterns before and after each block
- */
-
-static char *afs_check_string1 = "UAFS";
-static char *afs_check_string2 = "AFS_OSI_";
-
 void *
 afs_osi_Alloc(size_t size)
 {
@@ -987,6 +998,12 @@ afs_osi_Invisible(void)
     return;
 }
 
+void
+afs_osi_Visible(void)
+{
+    return;
+}
+
 int
 osi_GetTime(struct timeval *tv)
 {
@@ -1010,7 +1027,7 @@ osi_Active(struct vcache *avc)
 }
 
 int
-afs_osi_MapStrategy(int (*aproc) (), struct usr_buf *bp)
+afs_osi_MapStrategy(int (*aproc) (struct usr_buf *), struct usr_buf *bp)
 {
     afs_int32 returnCode;
     returnCode = (*aproc) (bp);
@@ -1018,16 +1035,16 @@ afs_osi_MapStrategy(int (*aproc) (), struct usr_buf *bp)
 }
 
 void
-osi_FlushPages(register struct vcache *avc, struct AFS_UCRED *credp)
+osi_FlushPages(register struct vcache *avc, afs_ucred_t *credp)
 {
     ObtainSharedLock(&avc->lock, 555);
-    if ((hcmp((avc->m.DataVersion), (avc->mapDV)) <= 0)
+    if ((hcmp((avc->f.m.DataVersion), (avc->mapDV)) <= 0)
        || ((avc->execsOrWriters > 0) && afs_DirtyPages(avc))) {
        ReleaseSharedLock(&avc->lock);
        return;
     }
     UpgradeSToWLock(&avc->lock, 565);
-    hset(avc->mapDV, avc->m.DataVersion);
+    hset(avc->mapDV, avc->f.m.DataVersion);
     ReleaseWriteLock(&avc->lock);
     return;
 }
@@ -1035,8 +1052,8 @@ osi_FlushPages(register struct vcache *avc, struct AFS_UCRED *credp)
 void
 osi_FlushText_really(register struct vcache *vp)
 {
-    if (hcmp(vp->m.DataVersion, vp->flushDV) > 0) {
-       hset(vp->flushDV, vp->m.DataVersion);
+    if (hcmp(vp->f.m.DataVersion, vp->flushDV) > 0) {
+       hset(vp->flushDV, vp->f.m.DataVersion);
     }
     return;
 }
@@ -1057,8 +1074,6 @@ void
 osi_Init(void)
 {
     int i;
-    int rc;
-    usr_thread_t tid;
 
     /*
      * Allocate the table used to implement psuedo-inodes.
@@ -1291,8 +1306,16 @@ SweepAFSCache(int *vFilesFound)
     for (currp = readdir(cdirp); currp; currp = readdir(cdirp)) {
        if (afsd_debug) {
            printf("%s: Current directory entry:\n", rn);
+#if defined(AFS_SGI62_ENV) || defined(AFS_USR_DARWIN100_ENV)
+            printf("\tinode=%" AFS_INT64_FMT ", reclen=%d, name='%s'\n",
+                  currp->d_ino, currp->d_reclen, currp->d_name);
+#elif defined(AFS_USR_DFBSD_ENV)
+           printf("\tinode=%d, name='%s'\n", currp->d_ino,
+                  currp->d_name);
+#else
            printf("\tinode=%d, reclen=%d, name='%s'\n", currp->d_ino,
                   currp->d_reclen, currp->d_name);
+#endif
        }
 
        /*
@@ -1389,8 +1412,8 @@ SweepAFSCache(int *vFilesFound)
     return (0);
 }
 
-static
-ConfigCell(register struct afsconf_cell *aci, char *arock,
+static int
+ConfigCell(register struct afsconf_cell *aci, void *arock,
           struct afsconf_dir *adir)
 {
     register int isHomeCell;
@@ -1420,10 +1443,7 @@ ConfigCell(register struct afsconf_cell *aci, char *arock,
 }
 
 static int
-ConfigCellAlias(aca, arock, adir)
-       struct afsconf_cellalias *aca;
-       char *arock;
-       struct afsconf_dir *adir;
+ConfigCellAlias(struct afsconf_cellalias *aca, void *arock, struct afsconf_dir *adir)
 {
        call_syscall(AFSOP_ADDCELLALIAS, (long)aca->aliasName, 
                     (long)aca->realName, 0, 0, 0);
@@ -1452,8 +1472,6 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
          int nDaemonsParam, int cacheFlagsParam, char *logFile)
 {
     int st;
-    struct usr_proc *procp;
-    struct usr_ucred *ucredp;
     int i;
     int rc;
     int currVFile;             /* Current AFS cache file number */
@@ -1461,8 +1479,6 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
     int cacheIteration;                /* cache verification loop counter */
     int vFilesFound;           /* Num data cache files found in sweep */
     FILE *logfd;
-    afs_int32 vfs1_type = -1;
-    struct afs_ioctl iob;
     char tbuffer[1024];
     char *p;
     char lastchar;
@@ -1482,12 +1498,12 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
        afs_osi_Alloc(sizeof(struct usr_ucred));
     usr_assert(afs_global_ucredp != NULL);
     afs_global_ucredp->cr_ref = 1;
-    afs_global_ucredp->cr_uid = geteuid();
-    afs_global_ucredp->cr_gid = getegid();
-    afs_global_ucredp->cr_ruid = getuid();
-    afs_global_ucredp->cr_rgid = getgid();
-    afs_global_ucredp->cr_suid = afs_global_ucredp->cr_ruid;
-    afs_global_ucredp->cr_sgid = afs_global_ucredp->cr_rgid;
+    afs_set_cr_uid(afs_global_ucredp, geteuid());
+    afs_set_cr_gid(afs_global_ucredp, getegid());
+    afs_set_cr_ruid(afs_global_ucredp, getuid());
+    afs_set_cr_rgid(afs_global_ucredp, getgid());
+    afs_global_ucredp->cr_suid = afs_cr_ruid(afs_global_ucredp);
+    afs_global_ucredp->cr_sgid = afs_cr_rgid(afs_global_ucredp);
     st = getgroups(NGROUPS, &afs_global_ucredp->cr_groups[0]);
     usr_assert(st >= 0);
     afs_global_ucredp->cr_ngroups = (unsigned long)st;
@@ -1501,7 +1517,7 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
     afs_global_procp = (struct usr_proc *)
        afs_osi_Alloc(sizeof(struct usr_proc));
     usr_assert(afs_global_procp != NULL);
-    afs_global_procp->p_pid = getpid();
+    afs_global_procp->p_pid = osi_getpid();
     afs_global_procp->p_ppid = (pid_t) 1;
     afs_global_procp->p_ucred = afs_global_ucredp;
 
@@ -1541,7 +1557,7 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
        cacheStatEntries = cacheStatEntriesParam;
     }
     strcpy(cacheBaseDir, cacheBaseDirParam);
-    if (nDaemons != 0) {
+    if (nDaemonsParam != 0) {
        nDaemons = nDaemonsParam;
     } else {
        nDaemons = 3;
@@ -1617,11 +1633,6 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
            printf("%s: My home cell is '%s'\n", rn, afs_LclCellName);
     }
 
-    /*
-     * Set the primary cell name.
-     */
-    call_syscall(AFSOP_SET_THISCELL, (long)afs_LclCellName, 0, 0, 0, 0);
-
     if ((logfd = fopen(fullpn_AFSLogFile, "r+")) == 0) {
        if (afsd_verbose)
            printf("%s: Creating '%s'\n", rn, fullpn_AFSLogFile);
@@ -1645,8 +1656,9 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
     }
     memset(pathname_for_V, 0, (cacheFiles * sizeof(char *)));
     if (afsd_debug)
-       printf("%s: %d pathname_for_V entries at 0x%x, %d bytes\n", rn,
-              cacheFiles, pathname_for_V, (cacheFiles * sizeof(AFSD_INO_T)));
+       printf("%s: %d pathname_for_V entries at %" AFS_PTR_FMT
+              ", %lud bytes\n", rn, cacheFiles, pathname_for_V,
+              afs_printable_uint32_lu(cacheFiles * sizeof(AFSD_INO_T)));
 
     /*
      * Set up all the pathnames we'll need for later.
@@ -1657,24 +1669,6 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
     sprintf(fullpn_VFile, "%s/V", cacheBaseDir);
     vFileNumber = fullpn_VFile + strlen(fullpn_VFile);
 
-    /*
-     * Start the RX listener.
-     */
-    if (afsd_debug)
-       printf("%s: Calling AFSOP_RXLISTENER_DAEMON\n", rn);
-    fork_syscall(AFSCALL_CALL, AFSOP_RXLISTENER_DAEMON, FALSE, FALSE, FALSE);
-
-    /*
-     * Start the RX event handler.
-     */
-    if (afsd_debug)
-       printf("%s: Calling AFSOP_RXEVENT_DAEMON\n", rn);
-    fork_syscall(AFSCALL_CALL, AFSOP_RXEVENT_DAEMON, FALSE);
-
-    /*
-     * Set up all the kernel processes needed for AFS.
-     */
-
     /* initialize AFS callback interface */
     {
        /* parse multihomed address files */
@@ -1693,12 +1687,30 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
        }
     }
 
+    /*
+     * Start the RX listener.
+     */
+    if (afsd_debug)
+       printf("%s: Calling AFSOP_RXLISTENER_DAEMON\n", rn);
+    fork_syscall(AFSCALL_CALL, AFSOP_RXLISTENER_DAEMON, FALSE, FALSE, FALSE, 0);
+
     if (afsd_verbose)
        printf("%s: Forking rx callback listener.\n", rn);
     /* Child */
     if (preallocs < cacheStatEntries + 50)
        preallocs = cacheStatEntries + 50;
-    fork_syscall(AFSCALL_CALL, AFSOP_START_RXCALLBACK, preallocs);
+    fork_syscall(AFSCALL_CALL, AFSOP_START_RXCALLBACK, preallocs, 0, 0, 0);
+
+    /*
+     * Start the RX event handler.
+     */
+    if (afsd_debug)
+       printf("%s: Calling AFSOP_RXEVENT_DAEMON\n", rn);
+    fork_syscall(AFSCALL_CALL, AFSOP_RXEVENT_DAEMON, FALSE, 0, 0, 0);
+
+    /*
+     * Set up all the kernel processes needed for AFS.
+     */
 
     if (afsd_verbose)
        printf("%s: Initializing AFS daemon.\n", rn);
@@ -1794,18 +1806,23 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
     afsconf_CellApply(afs_cdir, ConfigCell, NULL);
     afsconf_CellAliasApply(afs_cdir, ConfigCellAlias, NULL);
 
+    /*
+     * Set the primary cell name.
+     */
+    call_syscall(AFSCALL_CALL, AFSOP_SET_THISCELL, (long)afs_LclCellName, 0, 0, 0);
+
     if (afsd_verbose)
        printf("%s: Forking AFS daemon.\n", rn);
-    fork_syscall(AFSCALL_CALL, AFSOP_START_AFS);
+    fork_syscall(AFSCALL_CALL, AFSOP_START_AFS, 0, 0, 0, 0);
 
     if (afsd_verbose)
        printf("%s: Forking check server daemon.\n", rn);
-    fork_syscall(AFSCALL_CALL, AFSOP_START_CS);
+    fork_syscall(AFSCALL_CALL, AFSOP_START_CS, 0, 0, 0, 0);
 
     if (afsd_verbose)
        printf("%s: Forking %d background daemons.\n", rn, nDaemons);
     for (i = 0; i < nDaemons; i++) {
-       fork_syscall(AFSCALL_CALL, AFSOP_START_BKG);
+       fork_syscall(AFSCALL_CALL, AFSOP_START_BKG, 0, 0, 0, 0);
     }
 
     if (afsd_verbose)
@@ -1826,7 +1843,11 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
                         (long)pathname_for_V[currVFile], 0, 0, 0);
        }
     /*end for */
-#ifndef NETSCAPE_NSAPI
+/*#ifndef NETSCAPE_NSAPI*/
+#if 0
+/* this breaks solaris if the kernel-mode client has never been installed,
+ * and it doesn't seem to work now anyway, so just disable it */
+
     /*
      * Copy our tokens from the kernel to the user space client
      */
@@ -1849,7 +1870,7 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
        rc = lpioctl(0, _VICEIOCTL(8), &iob, 0);
 #endif
        if (rc < 0) {
-           usr_assert(errno == EDOM || errno == ENOSYS);
+           usr_assert(errno == EDOM || errno == ENOSYS || errno == ERANGE);
            break;
        }
 
@@ -1877,7 +1898,7 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
 
     if (afsd_verbose)
        printf("%s: Forking trunc-cache daemon.\n", rn);
-    fork_syscall(AFSCALL_CALL, AFSOP_START_TRUNCDAEMON);
+    fork_syscall(AFSCALL_CALL, AFSOP_START_TRUNCDAEMON, 0, 0, 0, 0);
 
     /*
      * Mount the AFS filesystem
@@ -1898,6 +1919,25 @@ uafs_Init(char *rn, char *mountDirParam, char *confDirParam,
     return;
 }
 
+int
+uafs_statvfs(struct statvfs *buf)
+{
+    int rc;
+
+    AFS_GLOCK();
+
+    rc = afs_statvfs(&afs_RootVfs, buf);
+
+    AFS_GUNLOCK();
+
+    if (rc) {
+       errno = rc;
+       return -1;
+    }
+
+    return 0;
+}
+
 void
 uafs_Shutdown(void)
 {
@@ -1965,10 +2005,10 @@ syscallThread(void *argp)
     /*
      * AFS daemons run authenticated
      */
-    u.u_viceid = getuid();
-    crp = u.u_cred;
-    crp->cr_uid = getuid();
-    crp->cr_ruid = getuid();
+    get_user_struct()->u_viceid = getuid();
+    crp = get_user_struct()->u_cred;
+    afs_set_cr_uid(crp, getuid());
+    afs_set_cr_ruid(crp, getuid());
     crp->cr_suid = getuid();
     crp->cr_groups[0] = getgid();
     crp->cr_ngroups = 1;
@@ -1980,10 +2020,12 @@ syscallThread(void *argp)
                 sysArgsP->param2, sysArgsP->param3, sysArgsP->param4);
 
     afs_osi_Free(argp, -1);
+    return 0;
 }
 
-fork_syscall(syscall, afscall, param1, param2, param3, param4)
-     long syscall, afscall, param1, param2, param3, param4;
+int
+fork_syscall(long syscall, long afscall, long param1, long param2,
+            long param3, long param4)
 {
     usr_thread_t tid;
     struct syscallThreadArgs *sysArgsP;
@@ -2000,10 +2042,12 @@ fork_syscall(syscall, afscall, param1, param2, param3, param4)
 
     usr_thread_create(&tid, syscallThread, sysArgsP);
     usr_thread_detach(tid);
+    return 0;
 }
 
-call_syscall(syscall, afscall, param1, param2, param3, param4)
-     long syscall, afscall, param1, param2, param3, param4;
+int
+call_syscall(long syscall, long afscall, long param1, long param2,
+            long param3, long param4)
 {
     int code = 0;
     struct a {
@@ -2022,8 +2066,8 @@ call_syscall(syscall, afscall, param1, param2, param3, param4)
     a.parm3 = param3;
     a.parm4 = param4;
 
-    u.u_error = 0;
-    u.u_ap = (char *)&a;
+    get_user_struct()->u_error = 0;
+    get_user_struct()->u_ap = (char *)&a;
 
     code = Afs_syscall();
     return code;
@@ -2040,6 +2084,7 @@ uafs_SetTokens(char *tbuffer, int tlen)
     iob.in_size = tlen;
     iob.out = &outbuf[0];
     iob.out_size = sizeof(outbuf);
+
     rc = call_syscall(AFSCALL_PIOCTL, 0, _VICEIOCTL(3), (long)&iob, 0, 0);
     if (rc != 0) {
        errno = rc;
@@ -2179,14 +2224,15 @@ int
 uafs_LookupName(char *path, struct usr_vnode *parentVp,
                struct usr_vnode **vpp, int follow, int no_eval_mtpt)
 {
-    int code;
+    int code = 0;
     int linkCount;
     struct usr_vnode *vp;
     struct usr_vnode *nextVp;
     struct usr_vnode *linkVp;
+    struct vcache *nextVc;
     char *tmpPath;
     char *pathP;
-    char *nextPathP;
+    char *nextPathP = NULL;
 
     AFS_ASSERT_GLOCK();
 
@@ -2242,7 +2288,7 @@ uafs_LookupName(char *path, struct usr_vnode *parentVp,
            /*
             * We need execute permission to search a directory
             */
-           code = afs_access(VTOAFS(vp), VEXEC, u.u_cred);
+           code = afs_access(VTOAFS(vp), VEXEC, get_user_struct()->u_cred);
            if (code != 0) {
                VN_RELE(vp);
                afs_osi_Free(tmpPath, strlen(path) + 1);
@@ -2253,17 +2299,20 @@ uafs_LookupName(char *path, struct usr_vnode *parentVp,
             * lookup the next component in the path, we can release the
             * subdirectory since we hold the global lock
             */
+           nextVc = NULL;
            nextVp = NULL;
 #ifdef AFS_WEB_ENHANCEMENTS
            if ((nextPathP != NULL && *nextPathP != '\0') || !no_eval_mtpt)
-               code = afs_lookup(vp, pathP, &nextVp, u.u_cred, 0);
+               code = afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred, 0);
            else
                code =
-                   afs_lookup(vp, pathP, &nextVp, u.u_cred,
+                   afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred,
                               AFS_LOOKUP_NOEVAL);
 #else
-           code = afs_lookup(vp, pathP, &nextVp, u.u_cred, 0);
+           code = afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred, 0);
 #endif /* AFS_WEB_ENHANCEMENTS */
+           if (nextVc)
+               nextVp=AFSTOV(nextVc);
            if (code != 0) {
                VN_RELE(vp);
                afs_osi_Free(tmpPath, strlen(path) + 1);
@@ -2353,7 +2402,7 @@ uafs_LookupLink(struct usr_vnode *vp, struct usr_vnode *parentVp,
     /*
      * Read the link data
      */
-    code = afs_readlink(vp, &uio, u.u_cred);
+    code = afs_readlink(VTOAFS(vp), &uio, get_user_struct()->u_cred);
     if (code) {
        afs_osi_Free(pathP, MAX_OSI_PATH + 1);
        return code;
@@ -2516,7 +2565,7 @@ uafs_mkdir_r(char *path, int mode)
     int code;
     char *nameP;
     struct vnode *parentP;
-    struct vnode *dirP;
+    struct vcache *dirP;
     struct usr_vattr attrs;
 
     if (uafs_IsRoot(path)) {
@@ -2554,16 +2603,16 @@ uafs_mkdir_r(char *path, int mode)
     usr_vattr_null(&attrs);
     attrs.va_type = VREG;
     attrs.va_mode = mode;
-    attrs.va_uid = u.u_cred->cr_uid;
-    attrs.va_gid = u.u_cred->cr_gid;
+    attrs.va_uid = afs_cr_uid(get_user_struct()->u_cred);
+    attrs.va_gid = afs_cr_gid(get_user_struct()->u_cred);
     dirP = NULL;
-    code = afs_mkdir(parentP, nameP, &attrs, &dirP, u.u_cred);
+    code = afs_mkdir(VTOAFS(parentP), nameP, &attrs, &dirP, get_user_struct()->u_cred);
     VN_RELE(parentP);
     if (code != 0) {
        errno = code;
        return -1;
     }
-    VN_RELE(dirP);
+    VN_RELE(AFSTOV(dirP));
     return 0;
 }
 
@@ -2653,8 +2702,8 @@ uafs_open_r(char *path, int flags, int mode)
            usr_vattr_null(&attrs);
            attrs.va_type = VREG;
            attrs.va_mode = mode;
-           attrs.va_uid = u.u_cred->cr_uid;
-           attrs.va_gid = u.u_cred->cr_gid;
+           attrs.va_uid = afs_cr_uid(get_user_struct()->u_cred);
+           attrs.va_gid = afs_cr_gid(get_user_struct()->u_cred);
            if (flags & O_TRUNC) {
                attrs.va_size = 0;
            }
@@ -2663,12 +2712,13 @@ uafs_open_r(char *path, int flags, int mode)
            code =
                afs_create(VTOAFS(dirP), nameP, &attrs,
                           (flags & O_EXCL) ? usr_EXCL : usr_NONEXCL, mode,
-                          &vc, u.u_cred);
+                          &vc, get_user_struct()->u_cred);
            VN_RELE(dirP);
            if (code != 0) {
                errno = code;
                return -1;
            }
+           fileP = AFSTOV(vc);
        } else {
            fileP = NULL;
            code = uafs_LookupName(nameP, dirP, &fileP, 1, 0);
@@ -2690,7 +2740,7 @@ uafs_open_r(char *path, int flags, int mode)
            }
            if (!fileMode)
                fileMode = VREAD;       /* since O_RDONLY is 0 */
-           code = afs_access(VTOAFS(fileP), fileMode, u.u_cred);
+           code = afs_access(VTOAFS(fileP), fileMode, get_user_struct()->u_cred);
            if (code != 0) {
                VN_RELE(fileP);
                errno = code;
@@ -2700,7 +2750,7 @@ uafs_open_r(char *path, int flags, int mode)
            /*
             * Get the file attributes, all we need is the size
             */
-           code = afs_getattr(VTOAFS(fileP), &attrs, u.u_cred);
+           code = afs_getattr(VTOAFS(fileP), &attrs, get_user_struct()->u_cred);
            if (code != 0) {
                VN_RELE(fileP);
                errno = code;
@@ -2741,8 +2791,9 @@ uafs_open_r(char *path, int flags, int mode)
      */
     if ((flags & O_TRUNC) && (attrs.va_size != 0)) {
        usr_vattr_null(&attrs);
+       attrs.va_mask = ATTR_SIZE;
        attrs.va_size = 0;
-       code = afs_setattr(VTOAFS(fileP), &attrs, u.u_cred);
+       code = afs_setattr(VTOAFS(fileP), &attrs, get_user_struct()->u_cred);
        if (code != 0) {
            VN_RELE(fileP);
            errno = code;
@@ -2754,7 +2805,7 @@ uafs_open_r(char *path, int flags, int mode)
     /*
      * do the open
      */
-    code = afs_open(&vc, openFlags, u.u_cred);
+    code = afs_open(&vc, openFlags, get_user_struct()->u_cred);
     if (code != 0) {
        VN_RELE(fileP);
        errno = code;
@@ -2812,13 +2863,23 @@ uafs_write(int fd, char *buf, int len)
 {
     int retval;
     AFS_GLOCK();
-    retval = uafs_write_r(fd, buf, len);
+    retval = uafs_pwrite_r(fd, buf, len, afs_FileOffsets[fd]);
+    AFS_GUNLOCK();
+    return retval;
+}
+
+int
+uafs_pwrite(int fd, char *buf, int len, off_t offset)
+{
+    int retval;
+    AFS_GLOCK();
+    retval = uafs_pwrite_r(fd, buf, len, offset);
     AFS_GUNLOCK();
     return retval;
 }
 
 int
-uafs_write_r(int fd, char *buf, int len)
+uafs_pwrite_r(int fd, char *buf, int len, off_t offset)
 {
     int code;
     struct usr_uio uio;
@@ -2841,7 +2902,7 @@ uafs_write_r(int fd, char *buf, int len)
     iov[0].iov_len = len;
     uio.uio_iov = &iov[0];
     uio.uio_iovcnt = 1;
-    uio.uio_offset = afs_FileOffsets[fd];
+    uio.uio_offset = offset;
     uio.uio_segflg = 0;
     uio.uio_fmode = FWRITE;
     uio.uio_resid = len;
@@ -2850,7 +2911,7 @@ uafs_write_r(int fd, char *buf, int len)
      * do the write
      */
 
-    code = afs_write(VTOAFS(fileP), &uio, afs_FileFlags[fd], u.u_cred, 0);
+    code = afs_write(VTOAFS(fileP), &uio, afs_FileFlags[fd], get_user_struct()->u_cred, 0);
     if (code) {
        errno = code;
        return -1;
@@ -2868,13 +2929,23 @@ uafs_read(int fd, char *buf, int len)
 {
     int retval;
     AFS_GLOCK();
-    retval = uafs_read_r(fd, buf, len);
+    retval = uafs_pread_r(fd, buf, len, afs_FileOffsets[fd]);
     AFS_GUNLOCK();
     return retval;
 }
 
 int
-uafs_read_r(int fd, char *buf, int len)
+uafs_pread(int fd, char *buf, int len, off_t offset)
+{
+    int retval;
+    AFS_GLOCK();
+    retval = uafs_pread_r(fd, buf, len, offset);
+    AFS_GUNLOCK();
+    return retval;
+}
+
+int
+uafs_pread_r(int fd, char *buf, int len, off_t offset)
 {
     int code;
     struct usr_uio uio;
@@ -2898,7 +2969,7 @@ uafs_read_r(int fd, char *buf, int len)
     iov[0].iov_len = len;
     uio.uio_iov = &iov[0];
     uio.uio_iovcnt = 1;
-    uio.uio_offset = afs_FileOffsets[fd];
+    uio.uio_offset = offset;
     uio.uio_segflg = 0;
     uio.uio_fmode = FREAD;
     uio.uio_resid = len;
@@ -2906,7 +2977,7 @@ uafs_read_r(int fd, char *buf, int len)
     /*
      * do the read
      */
-    code = afs_read(VTOAFS(fileP), &uio, u.u_cred, 0, &bufP, 0);
+    code = afs_read(VTOAFS(fileP), &uio, get_user_struct()->u_cred, 0, &bufP, 0);
     if (code) {
        errno = code;
        return -1;
@@ -2932,7 +3003,7 @@ uafs_GetAttr(struct usr_vnode *vp, struct stat *stats)
     /*
      * Get the attributes
      */
-    code = afs_getattr(VTOAFS(vp), &attrs, u.u_cred);
+    code = afs_getattr(VTOAFS(vp), &attrs, get_user_struct()->u_cred);
     if (code != 0) {
        return code;
     }
@@ -3082,8 +3153,9 @@ uafs_chmod_r(char *path, int mode)
        return -1;
     }
     usr_vattr_null(&attrs);
+    attrs.va_mask = ATTR_MODE;
     attrs.va_mode = mode;
-    code = afs_setattr(VTOAFS(vp), &attrs, u.u_cred);
+    code = afs_setattr(VTOAFS(vp), &attrs, get_user_struct()->u_cred);
     VN_RELE(vp);
     if (code != 0) {
        errno = code;
@@ -3118,8 +3190,9 @@ uafs_fchmod_r(int fd, int mode)
        return -1;
     }
     usr_vattr_null(&attrs);
+    attrs.va_mask = ATTR_MODE;
     attrs.va_mode = mode;
-    code = afs_setattr(VTOAFS(vp), &attrs, u.u_cred);
+    code = afs_setattr(VTOAFS(vp), &attrs, get_user_struct()->u_cred);
     if (code != 0) {
        errno = code;
        return -1;
@@ -3153,8 +3226,9 @@ uafs_truncate_r(char *path, int length)
        return -1;
     }
     usr_vattr_null(&attrs);
+    attrs.va_mask = ATTR_SIZE;
     attrs.va_size = length;
-    code = afs_setattr(VTOAFS(vp), &attrs, u.u_cred);
+    code = afs_setattr(VTOAFS(vp), &attrs, get_user_struct()->u_cred);
     VN_RELE(vp);
     if (code != 0) {
        errno = code;
@@ -3189,8 +3263,9 @@ uafs_ftruncate_r(int fd, int length)
        return -1;
     }
     usr_vattr_null(&attrs);
+    attrs.va_mask = ATTR_SIZE;
     attrs.va_size = length;
-    code = afs_setattr(VTOAFS(vp), &attrs, u.u_cred);
+    code = afs_setattr(VTOAFS(vp), &attrs, get_user_struct()->u_cred);
     if (code != 0) {
        errno = code;
        return -1;
@@ -3232,7 +3307,7 @@ uafs_lseek_r(int fd, int offset, int whence)
        newpos = offset;
        break;
     case SEEK_END:
-       code = afs_getattr(VTOAFS(vp), &attrs, u.u_cred);
+       code = afs_getattr(VTOAFS(vp), &attrs, get_user_struct()->u_cred);
        if (code != 0) {
            errno = code;
            return -1;
@@ -3277,7 +3352,7 @@ uafs_fsync_r(int fd)
        return -1;
     }
 
-    code = afs_fsync(fileP, u.u_cred);
+    code = afs_fsync(VTOAFS(fileP), get_user_struct()->u_cred);
     if (code != 0) {
        errno = code;
        return -1;
@@ -3312,7 +3387,7 @@ uafs_close_r(int fd)
     }
     afs_FileTable[fd] = NULL;
 
-    code = afs_close(fileP, afs_FileFlags[fd], u.u_cred);
+    code = afs_close(VTOAFS(fileP), afs_FileFlags[fd], get_user_struct()->u_cred);
     VN_RELE(fileP);
     if (code != 0) {
        errno = code;
@@ -3387,7 +3462,7 @@ uafs_link_r(char *existing, char *new)
     /*
      * Create the link
      */
-    code = afs_link(existP, dirP, nameP, u.u_cred);
+    code = afs_link(VTOAFS(existP), VTOAFS(dirP), nameP, get_user_struct()->u_cred);
     VN_RELE(existP);
     VN_RELE(dirP);
     if (code != 0) {
@@ -3454,9 +3529,9 @@ uafs_symlink_r(char *target, char *source)
     usr_vattr_null(&attrs);
     attrs.va_type = VLNK;
     attrs.va_mode = 0777;
-    attrs.va_uid = u.u_cred->cr_uid;
-    attrs.va_gid = u.u_cred->cr_gid;
-    code = afs_symlink(dirP, nameP, &attrs, target, u.u_cred);
+    attrs.va_uid = afs_cr_uid(get_user_struct()->u_cred);
+    attrs.va_gid = afs_cr_gid(get_user_struct()->u_cred);
+    code = afs_symlink(VTOAFS(dirP), nameP, &attrs, target, get_user_struct()->u_cred);
     VN_RELE(dirP);
     if (code != 0) {
        errno = code;
@@ -3513,7 +3588,7 @@ uafs_readlink_r(char *path, char *buf, int len)
     /*
      * Read the the link
      */
-    code = afs_readlink(vp, &uio, u.u_cred);
+    code = afs_readlink(VTOAFS(vp), &uio, get_user_struct()->u_cred);
     VN_RELE(vp);
     if (code) {
        errno = code;
@@ -3544,8 +3619,6 @@ int
 uafs_unlink_r(char *path)
 {
     int code;
-    int openFlags;
-    struct usr_vnode *fileP;
     struct usr_vnode *dirP;
     char *nameP;
 
@@ -3581,7 +3654,7 @@ uafs_unlink_r(char *path)
     /*
      * Remove the file
      */
-    code = afs_remove(dirP, nameP, u.u_cred);
+    code = afs_remove(VTOAFS(dirP), nameP, get_user_struct()->u_cred);
     VN_RELE(dirP);
     if (code != 0) {
        errno = code;
@@ -3658,7 +3731,7 @@ uafs_rename_r(char *old, char *new)
     /*
      * Rename the file
      */
-    code = afs_rename(odirP, onameP, ndirP, nnameP, u.u_cred);
+    code = afs_rename(VTOAFS(odirP), onameP, VTOAFS(ndirP), nnameP, get_user_struct()->u_cred);
     VN_RELE(odirP);
     VN_RELE(ndirP);
     if (code != 0) {
@@ -3687,8 +3760,6 @@ int
 uafs_rmdir_r(char *path)
 {
     int code;
-    int openFlags;
-    struct usr_vnode *fileP;
     struct usr_vnode *dirP;
     char *nameP;
 
@@ -3724,7 +3795,7 @@ uafs_rmdir_r(char *path)
     /*
      * Remove the directory
      */
-    code = afs_rmdir(dirP, nameP, u.u_cred);
+    code = afs_rmdir(VTOAFS(dirP), nameP, get_user_struct()->u_cred);
     VN_RELE(dirP);
     if (code != 0) {
        errno = code;
@@ -3872,7 +3943,7 @@ uafs_getdents_r(int fd, struct min_direct *buf, int len)
     /*
      * read the next chunk from the directory
      */
-    code = afs_readdir(vp, &uio, u.u_cred);
+    code = afs_readdir(VTOAFS(vp), &uio, get_user_struct()->u_cred);
     if (code != 0) {
        errno = code;
        return -1;
@@ -3898,7 +3969,6 @@ uafs_readdir(usr_DIR * dirp)
 struct usr_dirent *
 uafs_readdir_r(usr_DIR * dirp)
 {
-    int rc;
     int code;
     int len;
     struct usr_uio uio;
@@ -3907,6 +3977,11 @@ uafs_readdir_r(usr_DIR * dirp)
     struct usr_dirent *direntP;
     struct min_direct *directP;
 
+    if (!dirp) {
+       errno = EBADF;
+       return NULL;
+    }
+
     /*
      * Make sure this is an open file
      */
@@ -3937,7 +4012,7 @@ uafs_readdir_r(usr_DIR * dirp)
        /*
         * read the next chunk from the directory
         */
-       code = afs_readdir(vp, &uio, u.u_cred);
+       code = afs_readdir(VTOAFS(vp), &uio, get_user_struct()->u_cred);
        if (code != 0) {
            errno = code;
            return NULL;
@@ -3994,6 +4069,11 @@ uafs_closedir_r(usr_DIR * dirp)
     int fd;
     int rc;
 
+    if (!dirp) {
+       errno = EBADF;
+       return -1;
+    }
+
     fd = dirp->dd_fd;
     afs_osi_Free((char *)dirp,
                 sizeof(usr_DIR) + USR_DIRSIZE + sizeof(struct usr_dirent));
@@ -4135,7 +4215,7 @@ uafs_getcellstatus(char *cell, afs_int32 * status)
        return -1;
     }
 
-    *status = (afs_int32) iob.out;
+    *status = (intptr_t)iob.out;
     return 0;
 }
 
@@ -4212,8 +4292,6 @@ int
 uafs_statmountpoint(char *path)
 {
     int retval;
-    int code;
-    char buf[256];
 
     AFS_GLOCK();
     retval = uafs_statmountpoint_r(path);
@@ -4227,7 +4305,6 @@ uafs_statmountpoint_r(char *path)
     int code;
     struct vnode *vp;
     struct vcache *avc;
-    struct vrequest treq;
     int r;
 
     code = uafs_LookupName(path, afs_CurrentDir, &vp, 0, 1);
@@ -4250,7 +4327,7 @@ uafs_statmountpoint_r(char *path)
 int
 uafs_getRights(char *path)
 {
-    int code, rc;
+    int code;
     struct vnode *vp;
     int afs_rights;
 
@@ -4266,7 +4343,7 @@ uafs_getRights(char *path)
        PRSFS_READ | PRSFS_WRITE | PRSFS_INSERT | PRSFS_LOOKUP | PRSFS_DELETE
        | PRSFS_LOCK | PRSFS_ADMINISTER;
 
-    afs_rights = afs_getRights(vp, afs_rights, u.u_cred);
+    afs_rights = afs_getRights(VTOAFS(vp), afs_rights, get_user_struct()->u_cred);
 
     AFS_GUNLOCK();
     return afs_rights;