From fcddefb76af8a5bed1729ddbc6e2db9d3f3040ca Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Thu, 8 Oct 2009 21:53:03 -0400 Subject: [PATCH] Linux: kmem_cache_create fix and cleanup Fix the kmem_cache constructor function to match the current expected prototype, and cleanup related code. This has been wrong for a while, but since we were just passing extra parameters the only effect was to generate a warning. - Add a new configure test to detect the new constructor function signature - Define the older versions of the constructor in osi_compat.h, making them call the current version - Move a few compatibility #defines to osi_compat.h (cherry picked from 3abc87a5a94f0d5eaca702c7bd66fbe35ce7b896) Reviewed-on: http://gerrit.openafs.org/657 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear Change-Id: I3570a3268d35ac73409b96816ba5112f809f6645 Reviewed-on: http://gerrit.openafs.org/994 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- acinclude.m4 | 1 + src/afs/LINUX/osi_compat.h | 139 +++++++++++++++++++++++++++++++++++++ src/afs/LINUX/osi_vfsops.c | 45 +++--------- src/cf/linux-test4.m4 | 18 +++++ 4 files changed, 168 insertions(+), 35 deletions(-) create mode 100644 src/afs/LINUX/osi_compat.h diff --git a/acinclude.m4 b/acinclude.m4 index 65380560d..1c7a7deae 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -742,6 +742,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_HAVE_BDI_INIT LINUX_HAVE_KMEM_CACHE_T LINUX_KMEM_CACHE_CREATE_TAKES_DTOR + LINUX_KMEM_CACHE_CREATE_CTOR_TAKES_VOID LINUX_CONFIG_H_EXISTS LINUX_COMPLETION_H_EXISTS LINUX_SEMAPHORE_H_EXISTS diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h new file mode 100644 index 000000000..bcbb42ac5 --- /dev/null +++ b/src/afs/LINUX/osi_compat.h @@ -0,0 +1,139 @@ +/* Kernel compatibility routines + * + * This file contains definitions to provide compatibility between different + * versions of the Linux kernel. It is an ifdef maze, but the idea is that + * by concentrating the horror here, the rest of the tree may remaing a + * little cleaner... + */ + +#ifndef AFS_LINUX_OSI_COMPAT_H +#define AFS_LINUX_OSI_COMPAT_H + +#ifndef DO_SYNC_READ +static inline int +do_sync_read(struct file *fp, char *buf, size_t count, loff_t *offp) { + return generic_file_read(fp, buf, count, offp); +} + +static inline int +do_sync_write(struct file *fp, char *buf, size_t count, loff_t *offp) { + return generic_file_write(fp, buf, count, offp); +} + +#endif /* DO_SYNC_READ */ + +static inline int +afs_posix_lock_file(struct file *fp, struct file_lock *flp) { +#ifdef POSIX_LOCK_FILE_WAIT_ARG + return posix_lock_file(fp, flp, NULL); +#else + flp->fl_flags &=~ FL_SLEEP; + return posix_lock_file(fp, flp); +#endif +} + +static inline void +afs_posix_test_lock(struct file *fp, struct file_lock *flp) { +#if defined(POSIX_TEST_LOCK_CONFLICT_ARG) + struct file_lock conflict; + if (posix_test_lock(fp, flp, &conflict)) { + locks_copy_lock(flp, &conflict); + flp->fl_type = F_UNLCK; + } +#elif defined(POSIX_TEST_LOCK_RETURNS_CONFLICT) + struct file_lock *conflict; + if (conflict = posix_test_lock(fp, flp)) { + locks_copy_lock(flp, conflict); + flp->fl_type = F_UNLCK; + } +#else + posix_test_lock(fp, flp); +#endif +} + +#ifdef DCACHE_NFSFS_RENAMED +static inline void +afs_linux_clear_nfsfs_renamed(struct dentry *dp) { + spin_lock(&dp->d_lock); + dp->d_flags &= ~DCACHE_NFSFS_RENAMED; + spin_unlock(&dp->d_lock); +} + +static inline void +afs_linux_set_nfsfs_renamed(struct dentry *dp) { + spin_lock(&dp->d_lock); + dp->d_flags |= DCACHE_NFSFS_RENAMED; + spin_unlock(&dp->d_lock); +} +#else +static inline void afs_linux_clear_nfsfs_renamed(void) { return; } +static inline void afs_linux_set_nfsfs_renamed(void) { return; } +#endif + +#ifndef HAVE_KERNEL_HLIST_UNHASHED +static void +hlist_unhashed(const struct hlist_node *h) { + return (!h->pprev == NULL); +} +#endif + +#if defined(WRITEPAGE_ACTIVATE) +#define AOP_WRITEPAGE_ACTIVATE WRITEPAGE_ACTIVATE +#endif + +#if defined(HAVE_WRITE_BEGIN) && !defined(HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN) +static inline struct page * +grab_cache_page_write_begin(struct address_space *mapping, pgoff_t index, + unsigned int flags) { + return __grab_cache_page(mapping, index); +} +#endif + +#if defined(HAVE_KMEM_CACHE_T) +#define afs_kmem_cache_t kmem_cache_t +#else +#define afs_kmem_cache_t struct kmem_cache +#endif + +extern void init_once(void *); +#if defined(HAVE_KMEM_CACHE_T) +static inline void +init_once_func(void * foo, kmem_cache_t * cachep, unsigned long flags) { +#if defined(SLAB_CTOR_VERIFY) + if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) +#endif + init_once(foo); +} +#elif defined(KMEM_CACHE_INIT) +static inline void +init_once_func(struct kmem_cache * cachep, void * foo) { + init_once(foo); +} +#elif !defined(KMEM_CACHE_CTOR_TAKES_VOID) +static inline void +init_once_func(void * foo, struct kmem_cache * cachep, unsigned long flags) { +#if defined(SLAB_CTOR_VERIFY) + if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) +#endif + init_once(foo); +} +#else +static inline void +init_once_func(void * foo) { + init_once(foo); +} +#endif + +#ifndef SLAB_RECLAIM_ACCOUNT +#define SLAB_RECLAIM_ACCOUNT 0 +#endif + +#if defined(SLAB_KERNEL) +#define KALLOC_TYPE SLAB_KERNEL +#else +#define KALLOC_TYPE GFP_KERNEL +#endif + +#endif diff --git a/src/afs/LINUX/osi_vfsops.c b/src/afs/LINUX/osi_vfsops.c index abd555eaa..5af9fd416 100644 --- a/src/afs/LINUX/osi_vfsops.c +++ b/src/afs/LINUX/osi_vfsops.c @@ -28,6 +28,7 @@ #include "h/smp_lock.h" #endif +#include "osi_compat.h" struct vcache *afs_globalVp = 0; struct vfs *afs_globalVFS = 0; @@ -270,22 +271,14 @@ afs_notify_change(struct dentry *dp, struct iattr *iattrp) #if defined(STRUCT_SUPER_HAS_ALLOC_INODE) -#if defined(HAVE_KMEM_CACHE_T) -static kmem_cache_t *afs_inode_cachep; -#else -struct kmem_cache *afs_inode_cachep; -#endif +static afs_kmem_cache_t *afs_inode_cachep; static struct inode * afs_alloc_inode(struct super_block *sb) { struct vcache *vcp; -#if defined(SLAB_KERNEL) - vcp = (struct vcache *) kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL); -#else - vcp = (struct vcache *) kmem_cache_alloc(afs_inode_cachep, GFP_KERNEL); -#endif + vcp = (struct vcache *) kmem_cache_alloc(afs_inode_cachep, KALLOC_TYPE); if (!vcp) return NULL; @@ -298,43 +291,25 @@ afs_destroy_inode(struct inode *inode) kmem_cache_free(afs_inode_cachep, inode); } -static void -#if defined(HAVE_KMEM_CACHE_T) -init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) -#else -#if defined(KMEM_CACHE_INIT) -init_once(struct kmem_cache * cachep, void * foo) -#else -init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) -#endif -#endif +void +init_once(void * foo) { struct vcache *vcp = (struct vcache *) foo; -#if defined(SLAB_CTOR_VERIFY) - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) -#endif - inode_init_once(AFSTOV(vcp)); + inode_init_once(AFSTOV(vcp)); } int afs_init_inodecache(void) { -#ifndef SLAB_RECLAIM_ACCOUNT -#define SLAB_RECLAIM_ACCOUNT 0 -#endif - #if defined(KMEM_CACHE_TAKES_DTOR) afs_inode_cachep = kmem_cache_create("afs_inode_cache", - sizeof(struct vcache), - 0, SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT, - init_once, NULL); + sizeof(struct vcache), 0, + SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT, init_once_func, NULL); #else afs_inode_cachep = kmem_cache_create("afs_inode_cache", - sizeof(struct vcache), - 0, SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT, - init_once); + sizeof(struct vcache), 0, + SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT, init_once_func); #endif if (afs_inode_cachep == NULL) return -ENOMEM; diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 4ac688fa0..c3f1bf9d2 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -949,6 +949,24 @@ AC_DEFUN([LINUX_KMEM_CACHE_CREATE_TAKES_DTOR], [ ac_cv_linux_kmem_cache_create_takes_dtor=no)]) AC_MSG_RESULT($ac_cv_linux_kmem_cache_create_takes_dtor)]) +AC_DEFUN([LINUX_KMEM_CACHE_CREATE_CTOR_TAKES_VOID], [ + AC_MSG_CHECKING([whether kmem_cache_create constructor function takes a void pointer argument]) + AC_CACHE_VAL([ac_cv_linux_kmem_cache_create_ctor_takes_void], [ + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -Werror" + AC_TRY_KBUILD( +[#include ], +[void _ctor(void *v) { }; +kmem_cache_create(NULL, 0, 0, 0, _ctor);], + ac_cv_linux_kmem_cache_create_ctor_takes_void=yes, + ac_cv_linux_kmem_cache_create_ctor_takes_void=no) + CPPFLAGS="$save_CPPFLAGS" +]) + AC_MSG_RESULT($ac_cv_linux_kmem_cache_create_ctor_takes_void) + if test "x$ac_cv_linux_kmem_cache_create_ctor_takes_void" = "xyes"; then + AC_DEFINE([KMEM_CACHE_CTOR_TAKES_VOID], 1, [define if kmem_cache_create constructor function takes a single void pointer argument]) + fi]) + AC_DEFUN([LINUX_FS_STRUCT_FOP_HAS_SENDFILE], [ AC_MSG_CHECKING([for sendfile in struct file_operations]) AC_CACHE_VAL([ac_cv_linux_fs_struct_fop_has_sendfile], [ -- 2.39.5