linux26-more-updates-20040420

FIXES 4027

        . osi_cred now uses struct group_info
        . the big kernel lock has been moved from the fs generic code
          for some of the operations in 2.6
        . 2.6 now just uses iput() and hooks the appropriate routines
        . the dummy inode list handling should be clearer
This commit is contained in:
Chas Williams 2004-04-21 03:20:21 +00:00 committed by Derrick Brashear
parent 37d106e228
commit 171cec34dc
10 changed files with 298 additions and 174 deletions

View File

@ -63,6 +63,9 @@ crget(void)
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;
}
@ -71,6 +74,9 @@ void
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;
}
@ -88,7 +94,24 @@ cred_t *
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;
}
@ -97,17 +120,19 @@ cred_t *
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));
@ -127,14 +152,13 @@ crset(cred_t * cr)
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));

View File

@ -26,10 +26,86 @@ RCSID
#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;
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;
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);
}
#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.
*/
@ -37,21 +113,6 @@ int
set_pag_in_parent(int pag, int g0, int g1)
{
int i;
#if defined(AFS_LINUX26_ENV)
struct group_info *old_info, *new_info;
old_info = current->parent->group_info;
new_info = groups_alloc(old_info->ngroups + 2);
for(i = 0; i < old_info->ngroups; ++i)
GROUP_AT(new_info, i) = GROUP_AT(old_info, i);
GROUP_AT(new_info, i++) = g0;
GROUP_AT(new_info, i++) = g1;
current->parent->group_info = new_info;
put_group_info(old_info);
#else
#ifdef STRUCT_TASK_STRUCT_HAS_PARENT
gid_t *gp = current->parent->groups;
int ngroups = current->parent->ngroups;
@ -79,15 +140,48 @@ set_pag_in_parent(int pag, int g0, int g1)
current->parent->ngroups = 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;
@ -121,6 +215,7 @@ setpag(cred_t ** cr, afs_uint32 pagvalue, afs_uint32 * newpag,
osi_Free((char *)gidset, NGROUPS * sizeof(int));
return code;
#endif
}
@ -297,44 +392,3 @@ afs32_xsetgroups32(int gidsetsize, gid_t * grouplist)
#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;
}

View File

@ -56,7 +56,19 @@
#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
@ -105,9 +117,6 @@ extern struct vnodeops afs_file_iops, afs_dir_iops, afs_symlink_iops;
#define PAGESIZE PAGE_SIZE
#ifndef NGROUPS
#define NGROUPS NGROUPS_MAX
#endif
/* cred struct */
typedef struct cred { /* maps to task field: */
@ -120,8 +129,12 @@ 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

View File

@ -376,16 +376,13 @@ osi_clear_inode(struct inode *ip)
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.
@ -418,9 +415,13 @@ osi_iput(struct inode *ip)
#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
@ -453,7 +454,7 @@ check_bad_parent(struct dentry *dp)
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);
}

View File

@ -63,12 +63,6 @@ enum vcexcl { EXCL, NONEXCL } ;
#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)))
@ -110,7 +104,9 @@ typedef struct vattr {
*/
#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

View File

@ -225,6 +225,9 @@ afs_notify_change(struct dentry *dp, struct iattr *iattrp)
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);
@ -234,6 +237,9 @@ afs_notify_change(struct dentry *dp, struct iattr *iattrp)
* 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;
@ -275,21 +281,12 @@ afs_write_inode(struct inode *ip)
}
#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.
@ -303,11 +300,14 @@ afs_delete_inode(struct inode *ip)
{
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
@ -400,11 +400,10 @@ afs_umount_begin(struct super_block *sbp)
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,
@ -516,14 +515,6 @@ vattr2inode(struct inode *ip, struct vattr *vp)
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

View File

@ -47,7 +47,6 @@ RCSID
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;
@ -272,39 +271,33 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
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);
@ -335,7 +328,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
* 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)
@ -352,11 +345,11 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
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. */
@ -396,7 +389,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
#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);
@ -409,9 +402,16 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir)
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;
}
@ -763,15 +763,6 @@ struct file_operations afs_file_fops = {
* 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.
*/
@ -827,6 +818,16 @@ afs_linux_revalidate(struct dentry *dp)
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
@ -918,6 +919,7 @@ afs_linux_dentry_revalidate(struct dentry *dp)
return !bad_dentry;
}
#if !defined(AFS_LINUX26_ENV)
/* afs_dentry_iput */
static void
afs_dentry_iput(struct dentry *dp, struct inode *ip)
@ -932,6 +934,7 @@ afs_dentry_iput(struct dentry *dp, struct inode *ip)
osi_iput(ip);
}
#endif
static int
afs_dentry_delete(struct dentry *dp)
@ -952,10 +955,11 @@ 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
@ -983,6 +987,9 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
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);
@ -1011,11 +1018,14 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
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;
@ -1034,7 +1044,11 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
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) {
@ -1064,9 +1078,12 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
#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);
@ -1114,10 +1131,16 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp)
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;
}
@ -1154,6 +1177,9 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode)
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;
@ -1164,11 +1190,14 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int 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;
@ -1182,6 +1211,9 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp)
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
@ -1196,6 +1228,9 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp)
d_drop(dp);
}
#if defined(AFS_LINUX26_ENV)
unlock_kernel();
#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
@ -1212,20 +1247,27 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp,
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 */
@ -1233,6 +1275,11 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp,
d_move(olddp, newdp);
}
#if defined(AFS_LINUX26_ENV)
unlock_kernel();
#endif
AFS_GUNLOCK();
crfree(credp);
return -code;
}

View File

@ -74,7 +74,9 @@ osi_Init(void)
#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
@ -1059,15 +1061,8 @@ afs_osi_proc2cred(AFS_PROC * pr)
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));

View File

@ -450,25 +450,27 @@ PagInCred(const struct AFS_UCRED *cred)
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];

View File

@ -1024,6 +1024,7 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
ip->i_dev = afs_globalVFS->s_dev;
#endif
ip->i_sb = afs_globalVFS;
put_inode_on_dummy_list(ip);
}
#endif