From b2abbb4a319f8f98a4d18eaf4bfb3b4592d53d21 Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Mon, 11 Jul 2005 20:29:54 +0000 Subject: [PATCH] STABLE14-linux-dynamic-inodes-20050710 i slipped a rollback on the linux 2.4 dentry stuff for osi_UFS* in here at the same time. this patch lets us use kernel inodes instead of our own pool. (cherry picked from commit 652f3bd9cb7a5d7833a760ba50ef7c2c67214bba) --- acinclude.m4 | 7 +- src/afs/LINUX/osi_file.c | 52 +--- src/afs/LINUX/osi_machdep.h | 35 +-- src/afs/LINUX/osi_misc.c | 145 +-------- src/afs/LINUX/osi_module.c | 12 +- src/afs/LINUX/osi_prototypes.h | 8 +- src/afs/LINUX/osi_vfs.hin | 30 +- src/afs/LINUX/osi_vfsops.c | 254 ++++++--------- src/afs/LINUX/osi_vm.c | 20 +- src/afs/LINUX/osi_vnodeops.c | 533 +++++++++++++++++--------------- src/afs/VNOPS/afs_vnop_attrs.c | 8 +- src/afs/VNOPS/afs_vnop_lookup.c | 12 +- src/afs/afs.h | 27 +- src/afs/afs_osi.h | 6 +- src/afs/afs_prototypes.h | 2 - src/afs/afs_vcache.c | 275 ++++++---------- src/cf/linux-test2.m4 | 5 +- src/cf/linux-test4.m4 | 15 + src/venus/kdump.c | 2 +- 19 files changed, 568 insertions(+), 880 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 2b093e675..68c5660e8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -578,6 +578,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_COMPLETION_H_EXISTS LINUX_DEFINES_FOR_EACH_PROCESS LINUX_DEFINES_PREV_TASK + LINUX_FS_STRUCT_SUPER_HAS_ALLOC_INODE LINUX_FS_STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK LINUX_FS_STRUCT_ADDRESS_SPACE_HAS_GFP_MASK LINUX_FS_STRUCT_INODE_HAS_I_ALLOC_SEM @@ -635,7 +636,8 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) linux_syscall_method=kallsyms_symbol fi if test "x$linux_syscall_method" = "xnone"; then - AC_MSG_ERROR([no available sys_call_table access method]) + AC_MSG_WARN([no available sys_call_table access method -- guessing scan]) + linux_syscall_method=scan fi fi fi @@ -684,6 +686,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) if test "x$ac_cv_linux_func_write_inode_returns_int" = "xyes" ; then AC_DEFINE(WRITE_INODE_NOT_VOID, 1, [define if your sops.write_inode returns non-void]) fi + if test "x$ac_cv_linux_fs_struct_super_has_alloc_inode" = "xyes" ; then + AC_DEFINE(STRUCT_SUPER_HAS_ALLOC_INODE, 1, [define if your struct super_operations has alloc_inode]) + fi if test "x$ac_cv_linux_fs_struct_address_space_has_page_lock" = "xyes"; then AC_DEFINE(STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK, 1, [define if your struct address_space has page_lock]) fi diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index 83c06bf6f..7711a75fe 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -31,30 +31,13 @@ extern struct vfsmount *afs_cacheMnt; #endif extern struct super_block *afs_cacheSBp; -/*#if defined(AFS_LINUX26_ENV) && (defined(CONFIG_EXPORTFS) || defined(CONFIG_EXPORTFS_MODULE)) -#define HAS_UFSOPEN -extern struct export_operations export_op_default; - -#define CALL(ops,fun) ((ops->fun)?(ops->fun):export_op_default.fun) - -XXX something based on encode_fh / find_exported_dentry -This would require us to store an inode -> fh mapping (acquired by -afs_InitCacheFile or lookupname), but probably solves the resiserfs issue. -#elif... */ - -#if defined(AFS_LINUX24_ENV) && !defined(HAS_UFSOPEN) -#define HAS_UFSOPEN +#if defined(AFS_LINUX26_ENV) void * osi_UFSOpen(afs_int32 ainode) { register struct osi_file *afile = NULL; extern int cacheDiskType; struct inode *tip = NULL; -#ifndef AFS_LINUX26_ENV - afs_int32 code = 0; - struct list_head *lp = NULL; - struct dentry *tdp = NULL; -#endif struct dentry *dp = NULL; struct file *filp = NULL; AFS_STATCNT(osi_UFSOpen); @@ -79,33 +62,11 @@ osi_UFSOpen(afs_int32 ainode) osi_Panic("Can't get inode %d\n", ainode); tip->i_flags |= MS_NOATIME; /* Disable updating access times. */ -#ifdef AFS_LINUX26_ENV dp = d_alloc_anon(tip); -#else - spin_lock(&dcache_lock); - for (lp = tip->i_dentry.next; lp != &tip->i_dentry; lp = lp->next) { - tdp = list_entry(lp, struct dentry, d_alias); - if ( !(tdp->d_flags & DCACHE_NFSD_DISCONNECTED)) { - dget_locked(tdp); - dp=tdp; - break; - } - } - if (tdp && !dp) { - dget_locked(tdp); - dp=tdp; - } - tdp = NULL; - spin_unlock(&dcache_lock); - if (!dp) - dp = d_alloc_root(tip); - iput(tip); -#endif if (!dp) osi_Panic("Can't get dentry for inode %d\n", ainode); filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR); - if (IS_ERR(filp)) osi_Panic("Can't open inode %d\n", ainode); afile->filp = filp; @@ -116,9 +77,7 @@ osi_UFSOpen(afs_int32 ainode) afile->inum = ainode; /* for hint validity checking */ return (void *)afile; } -#endif - -#if !defined(HAS_UFSOPEN) +#else void * osi_UFSOpen(afs_int32 ainode) { @@ -152,9 +111,6 @@ osi_UFSOpen(afs_int32 ainode) FILE_INODE(filp) = tip; tip->i_flags |= MS_NOATIME; /* Disable updating access times. */ filp->f_flags = O_RDWR; -#if defined(AFS_LINUX26_ENV) - filp->f_mapping = tip->i_mapping; -#endif #if defined(AFS_LINUX24_ENV) filp->f_mode = FMODE_READ|FMODE_WRITE; filp->f_op = fops_get(tip->i_fop); @@ -194,14 +150,14 @@ afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat) return code; } -#ifdef AFS_LINUX24_ENV +#ifdef AFS_LINUX26_ENV int osi_UFSClose(register struct osi_file *afile) { AFS_STATCNT(osi_Close); if (afile) { if (OSIFILE_INODE(afile)) { - filp_close(afile->filp, NULL); + filp_close(afile->filp, NULL); } } diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h index 7d13d64b1..fd28337b2 100644 --- a/src/afs/LINUX/osi_machdep.h +++ b/src/afs/LINUX/osi_machdep.h @@ -74,39 +74,22 @@ #undef gop_lookupname #define gop_lookupname osi_lookupname -#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_LINUX24_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 osi_vnhold(V, N) do { VN_HOLD(AFSTOV(V)); } while (0) +#define VN_HOLD(V) osi_Assert(igrab((V)) == (V)) +#define VN_RELE(V) iput((V)) #define afs_suser(x) capable(CAP_SYS_ADMIN) #define wakeup afs_osi_Wakeup #undef vType -#define vType(V) ((( vnode_t *)V)->v_type & S_IFMT) +#define vType(V) ((AFSTOV((V)))->i_mode & S_IFMT) +#undef vSetType +#define vSetType(V, type) AFSTOV((V))->i_mode = ((type) | (AFSTOV((V))->i_mode & ~S_IFMT)) /* preserve mode */ -/* IsAfsVnode relies on the fast that there is only one vnodeop table for AFS. - * Use the same type of test as other OS's for compatibility. - */ #undef IsAfsVnode -extern struct vnodeops afs_file_iops, afs_dir_iops, afs_symlink_iops; -#define IsAfsVnode(v) (((v)->v_op == &afs_file_iops) ? 1 : \ - ((v)->v_op == &afs_dir_iops) ? 1 : \ - ((v)->v_op == &afs_symlink_iops)) +#define IsAfsVnode(V) ((V)->i_sb == afs_globalVFS) /* test superblock instead */ #undef SetAfsVnode -#define SetAfsVnode(v) +#define SetAfsVnode(V) /* unnecessary */ /* We often need to pretend we're in user space to get memory transfers * right for the kernel calls we use. @@ -183,7 +166,7 @@ typedef struct uio { /* Get/set the inode in the osifile struct. */ #define FILE_INODE(F) (F)->f_dentry->d_inode -#ifdef AFS_LINUX24_ENV +#ifdef AFS_LINUX26_ENV #define OSIFILE_INODE(a) FILE_INODE((a)->filp) #else #define OSIFILE_INODE(a) FILE_INODE(&(a)->file) diff --git a/src/afs/LINUX/osi_misc.c b/src/afs/LINUX/osi_misc.c index 261e428b5..09b3f2285 100644 --- a/src/afs/LINUX/osi_misc.c +++ b/src/afs/LINUX/osi_misc.c @@ -141,7 +141,7 @@ osi_InitCacheInfo(char *aname) int osi_rdwr(struct osi_file *osifile, uio_t * uiop, int rw) { -#ifdef AFS_LINUX24_ENV +#ifdef AFS_LINUX26_ENV struct file *filp = osifile->filp; #else struct file *filp = &osifile->file; @@ -324,147 +324,28 @@ afs_osi_SetTime(osi_timeval_t * tvp) #endif } -/* Free all the pages on any of the vnodes in the vlru. Must be done before - * freeing all memory. +/* osi_linux_free_inode_pages + * + * Free all vnodes remaining in the afs hash. Must be done before + * shutting down afs and freeing all memory. */ void osi_linux_free_inode_pages(void) { int i; - struct vcache *tvc; - struct inode *ip; + struct vcache *tvc, *nvc; extern struct vcache *afs_vhashT[VCSIZE]; for (i = 0; i < VCSIZE; i++) { - for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { - ip = AFSTOI(tvc); -#if defined(AFS_LINUX24_ENV) - if (ip->i_data.nrpages) { -#else - if (ip->i_nrpages) { -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - truncate_inode_pages(&ip->i_data, 0); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15) - truncate_inode_pages(ip, 0); -#else - invalidate_inode_pages(ip); -#endif -#if defined(AFS_LINUX24_ENV) - if (ip->i_data.nrpages) { -#else - if (ip->i_nrpages) { -#endif - printf("Failed to invalidate all pages on inode 0x%lx\n", - (unsigned long)ip); - } - } - } - } -} - -#if !defined(AFS_LINUX24_ENV) -void -osi_clear_inode(struct inode *ip) -{ - cred_t *credp = crref(); - struct vcache *vcp = ITOAFS(ip); - - if (ip->i_count > 1) - printf("afs_put_inode: ino %ld (0x%lx) has count %ld\n", - (long)ip->i_ino, (unsigned long)ip, (long)ip->i_count); - - afs_InactiveVCache(vcp, credp); - ObtainWriteLock(&vcp->lock, 504); - ip->i_nlink = 0; /* iput checks this after calling this routine. */ -#ifdef I_CLEAR - ip->i_state = I_CLEAR; -#endif - ReleaseWriteLock(&vcp->lock); - crfree(credp); -} - -/* 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. - */ -void -osi_iput(struct inode *ip) -{ - extern struct vfs *afs_globalVFS; - - AFS_GLOCK(); - - if (afs_globalVFS && ip->i_sb != afs_globalVFS) - osi_Panic("IPUT Not an afs inode\n"); - -#if defined(AFS_LINUX24_ENV) - if (atomic_read(&ip->i_count) == 0) -#else - if (ip->i_count == 0) -#endif - osi_Panic("IPUT Bad refCount %d on inode 0x%x\n", -#if defined(AFS_LINUX24_ENV) - atomic_read(&ip->i_count), -#else - ip->i_count, -#endif - ip); - -#if defined(AFS_LINUX24_ENV) - if (atomic_dec_and_test(&ip->i_count)) -#else - if (!--ip->i_count) -#endif - { - 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 - * due to being mounted in multiple points at once. If so, check_bad_parent() - * calls afs_lookup() to correct the vcache's mvid, as well as the volume's - * dotdotfid and mtpoint fid members. - * Parameters: - * dp - dentry to be checked. - * Return Values: - * None. - * Sideeffects: - * This dentry's vcache's mvid will be set to the correct parent directory's - * fid. - * This root vnode's volume will have its dotdotfid and mtpoint fids set - * to the correct parent and mountpoint fids. - */ - -void -check_bad_parent(struct dentry *dp) -{ - cred_t *credp; - struct vcache *vcp = ITOAFS(dp->d_inode), *avc = NULL; - struct vcache *pvc = ITOAFS(dp->d_parent->d_inode); - - if (vcp->mvid->Fid.Volume != pvc->fid.Fid.Volume) { /* bad parent */ - credp = crref(); - - - /* force a lookup, so vcp->mvid is fixed up */ - 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, - "check_bad_parent: bad pointer returned from afs_lookup origvc newvc dentry", - ICL_TYPE_POINTER, vcp, ICL_TYPE_POINTER, avc, - ICL_TYPE_POINTER, dp); + for (tvc = afs_vhashT[i]; tvc; ) { + int slept; + + nvc = tvc->hnext; + if (afs_FlushVCache(tvc, &slept)) /* slept always 0 for linux? */ + printf("Failed to invalidate all pages on inode 0x%p\n", tvc); + tvc = nvc; } - if (avc) - AFS_RELE(avc); - crfree(credp); } - /* if bad parent */ - return; } struct task_struct *rxk_ListenerTask; diff --git a/src/afs/LINUX/osi_module.c b/src/afs/LINUX/osi_module.c index 3eeda88a8..f2ca2b253 100644 --- a/src/afs/LINUX/osi_module.c +++ b/src/afs/LINUX/osi_module.c @@ -342,7 +342,7 @@ int init_module(void) #endif { - int e; + int err; RWLOCK_INIT(&afs_xosi, "afs_xosi"); #if !defined(AFS_LINUX24_ENV) @@ -360,8 +360,12 @@ init_module(void) osi_Init(); - e = osi_syscall_init(); - if (e) return e; + err = osi_syscall_init(); + if (err) + return err; + err = afs_init_inodecache(); + if (err) + return err; register_filesystem(&afs_fs_type); osi_sysctl_init(); #ifdef AFS_LINUX24_ENV @@ -383,7 +387,7 @@ cleanup_module(void) osi_syscall_clean(); unregister_filesystem(&afs_fs_type); - osi_linux_free_inode_pages(); /* Invalidate all pages using AFS inodes. */ + afs_destroy_inodecache(); osi_linux_free_afs_memory(); #ifdef AFS_LINUX24_ENV diff --git a/src/afs/LINUX/osi_prototypes.h b/src/afs/LINUX/osi_prototypes.h index 4265e0037..bf8b88ca6 100644 --- a/src/afs/LINUX/osi_prototypes.h +++ b/src/afs/LINUX/osi_prototypes.h @@ -37,7 +37,6 @@ extern int osi_InitCacheInfo(char *aname); extern int osi_rdwr(struct osi_file *osifile, uio_t * uiop, int rw); extern void afs_osi_SetTime(osi_timeval_t * tvp); extern void osi_linux_free_inode_pages(void); -extern void check_bad_parent(struct dentry *dp); /* osi_probe.c */ extern void *osi_find_syscall_table(int which); @@ -61,12 +60,11 @@ extern void osi_VM_Truncate(struct vcache *avc, int alen, struct AFS_UCRED *acred); /* osi_vfsops.c */ -extern void set_inode_cache(struct inode *ip, struct vattr *vp); -extern void put_inode_on_dummy_list(struct inode *ip); extern void vattr2inode(struct inode *ip, struct vattr *vp); +extern int afs_init_inodecache(void); +extern void afs_destroy_inodecache(void); /* osi_vnodeops.c */ -extern int afs_linux_writepage_sync(struct inode *ip, struct page *pp, - unsigned long offset, unsigned int count); +extern void afs_fill_inode(struct inode *ip, struct vattr *vattr); #endif /* _OSI_PROTO_H_ */ diff --git a/src/afs/LINUX/osi_vfs.hin b/src/afs/LINUX/osi_vfs.hin index c6c52f46d..b94a2ca02 100644 --- a/src/afs/LINUX/osi_vfs.hin +++ b/src/afs/LINUX/osi_vfs.hin @@ -9,39 +9,24 @@ /* * Linux interpretations of vnode and vfs structs. - * - * The Linux "inode" has been abstracted to the fs independent part to avoid - * wasting 100+bytes per vnode. */ #ifndef OSI_VFS_H_ #define OSI_VFS_H_ -#if !defined(AFS_LINUX26_ENV) -/* The vnode should match the current implementation of the fs independent - * part of the Linux inode. - */ -/* The first cut is to continue to use a separate vnode pool. */ -/* LINUX VNODE INCLUDED BELOW -- DO NOT MODIFY */ - -typedef struct vnode vnode_t; -#else typedef struct inode vnode_t; #define vnode inode -#endif -/* Map vnode fields to inode fields. */ +/* Map vnode fields to inode fields */ #define i_number i_ino #define v_count i_count #define v_op i_op -#if defined(AFS_LINUX24_ENV) #define v_fop i_fop -#endif #define v_type i_mode #define v_vfsp i_sb -#define vfs_vnodecovered s_covered +#define v_data u.generic_ip -/* v_type bits map to mode bits: */ +/* v_type bits map to mode bits */ #define VNON 0 #define VREG S_IFREG #define VDIR S_IFDIR @@ -58,15 +43,12 @@ enum vcexcl { EXCL, NONEXCL } ; #define FWRITE O_WRONLY|O_RDWR|O_APPEND #define FTRUNC O_TRUNC - #define IO_APPEND O_APPEND #define FSYNC O_SYNC -#define VTOI(V) ((struct inode*)V) +#define VTOI(V) (V) #define VFS_STATFS(V, S) ((V)->s_op->statfs)((V), (S), sizeof(*(S))) - - /* Various mode bits */ #define VWRITE S_IWUSR #define VREAD S_IRUSR @@ -74,7 +56,6 @@ enum vcexcl { EXCL, NONEXCL } ; #define VSUID S_ISUID #define VSGID S_ISGID - #define vfs super_block typedef struct vattr { @@ -97,7 +78,4 @@ typedef struct vattr { #define VATTR_NULL(A) memset(A, 0, sizeof(struct vattr)) - -#define vnodeops inode_operations - #endif /* OSI_VFS_H_ */ diff --git a/src/afs/LINUX/osi_vfsops.c b/src/afs/LINUX/osi_vfsops.c index a0ed85e3f..f799b79b8 100644 --- a/src/afs/LINUX/osi_vfsops.c +++ b/src/afs/LINUX/osi_vfsops.c @@ -46,7 +46,6 @@ extern struct dentry_operations afs_dentry_operations; /* Forward declarations */ static void iattr2vattr(struct vattr *vattrp, struct iattr *iattrp); -static void update_inode_cache(struct inode *ip, struct vattr *vp); static int afs_root(struct super_block *afsp); struct super_block *afs_read_super(struct super_block *sb, void *data, int silent); int afs_fill_super(struct super_block *sb, void *data, int silent); @@ -180,23 +179,18 @@ afs_root(struct super_block *afsp) if (!(code = afs_InitReq(&treq, credp)) && !(code = afs_CheckInit())) { tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL); if (tvp) { - extern struct inode_operations afs_dir_iops; -#if defined(AFS_LINUX24_ENV) - extern struct file_operations afs_dir_fops; -#endif + struct inode *ip = AFSTOV(tvp); + struct vattr vattr; - /* "/afs" is a directory, reset inode ops accordingly. */ - AFSTOV(tvp)->v_op = &afs_dir_iops; -#if defined(AFS_LINUX24_ENV) - AFSTOV(tvp)->v_fop = &afs_dir_fops; -#endif + afs_getattr(tvp, &vattr, credp); + afs_fill_inode(ip, &vattr); /* setup super_block and mount point inode. */ afs_globalVp = tvp; #if defined(AFS_LINUX24_ENV) - afsp->s_root = d_alloc_root(AFSTOI(tvp)); + afsp->s_root = d_alloc_root(ip); #else - afsp->s_root = d_alloc_root(AFSTOI(tvp), NULL); + afsp->s_root = d_alloc_root(ip, NULL); #endif afsp->s_root->d_op = &afs_dentry_operations; } else @@ -220,109 +214,133 @@ int afs_notify_change(struct dentry *dp, struct iattr *iattrp) { struct vattr vattr; - int code; cred_t *credp = crref(); struct inode *ip = dp->d_inode; + int code; - 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); - code = afs_setattr(ITOAFS(ip), &vattr, credp); - afs_CopyOutAttrs(ITOAFS(ip), &vattr); - /* Note that the inode may still not have all the correct info. But at - * least we've got the newest version of what was supposed to be set. - */ #if defined(AFS_LINUX26_ENV) - unlock_kernel(); + lock_kernel(); #endif + AFS_GLOCK(); + code = afs_setattr(VTOAFS(ip), &vattr, credp); + if (!code) { + afs_getattr(VTOAFS(ip), &vattr, credp); + vattr2inode(ip, &vattr); + } AFS_GUNLOCK(); +#if defined(AFS_LINUX26_ENV) + unlock_kernel(); +#endif crfree(credp); return -code; } -/* This list is simply used to initialize the i_list member of the - * linux inode. This stops linux inode syncing code from choking on our - * inodes. - */ -static LIST_HEAD(dummy_inode_list); +#if defined(STRUCT_SUPER_HAS_ALLOC_INODE) +static kmem_cache_t *afs_inode_cachep; +static struct inode * +afs_alloc_inode(struct super_block *sb) +{ + struct vcache *vcp; + + vcp = (struct vcache *) kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL); + if (!vcp) + return NULL; + + return AFSTOV(vcp); +} -/* This is included for documentation only. */ -/* afs_write_inode - * Used to flush in core inode to disk. We don't need to do this. Top level - * write_inode() routine will clear i_dirt. If this routine is in the table, - * it's expected to do the cleaning and clear i_dirt. - * - * 9/24/99: This is what we thought until we discovered msync() does end up calling - * this function to sync a single inode to disk. msync() only flushes selective - * pages to disk. So it needs an inode syncing function to update metadata when it - * has synced some pages of a file to disk. - */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -#ifdef WRITE_INODE_NOT_VOID -static int -#else static void -#endif -afs_write_inode(struct inode *ip, int unused) -#else +afs_destroy_inode(struct inode *inode) +{ + kmem_cache_free(afs_inode_cachep, inode); +} + static void -afs_write_inode(struct inode *ip) -#endif +init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) { - list_del(&ip->i_list); - /* and put it back on our dummy list. */ - put_inode_on_dummy_list(ip); + struct vcache *vcp = (struct vcache *) foo; - /* for now we don't actually update the metadata during msync. This - * is just to keep linux happy. */ -#ifdef WRITE_INODE_NOT_VOID - return 0; -#endif + if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) + inode_init_once(AFSTOV(vcp)); } -static void -afs_destroy_inode(struct inode *ip) +int +afs_init_inodecache(void) { - cred_t *credp = crref(); +#ifndef SLAB_RECLAIM_ACCOUNT +#define SLAB_RECLAIM_ACCOUNT 0 +#endif - /* locked by clear_inode() */ - put_inode_on_dummy_list(ip); - ip->i_state = 0; - afs_InactiveVCache(ITOAFS(ip), credp); /* afs_FlushVCache()? */ - AFS_GUNLOCK(); - crfree(credp); + afs_inode_cachep = kmem_cache_create("afs_inode_cache", + sizeof(struct vcache), + 0, SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT, + init_once, NULL); + if (afs_inode_cachep == NULL) + return -ENOMEM; + return 0; } +void +afs_destroy_inodecache(void) +{ + if (kmem_cache_destroy(afs_inode_cachep)) + printk(KERN_INFO "afs_inode_cache: not all structures were freed\n"); +} +#else +int +afs_init_inodecache(void) +{ + return 0; +} -/* afs_put_inode - * called from iput when count goes to zero. Linux version of inactive. - * For Linux 2.2, this funcionality has moved to the delete inode super op. - * If we use the common inode pool, we'll need to set i_nlink to 0 here. - * That will trigger the call to delete routine. - */ +void +afs_destroy_inodecache(void) +{ + return; +} +#endif -#if defined(AFS_LINUX24_ENV) static void afs_clear_inode(struct inode *ip) { - AFS_GLOCK(); /* unlocked by destroy_inode() */ + struct vcache *vcp = VTOAFS(ip); + + if (vcp->vlruq.prev || vcp->vlruq.next) + osi_Panic("inode freed while on LRU"); + if (vcp->hnext || vcp->vhnext) + osi_Panic("inode freed while still hashed"); + +#if !defined(STRUCT_SUPER_HAS_ALLOC_INODE) + afs_osi_Free(ip->u.generic_ip, sizeof(struct vcache)); +#endif } -#else + +/* afs_put_inode + * Linux version of inactive. When refcount == 2, we are about to + * decrement to 1 and the only reference remaining should be for + * the VLRU + */ + static void -afs_delete_inode(struct inode *ip) +afs_put_inode(struct inode *ip) { - AFS_GLOCK(); /* after spin_unlock(inode_lock) */ - osi_clear_inode(ip); + cred_t *credp = crref(); + struct vcache *vcp = VTOAFS(ip); + + AFS_GLOCK(); + ObtainReadLock(&vcp->lock); + if (VREFCOUNT(vcp) == 2) + afs_InactiveVCache(vcp, credp); + ReleaseReadLock(&vcp->lock); AFS_GUNLOCK(); + crfree(credp); } -#endif /* afs_put_super * Called from unmount to release super_block. */ @@ -343,6 +361,8 @@ afs_put_super(struct super_block *sbp) afs_globalVFS = 0; afs_globalVp = 0; + + osi_linux_free_inode_pages(); /* invalidate and release remaining AFS inodes. */ afs_shutdown(); #if defined(AFS_LINUX24_ENV) mntput(afs_cacheMnt); @@ -412,13 +432,12 @@ afs_umount_begin(struct super_block *sbp) } struct super_operations afs_sops = { -#if defined(AFS_LINUX24_ENV) +#if defined(STRUCT_SUPER_HAS_ALLOC_INODE) + .alloc_inode = afs_alloc_inode, .destroy_inode = afs_destroy_inode, - .clear_inode = afs_clear_inode, -#else - .delete_inode = afs_delete_inode, #endif - .write_inode = afs_write_inode, + .clear_inode = afs_clear_inode, + .put_inode = afs_put_inode, .put_super = afs_put_super, .statfs = afs_statfs, .umount_begin = afs_umount_begin @@ -470,41 +489,6 @@ iattr2vattr(struct vattr *vattrp, struct iattr *iattrp) } } -/* update_inode_cache - * Update inode with info from vattr struct. Use va_mask to determine what - * to update. - */ -static void -update_inode_cache(struct inode *ip, struct vattr *vp) -{ - if (vp->va_mask & ATTR_MODE) - ip->i_mode = vp->va_mode; - if (vp->va_mask & ATTR_UID) - ip->i_uid = vp->va_uid; - if (vp->va_mask & ATTR_GID) - ip->i_gid = vp->va_gid; - if (vp->va_mask & ATTR_SIZE) - ip->i_size = vp->va_size; - if (vp->va_mask & ATTR_ATIME) -#if defined(AFS_LINUX26_ENV) - ip->i_atime.tv_sec = vp->va_atime.tv_sec; -#else - ip->i_atime = vp->va_atime.tv_sec; -#endif - if (vp->va_mask & ATTR_MTIME) -#if defined(AFS_LINUX26_ENV) - ip->i_mtime.tv_sec = vp->va_mtime.tv_sec; -#else - ip->i_mtime = vp->va_mtime.tv_sec; -#endif - if (vp->va_mask & ATTR_CTIME) -#if defined(AFS_LINUX26_ENV) - ip->i_ctime.tv_sec = vp->va_ctime.tv_sec; -#else - ip->i_ctime = vp->va_ctime.tv_sec; -#endif -} - /* vattr2inode * Rewrite the inode cache from the attr. Assumes all vattr fields are valid. */ @@ -530,35 +514,3 @@ vattr2inode(struct inode *ip, struct vattr *vp) ip->i_ctime = vp->va_ctime.tv_sec; #endif } - -/* Put this afs inode on our own dummy list. Linux expects to see inodes - * nicely strung up in lists. Linux inode syncing code chokes on our inodes if - * they're not on any lists. - */ -void -put_inode_on_dummy_list(struct inode *ip) -{ - /* Initialize list. See explanation above. */ - list_add(&ip->i_list, &dummy_inode_list); -} - -/* And yet another routine to update the inode cache - called from ProcessFS */ -void -vcache2inode(struct vcache *avc) -{ - struct vattr vattr; - - VATTR_NULL(&vattr); - afs_CopyOutAttrs(avc, &vattr); /* calls vattr2inode */ -} - -/* Yet another one for fakestat'ed mountpoints */ -void -vcache2fakeinode(struct vcache *rootvp, struct vcache *mpvp) -{ - struct vattr vattr; - - VATTR_NULL(&vattr); - afs_CopyOutAttrs(rootvp, &vattr); - vattr2inode(AFSTOI(mpvp), &vattr); -} diff --git a/src/afs/LINUX/osi_vm.c b/src/afs/LINUX/osi_vm.c index 552697fff..2776aff89 100644 --- a/src/afs/LINUX/osi_vm.c +++ b/src/afs/LINUX/osi_vm.c @@ -43,9 +43,9 @@ RCSID int osi_VM_FlushVCache(struct vcache *avc, int *slept) { - struct inode *ip = AFSTOI(avc); + struct inode *ip = AFSTOV(avc); - if (VREFCOUNT(avc) != 0) + if (VREFCOUNT(avc) > 1) return EBUSY; if (avc->opens != 0) @@ -73,7 +73,7 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept) void osi_VM_TryToSmush(struct vcache *avc, struct AFS_UCRED *acred, int sync) { - struct inode *ip = AFSTOI(avc); + struct inode *ip = AFSTOV(avc); #if defined(AFS_LINUX26_ENV) invalidate_inode_pages(ip->i_mapping); @@ -100,7 +100,7 @@ osi_VM_FSyncInval(struct vcache *avc) void osi_VM_StoreAllSegments(struct vcache *avc) { - struct inode *ip = AFSTOI(avc); + struct inode *ip = AFSTOV(avc); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5) /* filemap_fdatasync() only exported in 2.4.5 and above */ @@ -125,15 +125,15 @@ void osi_VM_FlushPages(struct vcache *avc, struct AFS_UCRED *credp) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - struct inode *ip = AFSTOI(avc); + struct inode *ip = AFSTOV(avc); truncate_inode_pages(&ip->i_data, 0); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15) - struct inode *ip = AFSTOI(avc); + struct inode *ip = AFSTOV(avc); truncate_inode_pages(ip, 0); #else - invalidate_inode_pages(AFSTOI(avc)); + invalidate_inode_pages(AFSTOV(avc)); #endif } @@ -147,14 +147,14 @@ void osi_VM_Truncate(struct vcache *avc, int alen, struct AFS_UCRED *acred) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - struct inode *ip = AFSTOI(avc); + struct inode *ip = AFSTOV(avc); truncate_inode_pages(&ip->i_data, alen); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15) - struct inode *ip = AFSTOI(avc); + struct inode *ip = AFSTOV(avc); truncate_inode_pages(ip, alen); #else - invalidate_inode_pages(AFSTOI(avc)); + invalidate_inode_pages(AFSTOV(avc)); #endif } diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 33eeefaba..4b6889b63 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -50,22 +50,13 @@ RCSID #endif extern struct vcache *afs_globalVp; -extern afs_rwlock_t afs_xvcache; - -#if defined(AFS_LINUX24_ENV) -extern struct inode_operations afs_file_iops; -extern struct address_space_operations afs_file_aops; -struct address_space_operations afs_symlink_aops; -#endif -extern struct inode_operations afs_dir_iops; -extern struct inode_operations afs_symlink_iops; static ssize_t afs_linux_read(struct file *fp, char *buf, size_t count, loff_t * offp) { ssize_t code; - struct vcache *vcp = ITOAFS(fp->f_dentry->d_inode); + struct vcache *vcp = VTOAFS(fp->f_dentry->d_inode); cred_t *credp = crref(); struct vrequest treq; @@ -147,7 +138,7 @@ afs_linux_write(struct file *fp, const char *buf, size_t count, loff_t * offp) { ssize_t code = 0; int code2 = 0; - struct vcache *vcp = ITOAFS(fp->f_dentry->d_inode); + struct vcache *vcp = VTOAFS(fp->f_dentry->d_inode); struct vrequest treq; cred_t *credp = crref(); afs_offs_t toffs; @@ -263,7 +254,7 @@ static int afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) { extern struct DirEntry *afs_dir_GetBlob(); - struct vcache *avc = ITOAFS(FILE_INODE(fp)); + struct vcache *avc = VTOAFS(FILE_INODE(fp)); struct vrequest treq; register struct dcache *tdc; int code; @@ -443,7 +434,7 @@ static int afs_private_mmap_ops_inited = 0; static struct vm_operations_struct afs_shared_mmap_ops; static int afs_shared_mmap_ops_inited = 0; -void +static void afs_linux_vma_close(struct vm_area_struct *vmap) { struct vcache *vcp; @@ -453,7 +444,7 @@ afs_linux_vma_close(struct vm_area_struct *vmap) if (!vmap->vm_file) return; - vcp = ITOAFS(FILE_INODE(vmap->vm_file)); + vcp = VTOAFS(FILE_INODE(vmap->vm_file)); if (!vcp) return; @@ -502,7 +493,7 @@ afs_linux_vma_close(struct vm_area_struct *vmap) static int afs_linux_mmap(struct file *fp, struct vm_area_struct *vmap) { - struct vcache *vcp = ITOAFS(FILE_INODE(fp)); + struct vcache *vcp = VTOAFS(FILE_INODE(fp)); cred_t *credp = crref(); struct vrequest treq; int code; @@ -576,17 +567,18 @@ afs_linux_mmap(struct file *fp, struct vm_area_struct *vmap) return code; } -int +static int afs_linux_open(struct inode *ip, struct file *fp) { - int code; + struct vcache *vcp = VTOAFS(ip); cred_t *credp = crref(); + int code; #ifdef AFS_LINUX24_ENV lock_kernel(); #endif AFS_GLOCK(); - code = afs_open((struct vcache **)&ip, fp->f_flags, credp); + code = afs_open(&vcp, fp->f_flags, credp); AFS_GUNLOCK(); #ifdef AFS_LINUX24_ENV unlock_kernel(); @@ -599,7 +591,7 @@ afs_linux_open(struct inode *ip, struct file *fp) static int afs_linux_release(struct inode *ip, struct file *fp) { - struct vcache *vcp = ITOAFS(ip); + struct vcache *vcp = VTOAFS(ip); cred_t *credp = crref(); int code = 0; @@ -617,11 +609,10 @@ afs_linux_release(struct inode *ip, struct file *fp) return -code; } -#if defined(AFS_LINUX24_ENV) static int +#if defined(AFS_LINUX24_ENV) afs_linux_fsync(struct file *fp, struct dentry *dp, int datasync) #else -static int afs_linux_fsync(struct file *fp, struct dentry *dp) #endif { @@ -633,7 +624,7 @@ afs_linux_fsync(struct file *fp, struct dentry *dp) lock_kernel(); #endif AFS_GLOCK(); - code = afs_fsync(ITOAFS(ip), credp); + code = afs_fsync(VTOAFS(ip), credp); AFS_GUNLOCK(); #ifdef AFS_LINUX24_ENV unlock_kernel(); @@ -648,7 +639,7 @@ static int afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp) { int code = 0; - struct vcache *vcp = ITOAFS(FILE_INODE(fp)); + struct vcache *vcp = VTOAFS(FILE_INODE(fp)); cred_t *credp = crref(); struct AFS_FLOCK flock; /* Convert to a lock format afs_lockctl understands. */ @@ -689,11 +680,11 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp) * code for the sys_close() here, not afs_linux_release(), so call * afs_StoreAllSegments() with AFS_LASTSTORE */ -int +static int afs_linux_flush(struct file *fp) { struct vrequest treq; - struct vcache *vcp = ITOAFS(FILE_INODE(fp)); + struct vcache *vcp = VTOAFS(FILE_INODE(fp)); cred_t *credp = crref(); int code; @@ -778,40 +769,71 @@ struct file_operations afs_file_fops = { * AFS Linux dentry operations **********************************************************************/ +/* 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 + * due to being mounted in multiple points at once. If so, check_bad_parent() + * calls afs_lookup() to correct the vcache's mvid, as well as the volume's + * dotdotfid and mtpoint fid members. + * Parameters: + * dp - dentry to be checked. + * Return Values: + * None. + * Sideeffects: + * This dentry's vcache's mvid will be set to the correct parent directory's + * fid. + * This root vnode's volume will have its dotdotfid and mtpoint fids set + * to the correct parent and mountpoint fids. + */ + +static inline void +check_bad_parent(struct dentry *dp) +{ + cred_t *credp; + struct vcache *vcp = VTOAFS(dp->d_inode), *avc = NULL; + struct vcache *pvc = VTOAFS(dp->d_parent->d_inode); + + if (vcp->mvid->Fid.Volume != pvc->fid.Fid.Volume) { /* bad parent */ +printk("check_bad_parent(%s): bad parent vcp->mvid->Fid.Volume != pvc->fid.Fid.Volume\n", dp->d_name.name); + credp = crref(); + + /* force a lookup, so vcp->mvid is fixed up */ + 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, + "check_bad_parent: bad pointer returned from afs_lookup origvc newvc dentry", + ICL_TYPE_POINTER, vcp, ICL_TYPE_POINTER, avc, + ICL_TYPE_POINTER, dp); + } + if (avc) + AFS_RELE(AFSTOV(avc)); + crfree(credp); + } + + return; +} + /* afs_linux_revalidate * Ensure vcache is stat'd before use. Return 0 if entry is valid. */ static int afs_linux_revalidate(struct dentry *dp) { - int code; + struct vattr vattr; + struct vcache *vcp = VTOAFS(dp->d_inode); cred_t *credp; - struct vrequest treq; - struct vcache *vcp = ITOAFS(dp->d_inode); - struct vcache *rootvp = NULL; + int code; #ifdef AFS_LINUX24_ENV lock_kernel(); #endif AFS_GLOCK(); - if (afs_fakestat_enable && vcp->mvstat == 1 && vcp->mvid - && (vcp->states & CMValid) && (vcp->states & CStatd)) { - ObtainSharedLock(&afs_xvcache, 680); - rootvp = afs_FindVCache(vcp->mvid, 0, 0); - ReleaseSharedLock(&afs_xvcache); - } - /* Make this a fast path (no crref), since it's called so often. */ if (vcp->states & CStatd) { + if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */ check_bad_parent(dp); /* check and correct mvid */ - if (rootvp) - vcache2fakeinode(rootvp, vcp); - else - vcache2inode(vcp); - if (rootvp) - afs_PutVCache(rootvp); + AFS_GUNLOCK(); #ifdef AFS_LINUX24_ENV unlock_kernel(); @@ -820,9 +842,9 @@ afs_linux_revalidate(struct dentry *dp) } credp = crref(); - code = afs_InitReq(&treq, credp); + code = afs_getattr(vcp, &vattr, credp); if (!code) - code = afs_VerifyVCache(vcp, &treq); + vattr2inode(AFSTOV(vcp), &vattr); AFS_GUNLOCK(); #ifdef AFS_LINUX24_ENV @@ -838,8 +860,9 @@ static int afs_linux_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { int err = afs_linux_revalidate(dentry); - if (!err) + if (!err) { generic_fillattr(dentry->d_inode, stat); +} return err; } #endif @@ -851,20 +874,18 @@ afs_linux_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *sta * it is a directory. But since the kernel itself checks these possibilities * later on, we shouldn't have to do it until later. Perhaps in the future.. */ +static int #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10) #ifdef DOP_REVALIDATE_TAKES_NAMEIDATA -static int afs_linux_dentry_revalidate(struct dentry *dp, struct nameidata *nd) #else -static int afs_linux_dentry_revalidate(struct dentry *dp, int flags) #endif #else -static int afs_linux_dentry_revalidate(struct dentry *dp) #endif { - struct vrequest treq; + struct vattr vattr; cred_t *credp = NULL; struct vcache *vcp, *pvcp, *tvc = NULL; int valid; @@ -874,16 +895,16 @@ afs_linux_dentry_revalidate(struct dentry *dp) #endif AFS_GLOCK(); - vcp = ITOAFS(dp->d_inode); - pvcp = ITOAFS(dp->d_parent->d_inode); /* dget_parent()? */ + if (dp->d_inode) { - if (vcp) { + vcp = VTOAFS(dp->d_inode); + pvcp = VTOAFS(dp->d_parent->d_inode); /* dget_parent()? */ - /* If it's the AFS root no chance it needs revalidating */ if (vcp == afs_globalVp) goto good_dentry; - /* check_bad_parent()? */ + if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */ + check_bad_parent(dp); /* check and correct mvid */ #ifdef notdef /* If the last looker changes, we should make sure the current @@ -902,27 +923,38 @@ afs_linux_dentry_revalidate(struct dentry *dp) * is longer valid, we need to do a full lookup. VerifyVCache * isn't enough since the vnode may have been renamed. */ + if (hgetlo(pvcp->m.DataVersion) > dp->d_time || !(vcp->states & CStatd)) { credp = crref(); - if (afs_InitReq(&treq, credp)) - goto bad_dentry; afs_lookup(pvcp, dp->d_name.name, &tvc, credp); if (!tvc || tvc != vcp) goto bad_dentry; - if (afs_VerifyVCache(vcp, &treq)) /* update inode attributes */ + + if (afs_getattr(vcp, &vattr, credp)) goto bad_dentry; + vattr2inode(AFSTOV(vcp), &vattr); dp->d_time = hgetlo(pvcp->m.DataVersion); } + /* should we always update the attributes at this point? */ + /* unlikely--the vcache entry hasn't changed */ + } else { +#ifdef notyet + pvcp = VTOAFS(dp->d_parent->d_inode); /* dget_parent()? */ if (hgetlo(pvcp->m.DataVersion) > dp->d_time) goto bad_dentry; +#endif /* No change in parent's DataVersion so this negative - * lookup is still valid. + * lookup is still valid. BUT, if a server is down a + * negative lookup can result so there should be a + * liftime as well. For now, always expire. */ + + goto bad_dentry; } good_dentry: @@ -950,19 +982,23 @@ afs_linux_dentry_revalidate(struct dentry *dp) goto done; } -#if !defined(AFS_LINUX24_ENV) -/* afs_dentry_iput */ static void afs_dentry_iput(struct dentry *dp, struct inode *ip) { - osi_iput(ip); + struct vcache *vcp = VTOAFS(ip); + + AFS_GLOCK(); + if (vcp->states & CUnlinked) + (void) afs_remunlink(vcp, 1); /* perhaps afs_InactiveVCache() instead */ + AFS_GUNLOCK(); + + iput(ip); } -#endif static int afs_dentry_delete(struct dentry *dp) { - if (dp->d_inode && (ITOAFS(dp->d_inode)->states & CUnlinked)) + if (dp->d_inode && (VTOAFS(dp->d_inode)->states & CUnlinked)) return 1; /* bad inode? */ return 0; @@ -971,9 +1007,7 @@ afs_dentry_delete(struct dentry *dp) struct dentry_operations afs_dentry_operations = { .d_revalidate = afs_linux_dentry_revalidate, .d_delete = afs_dentry_delete, -#if !defined(AFS_LINUX24_ENV) .d_iput = afs_dentry_iput, -#endif }; /********************************************************************** @@ -988,62 +1022,42 @@ struct dentry_operations afs_dentry_operations = { * * name is in kernel space at this point. */ +static int #ifdef IOP_CREATE_TAKES_NAMEIDATA -int afs_linux_create(struct inode *dip, struct dentry *dp, int mode, struct nameidata *nd) #else -int afs_linux_create(struct inode *dip, struct dentry *dp, int mode) #endif { - int code; - cred_t *credp = crref(); struct vattr vattr; + cred_t *credp = crref(); const char *name = dp->d_name.name; - struct inode *ip; + struct vcache *vcp; + int code; VATTR_NULL(&vattr); vattr.va_mode = mode; + vattr.va_type = mode & S_IFMT; #if defined(AFS_LINUX26_ENV) lock_kernel(); #endif AFS_GLOCK(); - code = - afs_create(ITOAFS(dip), (char *)name, &vattr, NONEXCL, mode, - (struct vcache **)&ip, credp); + code = afs_create(VTOAFS(dip), (char *)name, &vattr, NONEXCL, mode, + &vcp, credp); if (!code) { - vattr2inode(ip, &vattr); - /* Reset ops if symlink or directory. */ -#if defined(AFS_LINUX24_ENV) - if (S_ISREG(ip->i_mode)) { - ip->i_op = &afs_file_iops; - ip->i_fop = &afs_file_fops; - ip->i_data.a_ops = &afs_file_aops; - } else if (S_ISDIR(ip->i_mode)) { - ip->i_op = &afs_dir_iops; - ip->i_fop = &afs_dir_fops; - } else if (S_ISLNK(ip->i_mode)) { - ip->i_op = &afs_symlink_iops; - ip->i_data.a_ops = &afs_symlink_aops; - ip->i_mapping = &ip->i_data; - } else - printk("afs_linux_create: FIXME\n"); -#else - if (S_ISDIR(ip->i_mode)) - ip->i_op = &afs_dir_iops; - else if (S_ISLNK(ip->i_mode)) - ip->i_op = &afs_symlink_iops; -#endif + struct inode *ip = AFSTOV(vcp); + afs_getattr(vcp, &vattr, credp); + afs_fill_inode(ip, &vattr); dp->d_op = &afs_dentry_operations; - dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion); + dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion); d_instantiate(dp, ip); } - AFS_GUNLOCK(); + #if defined(AFS_LINUX26_ENV) unlock_kernel(); #endif @@ -1053,77 +1067,52 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode) /* afs_linux_lookup */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10) +static struct dentry * #ifdef IOP_LOOKUP_TAKES_NAMEIDATA -struct dentry * afs_linux_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) #else -struct dentry * afs_linux_lookup(struct inode *dip, struct dentry *dp) #endif #else -int +static int afs_linux_lookup(struct inode *dip, struct dentry *dp) #endif { - int code = 0; + struct vattr vattr; cred_t *credp = crref(); struct vcache *vcp = NULL; const char *comp = dp->d_name.name; -#if 1 - struct dentry *res = 0; -#endif + struct dentry *res = NULL; + struct inode *ip = NULL; + int code; #if defined(AFS_LINUX26_ENV) lock_kernel(); #endif AFS_GLOCK(); - code = afs_lookup(ITOAFS(dip), comp, &vcp, credp); - AFS_GUNLOCK(); + code = afs_lookup(VTOAFS(dip), comp, &vcp, credp); if (vcp) { - struct inode *ip = AFSTOI(vcp); - /* Reset ops if symlink or directory. */ + ip = AFSTOV(vcp); + + afs_getattr(vcp, &vattr, credp); + afs_fill_inode(ip, &vattr); + } + dp->d_op = &afs_dentry_operations; + dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion); + AFS_GUNLOCK(); #if defined(AFS_LINUX24_ENV) - if (S_ISREG(ip->i_mode)) { - ip->i_op = &afs_file_iops; - ip->i_fop = &afs_file_fops; - ip->i_data.a_ops = &afs_file_aops; - } else if (S_ISDIR(ip->i_mode)) { - ip->i_op = &afs_dir_iops; - ip->i_fop = &afs_dir_fops; + if (ip && S_ISDIR(ip->i_mode)) { d_prune_aliases(ip); res = d_find_alias(ip); - } else if (S_ISLNK(ip->i_mode)) { - ip->i_op = &afs_symlink_iops; - ip->i_data.a_ops = &afs_symlink_aops; - ip->i_mapping = &ip->i_data; - } else - printk - ("afs_linux_lookup: ip->i_mode 0x%x dp->d_name.name %s code %d\n", - ip->i_mode, dp->d_name.name, code); -#ifdef STRUCT_INODE_HAS_I_SECURITY - if (ip->i_security == NULL) { - if (security_inode_alloc(ip)) - panic("afs_linux_lookup: Cannot allocate inode security"); - } -#endif -#else - if (S_ISDIR(ip->i_mode)) - ip->i_op = &afs_dir_iops; - else if (S_ISLNK(ip->i_mode)) - ip->i_op = &afs_symlink_iops; -#endif } - dp->d_op = &afs_dentry_operations; - dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion); -#if defined(AFS_LINUX24_ENV) if (res) { if (d_unhashed(res)) d_rehash(res); } else #endif - d_add(dp, AFSTOI(vcp)); + d_add(dp, ip); #if defined(AFS_LINUX26_ENV) unlock_kernel(); @@ -1149,7 +1138,7 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp) #endif } -int +static int afs_linux_link(struct dentry *olddp, struct inode *dip, struct dentry *newdp) { int code; @@ -1163,20 +1152,20 @@ afs_linux_link(struct dentry *olddp, struct inode *dip, struct dentry *newdp) d_drop(newdp); AFS_GLOCK(); - code = afs_link(ITOAFS(oldip), ITOAFS(dip), name, credp); + code = afs_link(VTOAFS(oldip), VTOAFS(dip), name, credp); AFS_GUNLOCK(); crfree(credp); return -code; } -int +static int afs_linux_unlink(struct inode *dip, struct dentry *dp) { int code = EBUSY; cred_t *credp = crref(); const char *name = dp->d_name.name; - struct vcache *tvc = ITOAFS(dp->d_inode); + struct vcache *tvc = VTOAFS(dp->d_inode); #if defined(AFS_LINUX26_ENV) lock_kernel(); @@ -1205,9 +1194,9 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp) } while (__dp->d_inode != NULL); AFS_GLOCK(); - code = afs_rename(ITOAFS(dip), dp->d_name.name, ITOAFS(dip), __dp->d_name.name, credp); + code = afs_rename(VTOAFS(dip), dp->d_name.name, VTOAFS(dip), __dp->d_name.name, credp); if (!code) { - tvc->mvid = __name; + tvc->mvid = (void *) __name; crhold(credp); if (tvc->uncred) { crfree(tvc->uncred); @@ -1218,7 +1207,7 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp) AFS_GUNLOCK(); if (!code) { - __dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion); + __dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion); d_move(dp, __dp); } dput(__dp); @@ -1227,7 +1216,7 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp) } AFS_GLOCK(); - code = afs_remove(ITOAFS(dip), name, credp); + code = afs_remove(VTOAFS(dip), name, credp); AFS_GUNLOCK(); if (!code) d_drop(dp); @@ -1240,7 +1229,7 @@ out: } -int +static int afs_linux_symlink(struct inode *dip, struct dentry *dp, const char *target) { int code; @@ -1253,15 +1242,15 @@ afs_linux_symlink(struct inode *dip, struct dentry *dp, const char *target) */ d_drop(dp); - AFS_GLOCK(); VATTR_NULL(&vattr); - code = afs_symlink(ITOAFS(dip), name, &vattr, target, credp); + AFS_GLOCK(); + code = afs_symlink(VTOAFS(dip), name, &vattr, target, credp); AFS_GUNLOCK(); crfree(credp); return -code; } -int +static int afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode) { int code; @@ -1273,22 +1262,23 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode) #if defined(AFS_LINUX26_ENV) lock_kernel(); #endif - AFS_GLOCK(); VATTR_NULL(&vattr); vattr.va_mask = ATTR_MODE; vattr.va_mode = mode; - code = afs_mkdir(ITOAFS(dip), name, &vattr, &tvcp, credp); - AFS_GUNLOCK(); + AFS_GLOCK(); + code = afs_mkdir(VTOAFS(dip), name, &vattr, &tvcp, credp); if (tvcp) { - tvcp->v.v_op = &afs_dir_iops; -#if defined(AFS_LINUX24_ENV) - tvcp->v.v_fop = &afs_dir_fops; -#endif + struct inode *ip = AFSTOV(tvcp); + + afs_getattr(tvcp, &vattr, credp); + afs_fill_inode(ip, &vattr); + dp->d_op = &afs_dentry_operations; - dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion); - d_instantiate(dp, AFSTOI(tvcp)); + dp->d_time = hgetlo(VTOAFS(dip)->m.DataVersion); + d_instantiate(dp, ip); } + AFS_GUNLOCK(); #if defined(AFS_LINUX26_ENV) unlock_kernel(); @@ -1297,7 +1287,7 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode) return -code; } -int +static int afs_linux_rmdir(struct inode *dip, struct dentry *dp) { int code; @@ -1308,7 +1298,7 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp) lock_kernel(); #endif AFS_GLOCK(); - code = afs_rmdir(ITOAFS(dip), name, credp); + code = afs_rmdir(VTOAFS(dip), name, credp); AFS_GUNLOCK(); /* Linux likes to see ENOTEMPTY returned from an rmdir() syscall @@ -1331,8 +1321,7 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp) } - -int +static int afs_linux_rename(struct inode *oldip, struct dentry *olddp, struct inode *newip, struct dentry *newdp) { @@ -1369,7 +1358,7 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp, #endif AFS_GLOCK(); - code = afs_rename(ITOAFS(oldip), oldname, ITOAFS(newip), newname, credp); + code = afs_rename(VTOAFS(oldip), oldname, VTOAFS(newip), newname, credp); AFS_GUNLOCK(); if (rehash) @@ -1397,7 +1386,7 @@ afs_linux_ireadlink(struct inode *ip, char *target, int maxlen, uio_seg_t seg) struct iovec iov; setup_uio(&tuio, &iov, target, (afs_offs_t) 0, maxlen, UIO_READ, seg); - code = afs_readlink(ITOAFS(ip), &tuio, credp); + code = afs_readlink(VTOAFS(ip), &tuio, credp); crfree(credp); if (!code) @@ -1410,7 +1399,7 @@ afs_linux_ireadlink(struct inode *ip, char *target, int maxlen, uio_seg_t seg) /* afs_linux_readlink * Fill target (which is in user space) with contents of symlink. */ -int +static int afs_linux_readlink(struct dentry *dp, char *target, int maxlen) { int code; @@ -1426,7 +1415,7 @@ afs_linux_readlink(struct dentry *dp, char *target, int maxlen) /* afs_linux_follow_link * a file system dependent link following routine. */ -struct dentry * +static struct dentry * afs_linux_follow_link(struct dentry *dp, struct dentry *basep, unsigned int follow) { @@ -1464,7 +1453,7 @@ afs_linux_follow_link(struct dentry *dp, struct dentry *basep, /* afs_linux_readpage * all reads come through here. A strategy-like read call. */ -int +static int afs_linux_readpage(struct file *fp, struct page *pp) { int code; @@ -1480,7 +1469,7 @@ afs_linux_readpage(struct file *fp, struct page *pp) struct iovec iovec; struct inode *ip = FILE_INODE(fp); int cnt = page_count(pp); - struct vcache *avc = ITOAFS(ip); + struct vcache *avc = VTOAFS(ip); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) @@ -1551,89 +1540,13 @@ afs_linux_readpage(struct file *fp, struct page *pp) return -code; } -#if defined(AFS_LINUX24_ENV) -#ifdef AOP_WRITEPAGE_TAKES_WRITEBACK_CONTROL -int -afs_linux_writepage(struct page *pp, struct writeback_control *wbc) -#else -int -afs_linux_writepage(struct page *pp) -#endif -{ - struct address_space *mapping = pp->mapping; - struct inode *inode; - unsigned long end_index; - unsigned offset = PAGE_CACHE_SIZE; - long status; - -#if defined(AFS_LINUX26_ENV) - if (PageReclaim(pp)) { - return WRITEPAGE_ACTIVATE; - } -#else - if (PageLaunder(pp)) { - return(fail_writepage(pp)); - } -#endif - - inode = (struct inode *)mapping->host; - end_index = inode->i_size >> PAGE_CACHE_SHIFT; - - /* easy case */ - if (pp->index < end_index) - goto do_it; - /* things got complicated... */ - offset = inode->i_size & (PAGE_CACHE_SIZE - 1); - /* OK, are we completely out? */ - if (pp->index >= end_index + 1 || !offset) - return -EIO; - do_it: - status = afs_linux_writepage_sync(inode, pp, 0, offset); - SetPageUptodate(pp); - UnlockPage(pp); - if (status == offset) - return 0; - else - return status; -} -#endif - -/* afs_linux_permission - * Check access rights - returns error if can't check or permission denied. - */ -#ifdef IOP_PERMISSION_TAKES_NAMEIDATA -int -afs_linux_permission(struct inode *ip, int mode, struct nameidata *nd) -#else -int -afs_linux_permission(struct inode *ip, int mode) -#endif -{ - int code; - cred_t *credp = crref(); - int tmp = 0; - - AFS_GLOCK(); - if (mode & MAY_EXEC) - tmp |= VEXEC; - if (mode & MAY_READ) - tmp |= VREAD; - if (mode & MAY_WRITE) - tmp |= VWRITE; - code = afs_access(ITOAFS(ip), tmp, credp); - - AFS_GUNLOCK(); - crfree(credp); - return -code; -} - #if defined(AFS_LINUX24_ENV) -int +static int afs_linux_writepage_sync(struct inode *ip, struct page *pp, unsigned long offset, unsigned int count) { - struct vcache *vcp = ITOAFS(ip); + struct vcache *vcp = VTOAFS(ip); char *buffer; afs_offs_t base; int code = 0; @@ -1656,7 +1569,8 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp, code = afs_write(vcp, &tuio, f_flags, credp, 0); - vcache2inode(vcp); + ip->i_size = vcp->m.Length; + ip->i_blocks = ((vcp->m.Length + 1023) >> 10) << 1; if (!code && afs_stats_cmperf.cacheCurrDirtyChunks > @@ -1682,17 +1596,61 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp, return code; } + +static int +#ifdef AOP_WRITEPAGE_TAKES_WRITEBACK_CONTROL +afs_linux_writepage(struct page *pp, struct writeback_control *wbc) +#else +afs_linux_writepage(struct page *pp) +#endif +{ + struct address_space *mapping = pp->mapping; + struct inode *inode; + unsigned long end_index; + unsigned offset = PAGE_CACHE_SIZE; + long status; + +#if defined(AFS_LINUX26_ENV) + if (PageReclaim(pp)) { + return WRITEPAGE_ACTIVATE; + } +#else + if (PageLaunder(pp)) { + return(fail_writepage(pp)); + } +#endif + + inode = (struct inode *)mapping->host; + end_index = inode->i_size >> PAGE_CACHE_SHIFT; + + /* easy case */ + if (pp->index < end_index) + goto do_it; + /* things got complicated... */ + offset = inode->i_size & (PAGE_CACHE_SIZE - 1); + /* OK, are we completely out? */ + if (pp->index >= end_index + 1 || !offset) + return -EIO; + do_it: + status = afs_linux_writepage_sync(inode, pp, 0, offset); + SetPageUptodate(pp); + UnlockPage(pp); + if (status == offset) + return 0; + else + return status; +} #else /* afs_linux_updatepage * What one would have thought was writepage - write dirty page to file. * Called from generic_file_write. buffer is still in user space. pagep * has been filled in with old data if we're updating less than a page. */ -int +static int afs_linux_updatepage(struct file *fp, struct page *pp, unsigned long offset, unsigned int count, int sync) { - struct vcache *vcp = ITOAFS(FILE_INODE(fp)); + struct vcache *vcp = VTOAFS(FILE_INODE(fp)); u8 *page_addr = (u8 *) afs_linux_page_address(pp); int code = 0; cred_t *credp; @@ -1712,7 +1670,8 @@ afs_linux_updatepage(struct file *fp, struct page *pp, unsigned long offset, code = afs_write(vcp, &tuio, fp->f_flags, credp, 0); - vcache2inode(vcp); + ip->i_size = vcp->m.Length; + ip->i_blocks = ((vcp->m.Length + 1023) >> 10) << 1; code = code ? -code : count - tuio.uio_resid; afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp, @@ -1727,6 +1686,34 @@ afs_linux_updatepage(struct file *fp, struct page *pp, unsigned long offset, } #endif +/* afs_linux_permission + * Check access rights - returns error if can't check or permission denied. + */ +static int +#ifdef IOP_PERMISSION_TAKES_NAMEIDATA +afs_linux_permission(struct inode *ip, int mode, struct nameidata *nd) +#else +afs_linux_permission(struct inode *ip, int mode) +#endif +{ + int code; + cred_t *credp = crref(); + int tmp = 0; + + AFS_GLOCK(); + if (mode & MAY_EXEC) + tmp |= VEXEC; + if (mode & MAY_READ) + tmp |= VREAD; + if (mode & MAY_WRITE) + tmp |= VWRITE; + code = afs_access(VTOAFS(ip), tmp, credp); + + AFS_GUNLOCK(); + crfree(credp); + return -code; +} + #if defined(AFS_LINUX24_ENV) static int afs_linux_commit_write(struct file *file, struct page *page, unsigned offset, @@ -1758,7 +1745,7 @@ afs_linux_prepare_write(struct file *file, struct page *page, unsigned from, extern int afs_notify_change(struct dentry *dp, struct iattr *iattrp); #endif -struct inode_operations afs_file_iops = { +static struct inode_operations afs_file_iops = { #if defined(AFS_LINUX26_ENV) .permission = afs_linux_permission, .getattr = afs_linux_getattr, @@ -1776,7 +1763,7 @@ struct inode_operations afs_file_iops = { }; #if defined(AFS_LINUX24_ENV) -struct address_space_operations afs_file_aops = { +static struct address_space_operations afs_file_aops = { .readpage = afs_linux_readpage, .writepage = afs_linux_writepage, .commit_write = afs_linux_commit_write, @@ -1789,7 +1776,7 @@ struct address_space_operations afs_file_aops = { * by what sort of operation is allowed..... */ -struct inode_operations afs_dir_iops = { +static struct inode_operations afs_dir_iops = { #if !defined(AFS_LINUX24_ENV) .default_file_ops = &afs_dir_fops, #else @@ -1846,12 +1833,12 @@ afs_symlink_filler(struct file *file, struct page *page) return code; } -struct address_space_operations afs_symlink_aops = { +static struct address_space_operations afs_symlink_aops = { .readpage = afs_symlink_filler }; #endif -struct inode_operations afs_symlink_iops = { +static struct inode_operations afs_symlink_iops = { #if defined(AFS_LINUX24_ENV) .readlink = page_readlink, #if defined(HAVE_KERNEL_PAGE_FOLLOW_LINK) @@ -1868,3 +1855,35 @@ struct inode_operations afs_symlink_iops = { .revalidate = afs_linux_revalidate, #endif }; + +void +afs_fill_inode(struct inode *ip, struct vattr *vattr) +{ + + if (vattr) + vattr2inode(ip, vattr); + +/* Reset ops if symlink or directory. */ + if (S_ISREG(ip->i_mode)) { + ip->i_op = &afs_file_iops; +#if defined(AFS_LINUX24_ENV) + ip->i_fop = &afs_file_fops; + ip->i_data.a_ops = &afs_file_aops; +#endif + + } else if (S_ISDIR(ip->i_mode)) { + ip->i_op = &afs_dir_iops; +#if defined(AFS_LINUX24_ENV) + ip->i_fop = &afs_dir_fops; +#endif + + } else if (S_ISLNK(ip->i_mode)) { + ip->i_op = &afs_symlink_iops; +#if defined(AFS_LINUX24_ENV) + ip->i_data.a_ops = &afs_symlink_aops; + ip->i_mapping = &ip->i_data; +#endif + } + + /* insert_inode_hash(ip); -- this would make iget() work (if we used it) */ +} diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c index 84fd3f235..8c8a72241 100644 --- a/src/afs/VNOPS/afs_vnop_attrs.c +++ b/src/afs/VNOPS/afs_vnop_attrs.c @@ -177,10 +177,6 @@ afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs) #endif #endif /* ! AFS_OSF_ENV && !AFS_DARWIN_ENV && !AFS_XBSD_ENV */ -#ifdef AFS_LINUX22_ENV - /* And linux has its own stash as well. */ - vattr2inode(AFSTOV(avc), attrs); -#endif return 0; } @@ -297,8 +293,8 @@ afs_getattr(OSI_VC_DECL(avc), struct vattr *attrs, struct AFS_UCRED *acred) * confuses getwd()... */ #ifdef AFS_LINUX22_ENV if (avc == afs_globalVp) { - struct inode *ip = avc->v.i_sb->s_root->d_inode; - attrs->va_nodeid = ip->i_ino; + struct inode *ip = AFSTOV(avc)->i_sb->s_root->d_inode; + attrs->va_nodeid = ip->i_ino; /* VTOI()? */ } #else if (AFSTOV(avc)->v_flag & VROOT) { diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index c82496a47..b64d32d73 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -31,10 +31,6 @@ RCSID extern struct DirEntry *afs_dir_GetBlob(); -#ifdef AFS_LINUX22_ENV -extern struct inode_operations afs_symlink_iops, afs_dir_iops; -#endif - afs_int32 afs_bkvolpref = 0; afs_int32 afs_bulkStatsDone; @@ -974,12 +970,8 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) * We only do this if the entry looks clear. */ afs_ProcessFS(tvcp, &statsp[i], areqp); -#ifdef AFS_LINUX22_ENV - /* overwrite the ops if it's a directory or symlink. */ - if (vType(tvcp) == VDIR) - tvcp->v.v_op = &afs_dir_iops; - else if (vType(tvcp) == VLNK) - tvcp->v.v_op = &afs_symlink_iops; +#if defined(AFS_LINUX22_ENV) + afs_fill_inode(AFSTOV(tvcp), NULL); /* reset inode operations */ #endif /* do some accounting for bulk stats: mark this entry as diff --git a/src/afs/afs.h b/src/afs/afs.h index 3bb371b82..1581c7bb0 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -558,10 +558,10 @@ struct SimpleLocks { #endif /* AFS_XBSD_ENV */ #if defined(AFS_LINUX24_ENV) -#define VREFCOUNT(v) atomic_read(&((vnode_t *) v)->v_count) -#define VREFCOUNT_SET(v, c) atomic_set(&((vnode_t *) v)->v_count, c) -#define VREFCOUNT_DEC(v) atomic_dec(&((vnode_t *) v)->v_count) -#define VREFCOUNT_INC(v) atomic_inc(&((vnode_t *) v)->v_count) +#define VREFCOUNT(v) atomic_read(&(AFSTOV(v)->v_count)) +#define VREFCOUNT_SET(v, c) atomic_set(&(AFSTOV(v)->v_count), c) +#define VREFCOUNT_DEC(v) atomic_dec(&(AFSTOV(v)->v_count)) +#define VREFCOUNT_INC(v) atomic_inc(&(AFSTOV(v)->v_count)) #else #define VREFCOUNT(v) ((v)->vrefCount) #define VREFCOUNT_SET(v, c) (v)->vrefCount = c; @@ -580,7 +580,7 @@ struct SimpleLocks { extern afs_int32 vmPageHog; /* counter for # of vnodes which are page hogs. */ -#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) +#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE)) #define VTOAFS(v) ((struct vcache *)(v)->v_data) #define AFSTOV(vc) ((vc)->v) #else @@ -588,25 +588,22 @@ extern afs_int32 vmPageHog; /* counter for # of vnodes which are page hogs. */ #define AFSTOV(V) (&(V)->v) #endif -#ifdef AFS_LINUX22_ENV -#define ITOAFS(V) ((struct vcache*)(V)) -#define AFSTOI(V) (struct inode *)(&(V)->v) -#endif - /* INVARIANTs: (vlruq.next != NULL) == (vlruq.prev != NULL) * nextfree => !vlruq.next && ! vlruq.prev * !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree) */ struct vcache { -#if defined(AFS_XBSD_ENV)||defined(AFS_DARWIN_ENV) +#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE)) struct vnode *v; #else struct vnode v; /* Has reference count in v.v_count */ #endif struct afs_q vlruq; /* lru q next and prev */ +#if !defined(AFS_LINUX22_ENV) struct vcache *nextfree; /* next on free list (if free) */ +#endif struct vcache *hnext; /* Hash next */ - struct vcache *vhnext; /* vol hash next */ + struct vcache *vhnext; /* vol hash next */ struct VenusFid fid; struct mstat { afs_size_t Length; @@ -1066,11 +1063,6 @@ extern struct brequest afs_brs[NBRS]; /* request structures */ * GetVCache incantation, and could eliminate even this code from afs_UFSRead * by making intentionally invalidating quick.stamp in the various callbacks * expiration/breaking code */ -#ifdef AFS_LINUX20_ENV -#define afs_VerifyVCache(avc, areq) \ - (((avc)->states & CStatd) ? (vcache2inode(avc), 0) : \ - afs_VerifyVCache2((avc),areq)) -#else #ifdef AFS_DARWIN_ENV #define afs_VerifyVCache(avc, areq) \ (((avc)->states & CStatd) ? (osi_VM_Setup(avc, 0), 0) : \ @@ -1079,7 +1071,6 @@ extern struct brequest afs_brs[NBRS]; /* request structures */ #define afs_VerifyVCache(avc, areq) \ (((avc)->states & CStatd) ? 0 : afs_VerifyVCache2((avc),areq)) #endif -#endif #define DO_STATS 1 /* bits used by FindVCache */ #define DO_VLRU 2 diff --git a/src/afs/afs_osi.h b/src/afs/afs_osi.h index 2e2879d73..99ce3137f 100644 --- a/src/afs/afs_osi.h +++ b/src/afs/afs_osi.h @@ -48,7 +48,7 @@ struct osi_stat { struct osi_file { afs_int32 size; /* file size in bytes XXX Must be first field XXX */ -#ifdef AFS_LINUX24_ENV +#ifdef AFS_LINUX26_ENV struct file *filp; /* May need this if we really open the file. */ #else #ifdef AFS_LINUX22_ENV @@ -123,7 +123,7 @@ struct afs_osi_WaitHandle { /* * Vnode related macros */ -#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) +#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_LINUX22_ENV) #define vSetVfsp(vc, vfsp) AFSTOV(vc)->v_mount = (vfsp) #define vSetType(vc, type) AFSTOV(vc)->v_type = (type) #define vType(vc) AFSTOV(vc)->v_type @@ -263,7 +263,7 @@ typedef struct timeval osi_timeval_t; calling VREF does not */ #define AFS_FAST_HOLD(vp) osi_vnhold((vp),0) #else -#define AFS_FAST_HOLD(vp) VN_HOLD(&(vp)->v) +#define AFS_FAST_HOLD(vp) VN_HOLD(AFSTOV(vp)) #endif #define AFS_FAST_RELE(vp) AFS_RELE(AFSTOV(vp)) diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 96f17b914..da72808ba 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -546,8 +546,6 @@ extern void setup_uio(uio_t * uiop, struct iovec *iovecp, const char *buf, uio_seg_t seg); extern int uiomove(char *dp, int length, uio_flag_t rw, uio_t * uiop); extern void osi_linux_free_inode_pages(void); -extern void osi_clear_inode(struct inode *ip); -extern void check_bad_parent(struct dentry *dp); #endif extern void osi_linux_mask(void); extern void osi_linux_unmask(void); diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 4c9dc09dc..d006eb101 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -47,7 +47,7 @@ RCSID #include "afs/afs_cbqueue.h" #include "afs/afs_osidnlc.h" -#ifdef AFS_OSF_ENV +#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) afs_int32 afs_maxvcount = 0; /* max number of vcache entries */ afs_int32 afs_vcount = 0; /* number of vcache in use now */ #endif /* AFS_OSF_ENV */ @@ -63,8 +63,10 @@ char *makesname(); /* Exported variables */ afs_rwlock_t afs_xvcache; /*Lock: alloc new stat cache entries */ afs_lock_t afs_xvcb; /*Lock: fids on which there are callbacks */ -struct vcache *freeVCList; /*Free list for stat cache entries */ -struct vcache *Initial_freeVCList; /*Initial list for above */ +#if !defined(AFS_LINUX22_ENV) +static struct vcache *freeVCList; /*Free list for stat cache entries */ +static struct vcache *Initial_freeVCList; /*Initial list for above */ +#endif struct afs_q VLRU; /*vcache LRU */ afs_int32 vcachegen = 0; unsigned int afs_paniconwarn = 0; @@ -151,9 +153,11 @@ afs_FlushVCache(struct vcache *avc, int *slept) code = EBUSY; goto bad; } +#if !defined(AFS_LINUX22_ENV) if (avc->nextfree || !avc->vlruq.prev || !avc->vlruq.next) { /* qv afs.h */ refpanic("LRU vs. Free inconsistency"); } +#endif avc->states |= CVFlushed; /* pull the entry out of the lruq and put it on the free list */ QRemove(&avc->vlruq); @@ -231,32 +235,36 @@ afs_FlushVCache(struct vcache *avc, int *slept) else afs_evenZaps++; -#if !defined(AFS_OSF_ENV) +#if !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV) /* put the entry in the free list */ avc->nextfree = freeVCList; freeVCList = avc; if (avc->vlruq.prev || avc->vlruq.next) { refpanic("LRU vs. Free inconsistency"); } + avc->states |= CVFlushed; #else /* This should put it back on the vnode free list since usecount is 1 */ afs_vcount--; vSetType(avc, VREG); if (VREFCOUNT(avc) > 0) { +#if defined(AFS_OSF_ENV) VN_UNLOCK(AFSTOV(avc)); +#endif AFS_RELE(AFSTOV(avc)); } else { if (afs_norefpanic) { printf("flush vc refcnt < 1"); afs_norefpanic++; +#if defined(AFS_OSF_ENV) (void)vgone(avc, VX_NOSLEEP, NULL); AFS_GLOCK(); VN_UNLOCK(AFSTOV(avc)); +#endif } else osi_Panic("flush vc refcnt < 1"); } #endif /* AFS_OSF_ENV */ - avc->states |= CVFlushed; return 0; bad: @@ -599,9 +607,9 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) int code, fv_slept; AFS_STATCNT(afs_NewVCache); -#ifdef AFS_OSF_ENV -#ifdef AFS_OSF30_ENV - if (afs_vcount >= afs_maxvcount) { +#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) +#if defined(AFS_OSF30_ENV) || defined(AFS_LINUX22_ENV) + if (afs_vcount >= afs_maxvcount) #else /* * If we are using > 33 % of the total system vnodes for AFS vcache @@ -610,8 +618,9 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) * our usage is > afs_maxvcount, set elsewhere to 0.5*nvnode, * we _must_ free some -- no choice). */ - if (((3 * afs_vcount) > nvnode) || (afs_vcount >= afs_maxvcount)) { + if (((3 * afs_vcount) > nvnode) || (afs_vcount >= afs_maxvcount)) #endif + { struct afs_q *tq, *uq; int i; char *panicstr; @@ -620,14 +629,59 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) for (tq = VLRU.prev; tq != &VLRU && anumber > 0; tq = uq) { tvc = QTOV(tq); uq = QPrev(tq); - if (tvc->states & CVFlushed) + if (tvc->states & CVFlushed) { refpanic("CVFlushed on VLRU"); - else if (i++ > afs_maxvcount) + } else if (i++ > afs_maxvcount) { refpanic("Exceeded pool of AFS vnodes(VLRU cycle?)"); - else if (QNext(uq) != tq) + } else if (QNext(uq) != tq) { refpanic("VLRU inconsistent"); - else if (VREFCOUNT(tvc) < 1) + } else if (VREFCOUNT(tvc) < 1) { refpanic("refcnt 0 on VLRU"); + } + +#if defined(AFS_LINUX22_ENV) + if (tvc != afs_globalVp && VREFCOUNT(tvc) > 1 && tvc->opens == 0) { + struct dentry *dentry; + struct list_head *cur, *head; + AFS_FAST_HOLD(tvc); + AFS_GUNLOCK(); +#if defined(AFS_LINUX24_ENV) + spin_lock(&dcache_lock); +#endif + head = &(AFSTOV(tvc))->i_dentry; + +restart: + cur = head; + while ((cur = cur->next) != head) { + dentry = list_entry(cur, struct dentry, d_alias); + + if (d_unhashed(dentry)) + continue; + + dget_locked(dentry); + +#if defined(AFS_LINUX24_ENV) + spin_unlock(&dcache_lock); +#endif + if (d_invalidate(dentry) == -EBUSY) { + dput(dentry); + /* perhaps lock and try to continue? (use cur as head?) */ + goto inuse; + } + dput(dentry); +#if defined(AFS_LINUX24_ENV) + spin_lock(&dcache_lock); +#endif + goto restart; + } +#if defined(AFS_LINUX24_ENV) + spin_unlock(&dcache_lock); +#endif + inuse: + AFS_GLOCK(); + AFS_FAST_RELE(tvc); + } +#endif if (VREFCOUNT(tvc) == 1 && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) { @@ -655,6 +709,24 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) } } +#if defined(AFS_LINUX22_ENV) +{ + struct inode *ip; + + AFS_GUNLOCK(); + ip = new_inode(afs_globalVFS); + if (!ip) + osi_Panic("afs_NewVCache: no more inodes"); + AFS_GLOCK(); +#if defined(STRUCT_SUPER_HAS_ALLOC_INODE) + tvc = VTOAFS(ip); +#else + tvc = afs_osi_Alloc(sizeof(struct vcache)); + ip->u.generic_ip = tvc; + tvc->v = ip; +#endif +} +#else AFS_GUNLOCK(); if (getnewvnode(MOUNT_AFS, &Afs_vnodeops, &nvc)) { /* What should we do ???? */ @@ -664,6 +736,7 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) tvc = nvc; tvc->nextfree = NULL; +#endif afs_vcount++; #else /* AFS_OSF_ENV */ /* pull out a free cache entry */ @@ -682,45 +755,6 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) } else if (QNext(uq) != tq) { refpanic("VLRU inconsistent"); } -#if defined(AFS_LINUX22_ENV) - if (tvc != afs_globalVp && VREFCOUNT(tvc) && tvc->opens == 0) { - struct dentry *dentry; - struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry; - AFS_FAST_HOLD(tvc); - AFS_GUNLOCK(); - -restart: -#if defined(AFS_LINUX24_ENV) - spin_lock(&dcache_lock); -#endif - cur = head; - while ((cur = cur->next) != head) { - dentry = list_entry(cur, struct dentry, d_alias); - - if (d_unhashed(dentry)) - continue; - - dget_locked(dentry); - -#if defined(AFS_LINUX24_ENV) - spin_unlock(&dcache_lock); -#endif - if (d_invalidate(dentry) == -EBUSY) { - dput(dentry); - /* perhaps lock and try to continue? (use cur as head?) */ - goto inuse; - } - dput(dentry); - goto restart; - } -#if defined(AFS_LINUX24_ENV) - spin_unlock(&dcache_lock); -#endif - inuse: - AFS_GLOCK(); - AFS_FAST_RELE(tvc); - } -#endif if (((VREFCOUNT(tvc) == 0) #if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) @@ -797,7 +831,7 @@ restart: panic("afs_NewVCache(): free vcache with vnode attached"); #endif -#if !defined(AFS_SGI_ENV) && !defined(AFS_OSF_ENV) +#if !defined(AFS_SGI_ENV) && !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV) memset((char *)tvc, 0, sizeof(struct vcache)); #else tvc->uncred = 0; @@ -871,92 +905,8 @@ restart: hzero(tvc->mapDV); tvc->truncPos = AFS_NOTRUNC; /* don't truncate until we need to */ hzero(tvc->m.DataVersion); /* in case we copy it into flushDV */ -#if defined(AFS_LINUX22_ENV) - { - struct inode *ip = AFSTOI(tvc); -#if defined(AFS_LINUX24_ENV) - struct address_space *mapping = &ip->i_data; -#endif - -#if defined(AFS_LINUX26_ENV) - inode_init_once(ip); -#else - sema_init(&ip->i_sem, 1); - INIT_LIST_HEAD(&ip->i_hash); - INIT_LIST_HEAD(&ip->i_dentry); -#if defined(AFS_LINUX24_ENV) - sema_init(&ip->i_zombie, 1); - init_waitqueue_head(&ip->i_wait); - spin_lock_init(&ip->i_data.i_shared_lock); -#ifdef STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK - spin_lock_init(&ip->i_data.page_lock); -#endif - INIT_LIST_HEAD(&ip->i_data.clean_pages); - INIT_LIST_HEAD(&ip->i_data.dirty_pages); - INIT_LIST_HEAD(&ip->i_data.locked_pages); - INIT_LIST_HEAD(&ip->i_dirty_buffers); -#ifdef STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS - INIT_LIST_HEAD(&ip->i_dirty_data_buffers); -#endif -#ifdef STRUCT_INODE_HAS_I_DEVICES - INIT_LIST_HEAD(&ip->i_devices); -#endif -#ifdef STRUCT_INODE_HAS_I_TRUNCATE_SEM - init_rwsem(&ip->i_truncate_sem); -#endif -#ifdef STRUCT_INODE_HAS_I_ALLOC_SEM - init_rwsem(&ip->i_alloc_sem); -#endif - -#else /* AFS_LINUX22_ENV */ - sema_init(&ip->i_atomic_write, 1); - init_waitqueue(&ip->i_wait); -#endif -#endif -#if defined(AFS_LINUX24_ENV) - mapping->host = ip; - ip->i_mapping = mapping; -#ifdef STRUCT_ADDRESS_SPACE_HAS_GFP_MASK - ip->i_data.gfp_mask = GFP_HIGHUSER; -#endif -#if defined(AFS_LINUX26_ENV) - mapping_set_gfp_mask(mapping, GFP_HIGHUSER); - { - extern struct backing_dev_info afs_backing_dev_info; - - mapping->backing_dev_info = &afs_backing_dev_info; - } -#endif -#endif - -#if !defined(AFS_LINUX26_ENV) - if (afs_globalVFS) - ip->i_dev = afs_globalVFS->s_dev; -#else -#ifdef STRUCT_INODE_HAS_I_SECURITY - ip->i_security = NULL; - if (security_inode_alloc(ip)) - panic("Cannot allocate inode security"); -#endif -#endif - ip->i_sb = afs_globalVFS; - put_inode_on_dummy_list(ip); -#ifdef STRUCT_INODE_HAS_I_SB_LIST - list_add(&ip->i_sb_list, &ip->i_sb->s_inodes); -#endif -#if defined(STRUCT_INODE_HAS_INOTIFY_LOCK) || defined(STRUCT_INODE_HAS_INOTIFY_SEM) - INIT_LIST_HEAD(&ip->inotify_watches); -#if defined(STRUCT_INODE_HAS_INOTIFY_SEM) - sema_init(&ip->inotify_sem, 1); -#else - spin_lock_init(&ip->inotify_lock); -#endif -#endif - } -#endif - -#ifdef AFS_OSF_ENV +#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) /* Hold it for the LRU (should make count 2) */ VN_HOLD(AFSTOV(tvc)); #else /* AFS_OSF_ENV */ @@ -1040,7 +990,9 @@ restart: tvc->mvstat = 2; if (afs_globalVFS == 0) osi_Panic("afs globalvfs"); +#if !defined(AFS_LINUX22_ENV) vSetVfsp(tvc, afs_globalVFS); +#endif vSetType(tvc, VREG); #ifdef AFS_AIX_ENV tvc->v.v_vfsnext = afs_globalVFS->vfs_vnodes; /* link off vfs */ @@ -1576,10 +1528,6 @@ afs_ProcessFS(register struct vcache *avc, else /* not found, add a new one if possible */ afs_AddAxs(avc->Access, areq->uid, astat->CallerAccess); } -#ifdef AFS_LINUX22_ENV - vcache2inode(avc); /* Set the inode attr cache */ -#endif - } /*afs_ProcessFS */ @@ -1709,9 +1657,6 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, ObtainWriteLock(&tvc->lock, 54); if (tvc->states & CStatd) { -#ifdef AFS_LINUX22_ENV - vcache2inode(tvc); -#endif ReleaseWriteLock(&tvc->lock); return tvc; } @@ -2572,10 +2517,6 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) else afs_stats_cmperf.vremoteAccesses++; } -#ifdef AFS_LINUX22_ENV - if (tvc && (tvc->states & CStatd)) - vcache2inode(tvc); /* mainly to reset i_nlink */ -#endif return tvc; } /*afs_FindVCache */ @@ -2730,9 +2671,11 @@ afs_vcacheInit(int astatSize) { register struct vcache *tvp; int i; -#if defined(AFS_OSF_ENV) +#if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) if (!afs_maxvcount) { -#if defined(AFS_OSF30_ENV) +#if defined(AFS_LINUX22_ENV) + afs_maxvcount = astatSize; /* no particular limit on linux? */ +#elif defined(AFS_OSF30_ENV) afs_maxvcount = max_vnodes / 2; /* limit ourselves to half the total */ #else afs_maxvcount = nvnode / 2; /* limit ourselves to half the total */ @@ -2748,18 +2691,7 @@ afs_vcacheInit(int astatSize) RWLOCK_INIT(&afs_xvcache, "afs_xvcache"); LOCK_INIT(&afs_xvcb, "afs_xvcb"); -#if !defined(AFS_OSF_ENV) -#ifdef AFS_LINUX26_ENV - printf("old style would have needed %d contiguous bytes\n", astatSize * - sizeof(struct vcache)); - Initial_freeVCList = freeVCList = tvp = (struct vcache *) - afs_osi_Alloc(sizeof(struct vcache)); - for (i = 0; i < astatSize; i++) { - tvp->nextfree = (struct vcache *) afs_osi_Alloc(sizeof(struct vcache)); - tvp = tvp->nextfree; - } - tvp->nextfree = NULL; -#else +#if !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV) /* Allocate and thread the struct vcache entries */ tvp = (struct vcache *)afs_osi_Alloc(astatSize * sizeof(struct vcache)); memset((char *)tvp, 0, sizeof(struct vcache) * astatSize); @@ -2774,7 +2706,6 @@ afs_vcacheInit(int astatSize) pin((char *)tvp, astatSize * sizeof(struct vcache)); /* XXX */ #endif #endif -#endif #if defined(AFS_SGI_ENV) for (i = 0; i < astatSize; i++) { @@ -2884,26 +2815,14 @@ shutdown_vcache(void) } afs_cbrSpace = 0; -#ifdef AFS_LINUX26_ENV - { - struct vcache *tvp = Initial_freeVCList; - while (tvp) { - struct vcache *next = tvp->nextfree; - - afs_osi_Free(tvp, sizeof(struct vcache)); - tvp = next; - } - } -#else #ifdef KERNEL_HAVE_PIN unpin(Initial_freeVCList, afs_cacheStats * sizeof(struct vcache)); #endif -#if !defined(AFS_OSF_ENV) +#if !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV) afs_osi_Free(Initial_freeVCList, afs_cacheStats * sizeof(struct vcache)); #endif -#endif -#if !defined(AFS_OSF_ENV) +#if !defined(AFS_OSF_ENV) && !defined(AFS_LINUX22_ENV) freeVCList = Initial_freeVCList = 0; #endif RWLOCK_INIT(&afs_xvcache, "afs_xvcache"); diff --git a/src/cf/linux-test2.m4 b/src/cf/linux-test2.m4 index cc7d39c1c..96bfe2e2e 100644 --- a/src/cf/linux-test2.m4 +++ b/src/cf/linux-test2.m4 @@ -82,6 +82,7 @@ AC_MSG_CHECKING(whether to build osi_vfs.h) configdir=ifelse([$1], ,[src/config],$1) outputdir=ifelse([$2], ,[src/afs/LINUX],$2) tmpldir=ifelse([$3], ,[src/afs/LINUX],$3) -chmod +x $configdir/make_vnode.pl -$configdir/make_vnode.pl -i $LINUX_KERNEL_PATH -t ${tmpldir} -o $outputdir +cp $tmpldir/osi_vfs.hin $outputdir/osi_vfs.h +# chmod +x $configdir/make_vnode.pl +# $configdir/make_vnode.pl -i $LINUX_KERNEL_PATH -t ${tmpldir} -o $outputdir ]) diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index ffb96e42b..64032f9cf 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -467,3 +467,18 @@ ac_cv_linux_sched_struct_task_struct_has_exit_state=yes, ac_cv_linux_sched_struct_task_struct_has_exit_state=no)]) AC_MSG_RESULT($ac_cv_linux_sched_struct_task_struct_has_exit_state) CPPFLAGS="$save_CPPFLAGS"]) + +AC_DEFUN([LINUX_FS_STRUCT_SUPER_HAS_ALLOC_INODE], [ +AC_MSG_CHECKING(for alloc_inode in struct super_operations) +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" +AC_CACHE_VAL(ac_cv_linux_fs_struct_super_has_alloc_inode, +[ +AC_TRY_COMPILE( +[#include ], +[struct super_operations _super; +printf("%p\n", _super.alloc_inode);], +ac_cv_linux_fs_struct_super_has_alloc_inode=yes, +ac_cv_linux_fs_struct_super_has_alloc_inode=no)]) +AC_MSG_RESULT($ac_cv_linux_fs_struct_super_has_alloc_inode) +CPPFLAGS="$save_CPPFLAGS"]) diff --git a/src/venus/kdump.c b/src/venus/kdump.c index b16d91921..ceeb8ce38 100644 --- a/src/venus/kdump.c +++ b/src/venus/kdump.c @@ -2885,7 +2885,7 @@ print_vcache(kmem, vep, ptr, pnt) printf("\n"); #ifdef AFS33 printf("%lx: refC=%d, pv=%d, pu=%d, flushDv=%d.%d, mapDV=%d.%d, ", - ptr, vep->vrefCount, vep->parentVnode, vep->parentUnique, + ptr, VREFCOUNT(vep), vep->parentVnode, vep->parentUnique, vep->flushDV.high, vep->flushDV.low, vep->mapDV.high, vep->mapDV.low); #ifdef AFS_64BIT_CLIENT -- 2.39.5