CRED_UNLOCK();
memset(tmp, 0, sizeof(cred_t));
+#if defined(AFS_LINUX26_ENV)
+ tmp->cr_group_info = groups_alloc(0);
+#endif
tmp->cr_ref = 1;
return tmp;
}
crfree(cred_t * cr)
{
if (cr->cr_ref > 1) {
+#if defined(AFS_LINUX26_ENV)
+ put_group_info(cr->cr_group_info);
+#endif
cr->cr_ref--;
return;
}
crdup(cred_t * cr)
{
cred_t *tmp = crget();
- *tmp = *cr;
+
+ tmp->cr_uid = cr->cr_uid;
+ tmp->cr_ruid = cr->cr_ruid;
+ tmp->cr_gid = cr->cr_gid;
+#if defined(AFS_LINUX26_ENV)
+{
+ struct group_info *old_info;
+
+ old_info = tmp->cr_group_info;
+ get_group_info(cr->cr_group_info);
+ tmp->cr_group_info = cr->cr_group_info;
+ put_group_info(old_info);
+}
+#else
+ memcpy(tmp->cr_groups, cr->cr_groups, NGROUPS * sizeof(gid_t));
+ tmp->cr_ngroups = cr->cr_ngroups;
+#endif
+
tmp->cr_ref = 1;
return tmp;
}
crref(void)
{
cred_t *cr = crget();
+
cr->cr_uid = current->fsuid;
cr->cr_ruid = current->uid;
cr->cr_gid = current->fsgid;
cr->cr_rgid = current->gid;
#if defined(AFS_LINUX26_ENV)
{
- int i;
+ struct group_info *old_info;
- for(i = 0; i < current->group_info->ngroups && i < NGROUPS; ++i)
- cr->cr_groups[i] = GROUP_AT(current->group_info, i);
- cr->cr_ngroups = current->group_info->ngroups;
+ old_info = cr->cr_group_info;
+ get_group_info(current->group_info);
+ cr->cr_group_info = current->group_info;
+ put_group_info(old_info);
}
#else
memcpy(cr->cr_groups, current->groups, NGROUPS * sizeof(gid_t));
current->gid = cr->cr_rgid;
#if defined(AFS_LINUX26_ENV)
{
- struct group_info *new_info;
- int i;
+ struct group_info *old_info;
- new_info = groups_alloc(cr->cr_ngroups);
- for(i = 0; i < cr->cr_ngroups; ++i)
- GROUP_AT(new_info, i) = cr->cr_groups[i];
- set_current_groups(new_info);
- put_group_info(new_info);
+ /* using set_current_groups() will sort the groups */
+ old_info = current->group_info;
+ get_group_info(cr->cr_group_info);
+ current->group_info = cr->cr_group_info;
+ put_group_info(old_info);
}
#else
memcpy(current->groups, cr->cr_groups, NGROUPS * sizeof(gid_t));
#include "h/smp_lock.h"
#endif
-static int afs_getgroups(cred_t * cr, gid_t * groups);
-static int afs_setgroups(cred_t ** cr, int ngroups, gid_t * gidset,
- int change_parent);
+#if defined(AFS_LINUX26_ENV)
+static int
+afs_setgroups(cred_t **cr, struct group_info *group_info, int change_parent)
+{
+ struct group_info *old_info;
-/* Only propogate the PAG to the parent process. Unix's propogate to
- * all processes sharing the cred.
- */
-int
-set_pag_in_parent(int pag, int g0, int g1)
+ AFS_STATCNT(afs_setgroups);
+
+ old_info = (*cr)->cr_group_info;
+ get_group_info(group_info);
+ (*cr)->cr_group_info = group_info;
+ put_group_info(old_info);
+
+ crset(*cr);
+
+ if (change_parent) {
+ old_info = current->parent->group_info;
+ get_group_info(group_info);
+ current->parent->group_info = group_info;
+ put_group_info(old_info);
+ }
+
+ return (0);
+}
+#else
+static int
+afs_setgroups(cred_t **cr, int ngroups, gid_t * gidset, int change_parent)
{
+ int ngrps;
int i;
-#if defined(AFS_LINUX26_ENV)
- struct group_info *old_info, *new_info;
+ gid_t *gp;
- old_info = current->parent->group_info;
- new_info = groups_alloc(old_info->ngroups + 2);
+ AFS_STATCNT(afs_setgroups);
- for(i = 0; i < old_info->ngroups; ++i)
- GROUP_AT(new_info, i) = GROUP_AT(old_info, i);
+ if (ngroups > NGROUPS)
+ return EINVAL;
- GROUP_AT(new_info, i++) = g0;
- GROUP_AT(new_info, i++) = g1;
+ gp = (*cr)->cr_groups;
+ if (ngroups < NGROUPS)
+ gp[ngroups] = (gid_t) NOGROUP;
- current->parent->group_info = new_info;
- put_group_info(old_info);
+ for (i = ngroups; i > 0; i--) {
+ *gp++ = *gidset++;
+ }
+
+ (*cr)->cr_ngroups = ngroups;
+ crset(*cr);
+ return (0);
+}
+#endif
+
+#if defined(AFS_LINUX26_ENV)
+static struct group_info *
+afs_getgroups(cred_t * cr)
+{
+ AFS_STATCNT(afs_getgroups);
+
+ get_group_info(cr->cr_group_info);
+ return cr->cr_group_info;
+}
#else
+/* Returns number of groups. And we trust groups to be large enough to
+ * hold all the groups.
+ */
+static int
+afs_getgroups(cred_t *cr, gid_t *groups)
+{
+ int i;
+ AFS_STATCNT(afs_getgroups);
+
+ gid_t *gp = cr->cr_groups;
+ int n = cr->cr_ngroups;
+
+ for (i = 0; (i < n) && (*gp != (gid_t) NOGROUP); i++)
+ *groups++ = *gp++;
+ return i;
+}
+#endif
+
+#if !defined(AFS_LINUX26_ENV)
+/* Only propogate the PAG to the parent process. Unix's propogate to
+ * all processes sharing the cred.
+ */
+int
+set_pag_in_parent(int pag, int g0, int g1)
+{
+ int i;
#ifdef STRUCT_TASK_STRUCT_HAS_PARENT
gid_t *gp = current->parent->groups;
int ngroups = current->parent->ngroups;
#else
current->p_pptr->ngroups = ngroups;
#endif
-#endif
return 0;
}
+#endif
int
setpag(cred_t ** cr, afs_uint32 pagvalue, afs_uint32 * newpag,
int change_parent)
{
+#if defined(AFS_LINUX26_ENV)
+ struct group_info *group_info;
+ gid_t g0, g1;
+
+ AFS_STATCNT(setpag);
+
+ group_info = afs_getgroups(*cr);
+ g0 = GROUP_AT(group_info, 0);
+ g1 = GROUP_AT(group_info, 1);
+
+ if (afs_get_pag_from_groups(g0, g1) == NOPAG) {
+ /* We will have to make sure group_info is big enough for pag */
+ struct group_info *tmp;
+ int i;
+
+ tmp = groups_alloc(group_info->ngroups + 2);
+ for (i = 0; i < group_info->ngroups; ++i)
+ GROUP_AT(tmp, i + 2) = GROUP_AT(group_info, i);
+ put_group_info(group_info);
+ group_info = tmp;
+ }
+
+ *newpag = (pagvalue == -1 ? genpag() : pagvalue);
+ afs_get_groups_from_pag(*newpag, &g0, &g1);
+ GROUP_AT(group_info, 0) = g0;
+ GROUP_AT(group_info, 1) = g1;
+
+ afs_setgroups(cr, group_info, change_parent);
+
+ put_group_info(group_info);
+
+ return 0;
+#else
gid_t *gidset;
afs_int32 ngroups, code = 0;
int j;
osi_Free((char *)gidset, NGROUPS * sizeof(int));
return code;
+#endif
}
#endif
#endif
-static int
-afs_setgroups(cred_t ** cr, int ngroups, gid_t * gidset, int change_parent)
-{
- int ngrps;
- int i;
- gid_t *gp;
-
- AFS_STATCNT(afs_setgroups);
-
- if (ngroups > NGROUPS)
- return EINVAL;
-
- gp = (*cr)->cr_groups;
- if (ngroups < NGROUPS)
- gp[ngroups] = (gid_t) NOGROUP;
-
- for (i = ngroups; i > 0; i--) {
- *gp++ = *gidset++;
- }
-
- (*cr)->cr_ngroups = ngroups;
- crset(*cr);
- return (0);
-}
-
-/* Returns number of groups. And we trust groups to be large enough to
- * hold all the groups.
- */
-static int
-afs_getgroups(cred_t * cr, gid_t * groups)
-{
- int i;
- gid_t *gp = cr->cr_groups;
- int n = cr->cr_ngroups;
- AFS_STATCNT(afs_getgroups);
-
- for (i = 0; (i < n) && (*gp != (gid_t) NOGROUP); i++) {
- *groups++ = *gp++;
- }
- return i;
-}
#undef gop_lookupname
#define gop_lookupname osi_lookupname
-#define osi_vnhold(v, n) VN_HOLD(v)
+#define osi_vnhold(v, n) do { VN_HOLD(AFSTOV(v)); } while (0)
+
+#if defined(AFS_LINUX24_ENV)
+#define VN_HOLD(V) atomic_inc(&((vnode_t *) V)->i_count)
+#else
+#define VN_HOLD(V) ((vnode_t *) V)->i_count++
+#endif
+
+#if defined(AFS_LINUX26_ENV)
+#define VN_RELE(V) iput((struct inode *) V)
+#else
+#define VN_RELE(V) osi_iput((struct inode *) V)
+#endif
#define osi_AllocSmall afs_osi_Alloc
#define osi_FreeSmall afs_osi_Free
#define PAGESIZE PAGE_SIZE
-#ifndef NGROUPS
-#define NGROUPS NGROUPS_MAX
-#endif
/* cred struct */
typedef struct cred { /* maps to task field: */
uid_t cr_ruid; /* uid */
gid_t cr_gid; /* egid */
gid_t cr_rgid; /* gid */
+#if defined(AFS_LINUX26_ENV)
+ struct group_info *cr_group_info;
+#else
gid_t cr_groups[NGROUPS]; /* 32 groups - empty set to NOGROUP */
int cr_ngroups;
+#endif
} cred_t;
#define AFS_UCRED cred
#define AFS_PROC struct task_struct
afs_InactiveVCache(vcp, credp);
ObtainWriteLock(&vcp->lock, 504);
-#if defined(AFS_LINUX24_ENV)
- atomic_set(&ip->i_count, 0);
-#else
- ip->i_count = 0;
-#endif
ip->i_nlink = 0; /* iput checks this after calling this routine. */
+ ip->i_state = I_CLEAR;
ReleaseWriteLock(&vcp->lock);
crfree(credp);
}
+#if !defined(AFS_LINUX26_ENV)
/* iput an inode. Since we still have a separate inode pool, we don't want
* to call iput on AFS inodes, since they would then end up on Linux's
* inode_unsed list.
#else
if (!--ip->i_count)
#endif
- osi_clear_inode(ip);
+ {
+ osi_clear_inode(ip);
+ ip->i_state = 0;
+ }
AFS_GUNLOCK();
}
+#endif
/* check_bad_parent() : Checks if this dentry's vcache is a root vcache
* that has its mvid (parent dir's fid) pointer set to the wrong directory
afs_lookup(pvc, dp->d_name.name, &avc, credp);
if (!avc || vcp != avc) { /* bad, very bad.. */
afs_Trace4(afs_iclSetp, CM_TRACE_TMP_1S3L, ICL_TYPE_STRING,
- "afs_linux_revalidate : bad pointer returned from afs_lookup origvc newvc dentry",
+ "check_bad_parent: bad pointer returned from afs_lookup origvc newvc dentry",
ICL_TYPE_POINTER, vcp, ICL_TYPE_POINTER, avc,
ICL_TYPE_POINTER, dp);
}
#define FSYNC O_SYNC
#define VTOI(V) ((struct inode*)V)
-#ifdef AFS_LINUX24_ENV
-#define VN_HOLD(V) atomic_inc(&((vnode_t*)V)->i_count)
-#else
-#define VN_HOLD(V) ((vnode_t*)V)->i_count++;
-#endif
-#define VN_RELE(V) osi_iput((struct inode *)V);
#define VFS_STATFS(V, S) ((V)->s_op->statfs)((V), (S), sizeof(*(S)))
*/
#define AT_SIZE ATTR_SIZE
#define AT_MODE ATTR_MODE
+#undef AT_UID
#define AT_UID ATTR_UID
+#undef AT_GID
#define AT_GID ATTR_GID
#define AT_MTIME ATTR_MTIME
struct inode *ip = dp->d_inode;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
VATTR_NULL(&vattr);
iattr2vattr(&vattr, iattrp); /* Convert for AFS vnodeops call. */
update_inode_cache(ip, &vattr);
* least we've got the newest version of what was supposed to be set.
*/
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
}
-#if defined(AFS_LINUX26_ENV)
static void
afs_destroy_inode(struct inode *ip)
{
- /* afs inodes cannot be destroyed */
+ ip->i_state = 0;
}
-static void
-afs_clear_inode(struct inode *ip)
-{
- AFS_GLOCK();
- osi_clear_inode(ip);
- AFS_GUNLOCK();
-}
-#else
/* afs_put_inode
* called from iput when count goes to zero. Linux version of inactive.
{
struct vcache *vp = ITOAFS(ip);
+#ifdef AFS_LINUX26_ENV
+ put_inode_on_dummy_list(ip);
+#endif
+
AFS_GLOCK();
osi_clear_inode(ip);
AFS_GUNLOCK();
}
-#endif
/* afs_put_super
struct super_operations afs_sops = {
#if defined(AFS_LINUX26_ENV)
+ .drop_inode = generic_delete_inode,
.destroy_inode = afs_destroy_inode,
- .clear_inode = afs_clear_inode,
-#else
- .delete_inode = afs_delete_inode,
#endif
+ .delete_inode = afs_delete_inode,
.write_inode = afs_write_inode,
.put_super = afs_put_super,
.statfs = afs_statfs,
ip->i_mtime = vp->va_mtime.tv_sec;
ip->i_ctime = vp->va_ctime.tv_sec;
#endif
-
- /* we should put our inodes on a dummy inode list to keep linux happy. */
- if (!ip->i_list.prev && !ip->i_list.next) {
- /* this might be bad as we are reaching under the covers of the
- * list structure but we want to avoid putting the inode
- * on the list more than once. */
- put_inode_on_dummy_list(ip);
- }
}
/* Put this afs inode on our own dummy list. Linux expects to see inodes
extern struct vcache *afs_globalVp;
extern afs_rwlock_t afs_xvcache;
-extern struct dentry_operations *afs_dops;
#if defined(AFS_LINUX24_ENV)
extern struct inode_operations afs_file_iops;
extern struct address_space_operations afs_file_aops;
struct afs_fakestat_state fakestat;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
AFS_STATCNT(afs_readdir);
code = afs_InitReq(&treq, credp);
crfree(credp);
- if (code) {
- AFS_GUNLOCK();
- return -code;
- }
+ if (code)
+ goto out1;
afs_InitFakeStat(&fakestat);
code = afs_EvalFakeStat(&avc, &fakestat, &treq);
- if (code) {
- afs_PutFakeStat(&fakestat);
- AFS_GUNLOCK();
- return -code;
- }
+ if (code)
+ goto out;
/* update the cache entry */
tagain:
code = afs_VerifyVCache(avc, &treq);
- if (code) {
- afs_PutFakeStat(&fakestat);
- AFS_GUNLOCK();
- return -code;
- }
+ if (code)
+ goto out;
/* get a reference to the entire directory */
tdc = afs_GetDCache(avc, (afs_size_t) 0, &treq, &origOffset, &tlen, 1);
len = tlen;
if (!tdc) {
- afs_PutFakeStat(&fakestat);
- AFS_GUNLOCK();
- return -ENOENT;
+ code = -ENOENT;
+ goto out;
}
ObtainReadLock(&avc->lock);
ObtainReadLock(&tdc->lock);
* takes an offset in units of blobs, rather than bytes.
*/
code = 0;
- offset = (int)fp->f_pos;
+ offset = (int) fp->f_pos;
while (1) {
dirpos = BlobScan(&tdc->f.inode, offset);
if (!dirpos)
else {
printf("afs_linux_readdir: afs_dir_GetBlob failed, null name (inode %x, dirpos %d)\n",
&tdc->f.inode, dirpos);
- DRelease(de, 0);
+ DRelease((struct buffer *) de, 0);
afs_PutDCache(tdc);
ReleaseReadLock(&avc->lock);
- afs_PutFakeStat(&fakestat);
- return -ENOENT;
+ code = -ENOENT;
+ goto out;
}
/* filldir returns -EINVAL when the buffer is full. */
#else
code = (*filldir) (dirbuf, de->name, len, offset, ino);
#endif
- DRelease(de, 0);
+ DRelease((struct buffer *)de, 0);
if (code)
break;
offset = dirpos + 1 + ((len + 16) >> 5);
ReleaseReadLock(&tdc->lock);
afs_PutDCache(tdc);
ReleaseReadLock(&avc->lock);
+ code = 0;
+
+out:
afs_PutFakeStat(&fakestat);
+out1:
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
- return 0;
+ return code;
}
* AFS Linux dentry operations
**********************************************************************/
-static int
-afs_linux_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-{
- int err = afs_linux_revalidate(dentry);
- if (!err)
- generic_fillattr(dentry->d_inode, stat);
- return err;
-}
-
/* afs_linux_revalidate
* Ensure vcache is stat'd before use. Return 0 if entry is valid.
*/
return -code;
}
+#if defined(AFS_LINUX26_ENV)
+static int
+afs_linux_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+ int err = afs_linux_revalidate(dentry);
+ if (!err)
+ generic_fillattr(dentry->d_inode, stat);
+ return err;
+}
+#endif
/* Validate a dentry. Return 1 if unchanged, 0 if VFS layer should re-evaluate.
* In kernels 2.2.10 and above, we are passed an additional flags var which
return !bad_dentry;
}
+#if !defined(AFS_LINUX26_ENV)
/* afs_dentry_iput */
static void
afs_dentry_iput(struct dentry *dp, struct inode *ip)
osi_iput(ip);
}
+#endif
static int
afs_dentry_delete(struct dentry *dp)
struct dentry_operations afs_dentry_operations = {
.d_revalidate = afs_linux_dentry_revalidate,
- .d_iput = afs_dentry_iput,
.d_delete = afs_dentry_delete,
+#if !defined(AFS_LINUX26_ENV)
+ .d_iput = afs_dentry_iput,
+#endif
};
-struct dentry_operations *afs_dops = &afs_dentry_operations;
/**********************************************************************
* AFS Linux inode operations
vattr.va_mode = mode;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
code =
afs_create(ITOAFS(dip), name, &vattr, NONEXCL, mode,
(struct vcache **)&ip, credp);
ip->i_op = &afs_symlink_iops;
#endif
- dp->d_op = afs_dops;
+ dp->d_op = &afs_dentry_operations;
dp->d_time = jiffies;
d_instantiate(dp, ip);
}
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
cred_t *credp = crref();
struct vcache *vcp = NULL;
const char *comp = dp->d_name.name;
+
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
code = afs_lookup(ITOAFS(dip), comp, &vcp, credp);
if (vcp) {
#endif
}
dp->d_time = jiffies;
- dp->d_op = afs_dops;
+ dp->d_op = &afs_dentry_operations;
d_add(dp, AFSTOI(vcp));
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
const char *name = dp->d_name.name;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
code = afs_remove(ITOAFS(dip), name, credp);
- AFS_GUNLOCK();
if (!code)
d_drop(dp);
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
+ AFS_GUNLOCK();
crfree(credp);
return -code;
}
const char *name = dp->d_name.name;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
VATTR_NULL(&vattr);
vattr.va_mask = ATTR_MODE;
vattr.va_mode = mode;
#if defined(AFS_LINUX24_ENV)
tvcp->v.v_fop = &afs_dir_fops;
#endif
- dp->d_op = afs_dops;
+ dp->d_op = &afs_dentry_operations;
dp->d_time = jiffies;
d_instantiate(dp, AFSTOI(tvcp));
}
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
const char *name = dp->d_name.name;
AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
code = afs_rmdir(ITOAFS(dip), name, credp);
/* Linux likes to see ENOTEMPTY returned from an rmdir() syscall
d_drop(dp);
}
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
const char *oldname = olddp->d_name.name;
const char *newname = newdp->d_name.name;
+ AFS_GLOCK();
+#if defined(AFS_LINUX26_ENV)
+ lock_kernel();
+#endif
/* Remove old and new entries from name hash. New one will change below.
* While it's optimal to catch failures and re-insert newdp into hash,
* it's also error prone and in that case we're already dealing with error
* cases. Let another lookup put things right, if need be.
*/
- if (!list_empty(&olddp->d_hash)) {
+#if defined(AFS_LINUX26_ENV)
+ if (!d_unhashed(olddp))
d_drop(olddp);
- }
- if (!list_empty(&newdp->d_hash)) {
+ if (!d_unhashed(newdp))
d_drop(newdp);
- }
- AFS_GLOCK();
+#else
+ if (!list_empty(&olddp->d_hash))
+ d_drop(olddp);
+ if (!list_empty(&newdp->d_hash))
+ d_drop(newdp);
+#endif
code = afs_rename(ITOAFS(oldip), oldname, ITOAFS(newip), newname, credp);
- AFS_GUNLOCK();
if (!code) {
/* update time so it doesn't expire immediately */
d_move(olddp, newdp);
}
+#if defined(AFS_LINUX26_ENV)
+ unlock_kernel();
+#endif
+ AFS_GUNLOCK();
+
crfree(credp);
return -code;
}
#endif /* AFS_HPUX_ENV */
if (!afs_osicred_initialized) {
-#ifdef AFS_XBSD_ENV
+#if defined(AFS_LINUX26_ENV)
+ afs_osi_credp = crref();
+#elif defined(AFS_XBSD_ENV)
/* Can't just invent one, must use crget() because of mutex */
afs_osi_credp = crdup(osi_curcred());
#else
cr.cr_ref = 1;
cr.cr_uid = pr->uid;
#if defined(AFS_LINUX26_ENV)
-{
- int i;
-
- memset(cr.cr_groups, 0, NGROUPS * sizeof(gid_t));
-
- cr.cr_ngroups = pr->group_info->ngroups;
- for(i = 0; i < pr->group_info->ngroups; ++i)
- cr.cr_groups[i] = GROUP_AT(pr->group_info, i);
-}
+ get_group_info(pr->group_info);
+ cr.cr_group_info = pr->group_info;
#else
cr.cr_ngroups = pr->ngroups;
memcpy(cr.cr_groups, pr->groups, NGROUPS * sizeof(gid_t));
g0 = cred->cr_groups[1];
g1 = cred->cr_groups[2];
#else
-#ifdef AFS_AIX_ENV
-#ifdef AFS_AIX51_ENV
+#if defined(AFS_AIX51_ENV)
if (kcred_getpag(cred, PAG_AFS, &pag) < 0 || pag == 0)
pag = NOPAG;
return pag;
-#else
+#elif defined(AFS_AIX_ENV)
if (cred->cr_ngrps < 2) {
return NOPAG;
}
-#endif
-#else
-#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_DUX40_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_XBSD_ENV)
+#elif defined(AFS_LINUX26_ENV)
+ if (cred->cr_group_info->ngroups < 2)
+ return NOPAG;
+#elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_DUX40_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_XBSD_ENV)
if (cred->cr_ngroups < 2)
return NOPAG;
#endif
-#endif
-#ifdef AFS_AIX51_ENV
+#if defined(AFS_AIX51_ENV)
g0 = cred->cr_groupset.gs_union.un_groups[0];
g1 = cred->cr_groupset.gs_union.un_groups[1];
+#elif defined(AFS_LINUX26_ENV)
+ g0 = GROUP_AT(cred->cr_group_info, 0);
+ g1 = GROUP_AT(cred->cr_group_info, 1);
#else
g0 = cred->cr_groups[0];
g1 = cred->cr_groups[1];
ip->i_dev = afs_globalVFS->s_dev;
#endif
ip->i_sb = afs_globalVFS;
+ put_inode_on_dummy_list(ip);
}
#endif