mirror of
https://git.openafs.org/openafs.git
synced 2025-01-21 00:10:15 +00:00
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:
parent
37d106e228
commit
171cec34dc
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user