afs: Properly type afs_osi_suser cred arg
[openafs.git] / src / afs / afs_osi_pag.c
index 170dd61..c0667d9 100644 (file)
@@ -32,7 +32,7 @@
 
 
 /* Imported variables */
-extern int afs_shuttingdown;
+extern enum afs_shutdown_state afs_shuttingdown;
 
 /* Exported variables */
 afs_uint32 pag_epoch;
@@ -42,13 +42,6 @@ afs_uint32 pagCounter = 1;
 afs_uint32 pagCounter = 0;
 #endif /* UKERNEL */
 
-#ifdef AFS_LINUX26_ONEGROUP_ENV
-#define NUMPAGGROUPS 1
-#else
-#define NUMPAGGROUPS 2
-#endif
-/* Local variables */
-
 /*
  * Pags are implemented as follows: the set of groups whose long
  * representation is '41XXXXXX' hex are used to represent the pags.
@@ -146,7 +139,7 @@ static int afs_pag_sleepcnt = 0;
 static int afs_pag_timewarn = 0;
 
 static int
-afs_pag_sleep(afs_ucred_t **acred)
+afs_pag_sleep(afs_ucred_t *acred)
 {
     int rv = 0;
 
@@ -167,8 +160,10 @@ afs_pag_sleep(afs_ucred_t **acred)
 }
 
 static int
-afs_pag_wait(afs_ucred_t **acred)
+afs_pag_wait(afs_ucred_t *acred)
 {
+    int code = 0;
+
     if (afs_pag_sleep(acred)) {
        if (!afs_pag_sleepcnt) {
            afs_warn("%s() PAG throttling triggered, pid %d... sleeping.  sleepcnt %d\n",
@@ -178,14 +173,13 @@ afs_pag_wait(afs_ucred_t **acred)
        afs_pag_sleepcnt++;
 
        do {
-           /* XXX spins on EINTR */
-           afs_osi_Wait(1000, (struct afs_osi_WaitHandle *)0, 0);
-       } while (afs_pag_sleep(acred));
+           code = afs_osi_Wait(1000, (struct afs_osi_WaitHandle *)0, 0);
+       } while (!code && afs_pag_sleep(acred));
 
        afs_pag_sleepcnt--;
     }
 
-    return 0;
+    return code;
 }
 
 int
@@ -203,11 +197,11 @@ afs_setpag(void)
 {
 
 #if     defined(AFS_SUN5_ENV)
-    afs_ucred_t **acred = *credpp;
+    afs_ucred_t *acred = *credpp;
 #elif  defined(AFS_OBSD_ENV)
-    afs_ucred_t **acred = &p->p_ucred;
+    afs_ucred_t *acred = p->p_ucred;
 #else
-    afs_ucred_t **acred = NULL;
+    afs_ucred_t *acred = NULL;
 #endif
 
     int code = 0;
@@ -219,7 +213,10 @@ afs_setpag(void)
 
     AFS_STATCNT(afs_setpag);
 
-    afs_pag_wait(acred);
+    code = afs_pag_wait(acred);
+    if (code) {
+       goto done;
+    }
 
 
 #if    defined(AFS_SUN5_ENV)
@@ -278,6 +275,7 @@ afs_setpag(void)
     code = AddPag(genpag(), &u.u_cred);
 #endif
 
+  done:
     afs_Trace1(afs_iclSetp, CM_TRACE_SETPAG, ICL_TYPE_INT32, code);
 
 #if defined(KERNEL_HAVE_UERROR)
@@ -313,11 +311,11 @@ afs_setpag_val(int pagval)
 {
 
 #if     defined(AFS_SUN5_ENV)
-    afs_ucred_t **acred = *credp;
+    afs_ucred_t *acred = *credp;
 #elif  defined(AFS_OBSD_ENV)
-    afs_ucred_t **acred = &p->p_ucred;
+    afs_ucred_t *acred = p->p_ucred;
 #else
-    afs_ucred_t **acred = NULL;
+    afs_ucred_t *acred = NULL;
 #endif
 
     int code = 0;
@@ -329,7 +327,10 @@ afs_setpag_val(int pagval)
 
     AFS_STATCNT(afs_setpag);
 
-    afs_pag_wait(acred);
+    code = afs_pag_wait(acred);
+    if (code) {
+       goto done;
+    }
 
 #if    defined(AFS_SUN5_ENV)
     code = AddPag(pagval, credpp);
@@ -379,6 +380,7 @@ afs_setpag_val(int pagval)
     code = AddPag(pagval, &u.u_cred);
 #endif
 
+  done:
     afs_Trace1(afs_iclSetp, CM_TRACE_SETPAG, ICL_TYPE_INT32, code);
 #if defined(KERNEL_HAVE_UERROR)
     if (!getuerror())
@@ -390,7 +392,7 @@ afs_setpag_val(int pagval)
     return (code);
 }
 
-#ifndef AFS_LINUX26_ONEGROUP_ENV
+#ifndef AFS_PAG_ONEGROUP_ENV
 int
 afs_getpag_val(void)
 {
@@ -455,7 +457,7 @@ afs_InitReq(struct vrequest *av, afs_ucred_t *acred)
 
     AFS_STATCNT(afs_InitReq);
     memset(av, 0, sizeof(*av));
-    if (afs_shuttingdown)
+    if (afs_shuttingdown == AFS_SHUTDOWN)
        return EIO;
 
 #ifdef AFS_LINUX26_ENV
@@ -480,13 +482,67 @@ afs_InitReq(struct vrequest *av, afs_ucred_t *acred)
 #elif defined(AFS_SUN510_ENV)
         av->uid = crgetruid(acred);
 #else
-       av->uid = afs_cr_uid(acred);    /* default when no pag is set */
+       av->uid = afs_cr_ruid(acred);   /* default when no pag is set */
 #endif
     }
     return 0;
 }
 
-#ifndef AFS_LINUX26_ONEGROUP_ENV
+/*!
+ * Allocate and setup a vrequest.
+ *
+ * \note The caller must free the allocated vrequest with
+ *       afs_DestroyReq() if this function returns successfully (zero).
+ *
+ * \note The GLOCK must be held on platforms which require the GLOCK
+ *       for osi_AllocSmallSpace() and osi_FreeSmallSpace().
+ *
+ * \param[out] avpp   address of the vrequest pointer
+ * \param[in]  acred  user credentials to setup the vrequest
+ *                    afs_osi_credp should be used for anonymous connections
+ * \return     0 on success
+ */
+int
+afs_CreateReq(struct vrequest **avpp, afs_ucred_t *acred)
+{
+    int code;
+    struct vrequest *treq = NULL;
+
+    if (afs_shuttingdown == AFS_SHUTDOWN) {
+       return EIO;
+    }
+    if (!avpp || !acred) {
+       return EINVAL;
+    }
+    treq = osi_AllocSmallSpace(sizeof(struct vrequest));
+    if (!treq) {
+       return ENOMEM;
+    }
+    code = afs_InitReq(treq, acred);
+    if (code != 0) {
+       osi_FreeSmallSpace(treq);
+       return code;
+    }
+    *avpp = treq;
+    return 0;
+}
+
+/*!
+ * Deallocate a vrequest.
+ *
+ * \note The GLOCK must be held on platforms which require the GLOCK
+ *       for osi_FreeSmallSpace().
+ *
+ * \param[in]  av  pointer to the vrequest to free; may be NULL
+ */
+void
+afs_DestroyReq(struct vrequest *av)
+{
+    if (av) {
+       osi_FreeSmallSpace(av);
+    }
+}
+
 afs_uint32
 afs_get_pag_from_groups(gid_t g0a, gid_t g1a)
 {
@@ -514,6 +570,7 @@ afs_get_pag_from_groups(gid_t g0a, gid_t g1a)
     return NOPAG;
 }
 
+#ifndef AFS_PAG_ONEGROUP_ENV
 void
 afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p)
 {
@@ -533,7 +590,8 @@ afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p)
     *g1p = g1 + 0x3f00;
 }
 #else
-void afs_get_groups_from_pag(afs_uint32 pag, gid_t *g0p, gid_t *g1p)
+void
+afs_get_groups_from_pag(afs_uint32 pag, gid_t *g0p, gid_t *g1p)
 {
     AFS_STATCNT(afs_get_groups_from_pag);
     *g0p = pag;
@@ -541,7 +599,13 @@ void afs_get_groups_from_pag(afs_uint32 pag, gid_t *g0p, gid_t *g1p)
 }
 #endif
 
-#if !defined(AFS_LINUX26_ENV) && !defined(AFS_DARWIN110_ENV)
+#ifdef AFS_LINUX26_ENV
+/* osi_get_group_pag is defined in <ARCH>/osi_groups.c */
+#elif defined(AFS_PAG_ONEGROUP_ENV)
+/* osi_get_group_pag is defined in <ARCH>/osi_groups.c */
+#elif defined(AFS_DARWIN110_ENV)
+/* We don't have pags, so we do not define an osi_get_group_pag */
+#else
 static afs_int32
 osi_get_group_pag(afs_ucred_t *cred)
 {
@@ -576,7 +640,7 @@ osi_get_group_pag(afs_ucred_t *cred)
     if (cred->cr_ngrps < 2)
        return NOPAG;
 # elif defined(AFS_LINUX26_ENV)
-    if (afs_cr_group_info(cred)->ngroups < NUMPAGGROUPS)
+    if (afs_cr_group_info(cred)->ngroups < AFS_NUMPAGGROUPS)
        return NOPAG;
 # elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_XBSD_ENV)
 #  if defined(AFS_SUN510_ENV)