From 53774c945e91ea344cbe51c9fafae8acf711f558 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Mon, 28 May 2012 21:43:12 -0400 Subject: [PATCH 01/12] Linux 3.4: replace end_writeback with clear_inode end_writeback() is renamed to clear_inode(). Add a configure test and cope. Change-Id: Icaf5b6b54d0ee377fabcf0b295d690eaa6b4be5e Reviewed-on: http://gerrit.openafs.org/7503 Reviewed-by: Derrick Brashear Tested-by: BuildBot (cherry picked from commit 2b33384a4a7b88842281021129ffccc837d91d36) --- acinclude.m4 | 3 +++ src/afs/LINUX/osi_vfsops.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 6e2c9ae..c14b581 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -840,6 +840,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) #include ], [struct page *_page; int bchecked = PageFsMisc(_page);]) + AC_CHECK_LINUX_FUNC([clear_inode], + [#include ], + [clear_inode(NULL);]) AC_CHECK_LINUX_FUNC([current_kernel_time], [#include ], [struct timespec s; diff --git a/src/afs/LINUX/osi_vfsops.c b/src/afs/LINUX/osi_vfsops.c index a6be1b3..bc951a2 100644 --- a/src/afs/LINUX/osi_vfsops.c +++ b/src/afs/LINUX/osi_vfsops.c @@ -284,7 +284,11 @@ afs_evict_inode(struct inode *ip) osi_Panic("inode freed while still hashed"); truncate_inode_pages(&ip->i_data, 0); +#if defined(HAVE_LINUX_CLEAR_INODE) + clear_inode(ip); +#else end_writeback(ip); +#endif #if !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE) afs_osi_Free(ip->u.generic_ip, sizeof(struct vcache)); -- 1.8.0 From 235dee4c449bb5d5307f9b14d5effa4509d58efc Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Sat, 2 Jun 2012 21:35:53 -0400 Subject: [PATCH 02/12] Linux 3.5: encode_fh API change The encode_fh export operation now expects two inode arguments instead of a dentry and a "connectable" flag. Use the inode of the dentry we're interested in, and NULL as the parent inode which is the same as passing a 0 flag in the previous API. Change-Id: I05cf146fb2a4bacdca20a9f108d04ccb11530804 Reviewed-on: http://gerrit.openafs.org/7523 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 5227148ae17949705487ea673d558ebfe143e635) --- acinclude.m4 | 1 + src/afs/LINUX/osi_compat.h | 4 ++++ src/cf/linux-test4.m4 | 14 ++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index c14b581..25484cf 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -958,6 +958,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_D_COUNT_IS_INT LINUX_IOP_MKDIR_TAKES_UMODE_T LINUX_IOP_CREATE_TAKES_UMODE_T + LINUX_EXPORT_OP_ENCODE_FH_TAKES_INODES dnl If we are guaranteed that keyrings will work - that is dnl a) The kernel has keyrings enabled diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index b94295c..4c7c261 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -333,7 +333,11 @@ afs_get_dentry_from_fh(struct super_block *afs_cacheSBp, afs_dcache_id_t *ainode static inline int afs_get_fh_from_dentry(struct dentry *dp, afs_ufs_dcache_id_t *ainode, int *max_lenp) { if (dp->d_sb->s_export_op->encode_fh) +#if defined(EXPORT_OP_ENCODE_FH_TAKES_INODES) + return dp->d_sb->s_export_op->encode_fh(dp->d_inode, &ainode->raw[0], max_lenp, NULL); +#else return dp->d_sb->s_export_op->encode_fh(dp, &ainode->raw[0], max_lenp, 0); +#endif #if defined(NEW_EXPORT_OPS) /* If fs doesn't provide an encode_fh method, assume the default INO32 type */ *max_lenp = sizeof(struct fid)/4; diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index f5e91b1..f13e97d 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -661,3 +661,17 @@ AC_DEFUN([LINUX_IOP_CREATE_TAKES_UMODE_T], [ [define if inode.i_op->create takes a umode_t argument], [-Werror]) ]) + + +AC_DEFUN([LINUX_EXPORT_OP_ENCODE_FH_TAKES_INODES], [ + AC_CHECK_LINUX_BUILD([whether export operation encode_fh takes inode arguments], + [ac_cv_linux_export_op_encode_fh__takes_inodes], + [#include ], + [struct export_operations _exp_ops; + int _encode_fh(struct inode *i, __u32 *fh, int *len, struct inode *p) + {return 0;}; + _exp_ops.encode_fh = _encode_fh;], + [EXPORT_OP_ENCODE_FH_TAKES_INODES], + [define if encode_fh export op takes inode arguments], + [-Werror]) +]) -- 1.8.0 From f6093c4716d36b7499b5c84950e6ec4480745467 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Sat, 2 Jun 2012 20:45:08 -0400 Subject: [PATCH 03/12] afsd: include sys/resource.h in afsd_kernel.c With a recent glibc update, sys/wait.h no longer includes sys/resource.h unless __USE_SVID, __USE_XOPEN or __USE_XOPEN2K8 are set. Don't rely on the indirect inclusion to get the bits we need; include it directly in afsd_kernel.c. This include used to be there but was dropped when afsd_kernel.c was split off. Reviewed-on: http://gerrit.openafs.org/7522 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit bc3a32a84facb8114a8c7de87025f972d0281098) Change-Id: Ia5ba6a0e662607e680b4431f146c969b7069bcfd Reviewed-on: http://gerrit.openafs.org/8155 Reviewed-by: Ken Dreyer Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear (cherry picked from commit 5842f856652051a4386b1e0170f18dca911ca4c6) --- src/afsd/afsd_kernel.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/afsd/afsd_kernel.c b/src/afsd/afsd_kernel.c index 1f7fdbb..e1e87a7 100644 --- a/src/afsd/afsd_kernel.c +++ b/src/afsd/afsd_kernel.c @@ -37,6 +37,10 @@ #include #endif +#if defined(AFS_LINUX20_ENV) +#include +#endif + #ifdef HAVE_SYS_FS_TYPES_H #include #endif -- 1.8.0 From 31a7f5ef2fcb81c2510834befd15fb057d067eaf Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Mon, 13 Aug 2012 20:32:08 -0400 Subject: [PATCH 04/12] Linux: bypass: consolidate copy_page macros into a single function The copy_page(s) macros are very similar; combine them into a single function that can be used for all cases. This will make it easier to add some pre-processor logic around the kmap_atomic calls to adapt to Linux API changes. Reviewed-on: http://gerrit.openafs.org/7980 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 0a8256a26fafb490b454f2a857b0c15d859572c5) Change-Id: I6835a024428b26a8cd8d073f6304d0d0b3042b24 Reviewed-on: http://gerrit.openafs.org/8077 Reviewed-by: Derrick Brashear Reviewed-by: Ken Dreyer Tested-by: BuildBot (cherry picked from commit 54db9af1a87c03d6f00ab70565c9d1f733813fc2) --- src/afs/afs_bypasscache.c | 63 ++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/src/afs/afs_bypasscache.c b/src/afs/afs_bypasscache.c index e447024..b350233 100644 --- a/src/afs/afs_bypasscache.c +++ b/src/afs/afs_bypasscache.c @@ -270,49 +270,12 @@ done: #ifdef UKERNEL typedef void * bypass_page_t; -#define copy_page(pp, pageoff, rxiov, iovno, iovoff, auio, curiov) \ - do { \ - int dolen = auio->uio_iov[curiov].iov_len - pageoff; \ - memcpy(((char *)pp) + pageoff, \ - ((char *)rxiov[iovno].iov_base) + iovoff, dolen); \ - auio->uio_resid -= dolen; \ - } while(0) - -#define copy_pages(pp, pageoff, rxiov, iovno, iovoff, auio, curiov) \ - do { \ - int dolen = rxiov[iovno].iov_len - iovoff; \ - memcpy(((char *)pp) + pageoff, \ - ((char *)rxiov[iovno].iov_base) + iovoff, dolen); \ - auio->uio_resid -= dolen; \ - } while(0) - #define unlock_and_release_pages(auio) #define release_full_page(pp, pageoff) #else typedef struct page * bypass_page_t; -#define copy_page(pp, pageoff, rxiov, iovno, iovoff, auio, curiov) \ - do { \ - char *address; \ - int dolen = auio->uio_iov[curiov].iov_len - pageoff; \ - address = kmap_atomic(pp, KM_USER0); \ - memcpy(address + pageoff, \ - (char *)(rxiov[iovno].iov_base) + iovoff, dolen); \ - kunmap_atomic(address, KM_USER0); \ - } while(0) - -#define copy_pages(pp, pageoff, rxiov, iovno, iovoff, auio, curiov) \ - do { \ - char *address; \ - int dolen = rxiov[iovno].iov_len - iovoff; \ - address = kmap_atomic(pp, KM_USER0); \ - memcpy(address + pageoff, \ - (char *)(rxiov[iovno].iov_base) + iovoff, dolen); \ - kunmap_atomic(address, KM_USER0); \ - } while(0) - - #define unlock_and_release_pages(auio) \ do { \ struct iovec *ciov; \ @@ -347,8 +310,30 @@ typedef struct page * bypass_page_t; afs_warn("afs_NoCacheFetchProc: page not locked!\n"); \ put_page(pp); /* decrement refcount */ \ } while(0) +#endif + +static void +afs_bypass_copy_page(bypass_page_t pp, int pageoff, struct iovec *rxiov, + int iovno, int iovoff, struct uio *auio, int curiov, int partial) +{ + char *address; + int dolen; + + if (partial) + dolen = rxiov[iovno].iov_len - iovoff; + else + dolen = auio->uio_iov[curiov].iov_len - pageoff; +#if !defined(UKERNEL) + address = kmap_atomic(pp, KM_USER0); +#else + address = pp; #endif + memcpy(address + pageoff, (char *)(rxiov[iovno].iov_base) + iovoff, dolen); +#if !defined(UKERNEL) + kunmap_atomic(address, KM_USER0); +#endif +} /* no-cache prefetch routine */ static afs_int32 @@ -447,7 +432,7 @@ afs_NoCacheFetchProc(struct rx_call *acall, if (pageoff + (rxiov[iovno].iov_len - iovoff) <= auio->uio_iov[curpage].iov_len) { /* Copy entire (or rest of) current iovec into current page */ if (pp) - copy_pages(pp, pageoff, rxiov, iovno, iovoff, auio, curpage); + afs_bypass_copy_page(pp, pageoff, rxiov, iovno, iovoff, auio, curpage, 0); length -= (rxiov[iovno].iov_len - iovoff); pageoff += rxiov[iovno].iov_len - iovoff; iovno++; @@ -455,7 +440,7 @@ afs_NoCacheFetchProc(struct rx_call *acall, } else { /* Copy only what's needed to fill current page */ if (pp) - copy_page(pp, pageoff, rxiov, iovno, iovoff, auio, curpage); + afs_bypass_copy_page(pp, pageoff, rxiov, iovno, iovoff, auio, curpage, 1); length -= (auio->uio_iov[curpage].iov_len - pageoff); iovoff += auio->uio_iov[curpage].iov_len - pageoff; pageoff = auio->uio_iov[curpage].iov_len; -- 1.8.0 From 51102503174a33c0bbb74a062a9413a0f041588e Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Tue, 14 Aug 2012 16:34:42 -0400 Subject: [PATCH 05/12] Linux 3.6: kmap_atomic API change kmap_atomic no longer requires a KM_TYPE argument. Test for this and adjust the affected code. Reviewed-on: http://gerrit.openafs.org/7981 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 049c485b4a39ba510035788b4959d839ef668c55) Change-Id: Iac8be7901da4b277864b1b6cc987cf5087992789 Reviewed-on: http://gerrit.openafs.org/8078 Reviewed-by: Derrick Brashear Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: Ken Dreyer Tested-by: BuildBot (cherry picked from commit 76ab286feb1570efa9763e076020fc43fb0a95fa) --- acinclude.m4 | 1 + src/afs/afs_bypasscache.c | 8 ++++++++ src/cf/linux-test4.m4 | 12 ++++++++++++ 3 files changed, 21 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 25484cf..20fd15e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -959,6 +959,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_IOP_MKDIR_TAKES_UMODE_T LINUX_IOP_CREATE_TAKES_UMODE_T LINUX_EXPORT_OP_ENCODE_FH_TAKES_INODES + LINUX_KMAP_ATOMIC_TAKES_NO_KM_TYPE dnl If we are guaranteed that keyrings will work - that is dnl a) The kernel has keyrings enabled diff --git a/src/afs/afs_bypasscache.c b/src/afs/afs_bypasscache.c index b350233..1138f89 100644 --- a/src/afs/afs_bypasscache.c +++ b/src/afs/afs_bypasscache.c @@ -325,13 +325,21 @@ afs_bypass_copy_page(bypass_page_t pp, int pageoff, struct iovec *rxiov, dolen = auio->uio_iov[curiov].iov_len - pageoff; #if !defined(UKERNEL) +# if defined(KMAP_ATOMIC_TAKES_NO_KM_TYPE) + address = kmap_atomic(pp); +# else address = kmap_atomic(pp, KM_USER0); +# endif #else address = pp; #endif memcpy(address + pageoff, (char *)(rxiov[iovno].iov_base) + iovoff, dolen); #if !defined(UKERNEL) +# if defined(KMAP_ATOMIC_TAKES_NO_KM_TYPE) + kunmap_atomic(address); +# else kunmap_atomic(address, KM_USER0); +# endif #endif } diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index f13e97d..7db805f 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -675,3 +675,15 @@ AC_DEFUN([LINUX_EXPORT_OP_ENCODE_FH_TAKES_INODES], [ [define if encode_fh export op takes inode arguments], [-Werror]) ]) + + +AC_DEFUN([LINUX_KMAP_ATOMIC_TAKES_NO_KM_TYPE], [ + AC_CHECK_LINUX_BUILD([whether kmap_atomic takes no km_type argument], + [ac_cv_linux_kma_atomic_takes_no_km_type], + [#include ], + [struct page *p = NULL; + kmap_atomic(p);], + [KMAP_ATOMIC_TAKES_NO_KM_TYPE], + [define if kmap_atomic takes no km_type argument], + [-Werror]) +]) -- 1.8.0 From f842c54d6cba963ce34f2d092c9586c6ee21a13c Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Mon, 13 Aug 2012 21:36:15 -0400 Subject: [PATCH 06/12] Linux 3.6: dentry_open API change dentry_open now takes a path argument that combines the dentry and the vfsmount pointers. Add a configure test and a new compat inline function to keep things cleaner in the main source file. Reviewed-on: http://gerrit.openafs.org/7982 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 8766a65e97eb90cb6c97ccd35181c441ece14f8a) Change-Id: I2c0f59ad9aa6e544a2a613e902933d463f22a5b6 Reviewed-on: http://gerrit.openafs.org/8079 Reviewed-by: Ken Dreyer Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 1bba9760b26bdb1ef1e17f9d1e15be9d565828cc) --- acinclude.m4 | 1 + src/afs/LINUX/osi_compat.h | 16 ++++++++++++++++ src/afs/LINUX/osi_file.c | 4 ++-- src/cf/linux-test4.m4 | 12 ++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 20fd15e..d99c755 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -960,6 +960,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_IOP_CREATE_TAKES_UMODE_T LINUX_EXPORT_OP_ENCODE_FH_TAKES_INODES LINUX_KMAP_ATOMIC_TAKES_NO_KM_TYPE + LINUX_DENTRY_OPEN_TAKES_PATH dnl If we are guaranteed that keyrings will work - that is dnl a) The kernel has keyrings enabled diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index 4c7c261..84fcaa5 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -445,4 +445,20 @@ afs_get_dentry_ref(struct path *path, struct vfsmount **mnt, struct dentry **dpp #endif } +#if defined(STRUCT_TASK_STRUCT_HAS_CRED) +static inline struct file * +afs_dentry_open(struct dentry *dp, struct vfsmount *mnt, int flags, const struct cred *creds) { +#if defined(DENTRY_OPEN_TAKES_PATH) + struct path path; + struct file *filp; + path.mnt = mnt; + path.dentry = dp; + filp = dentry_open(&path, flags, creds); + return filp; +#else + return dentry_open(dp, mntget(mnt), flags, creds); +#endif +} +#endif + #endif /* AFS_LINUX_OSI_COMPAT_H */ diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index 3c20fd9..27806ab 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -56,9 +56,9 @@ afs_linux_raw_open(afs_dcache_id_t *ainode) #if defined(STRUCT_TASK_STRUCT_HAS_CRED) /* Use stashed credentials - prevent selinux/apparmor problems */ - filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, cache_creds); + filp = afs_dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, cache_creds); if (IS_ERR(filp)) - filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, current_cred()); + filp = afs_dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, current_cred()); #else filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR); #endif diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 7db805f..427c5e1 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -687,3 +687,15 @@ AC_DEFUN([LINUX_KMAP_ATOMIC_TAKES_NO_KM_TYPE], [ [define if kmap_atomic takes no km_type argument], [-Werror]) ]) + + +AC_DEFUN([LINUX_DENTRY_OPEN_TAKES_PATH], [ + AC_CHECK_LINUX_BUILD([whether dentry_open takes a path argument], + [ac_cv_linux_dentry_open_takes_path], + [#include ], + [struct path p; + dentry_open(&p, 0, NULL);], + [DENTRY_OPEN_TAKES_PATH], + [define if dentry_open takes a path argument], + [-Werror]) +]) -- 1.8.0 From 1aebd8757ba9684e0be18d722797a594146cefce Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Mon, 13 Aug 2012 21:55:25 -0400 Subject: [PATCH 07/12] Linux 3.6: d_alias and i_dentry are now hlists The d_alias pointer is now the head of an hlist. This means the iterator is a different macro and has no "reverse" version since hlists have no direct pointer to the list tail. inode->i_dentry gets the same treatment. Adjust where we use it. Reviewed-on: http://gerrit.openafs.org/7983 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 6bea047fb404bde828c6358ae06f7941aa2bc959) Change-Id: I7e7b87e5f5c240f3f0ff25fa723c857ab9d0108c Reviewed-on: http://gerrit.openafs.org/8080 Reviewed-by: Derrick Brashear Reviewed-by: Ken Dreyer Tested-by: BuildBot (cherry picked from commit b5a66fb391b47848f023042e96c87a1b7d49b888) --- acinclude.m4 | 1 + src/afs/LINUX/osi_vcache.c | 12 ++++++++++++ src/afs/afs_daemons.c | 5 +++++ src/cf/linux-test4.m4 | 13 +++++++++++++ 4 files changed, 31 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index d99c755..d52d149 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -961,6 +961,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_EXPORT_OP_ENCODE_FH_TAKES_INODES LINUX_KMAP_ATOMIC_TAKES_NO_KM_TYPE LINUX_DENTRY_OPEN_TAKES_PATH + LINUX_D_ALIAS_IS_HLIST dnl If we are guaranteed that keyrings will work - that is dnl a) The kernel has keyrings enabled diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c index e82d78e..cd61c65 100644 --- a/src/afs/LINUX/osi_vcache.c +++ b/src/afs/LINUX/osi_vcache.c @@ -19,7 +19,11 @@ osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { struct dentry *dentry; struct inode *inode = AFSTOV(avc); +#if defined(D_ALIAS_IS_HLIST) + struct hlist_node *cur, *head; +#else struct list_head *cur, *head; +#endif /* First, see if we can evict the inode from the dcache */ if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) { @@ -53,12 +57,20 @@ restart: spin_unlock(&dcache_lock); #else /* HAVE_DCACHE_LOCK */ spin_lock(&inode->i_lock); +#if defined(D_ALIAS_IS_HLIST) + head = inode->i_dentry.first; +#else head = &inode->i_dentry; +#endif restart: cur = head; while ((cur = cur->next) != head) { +#if defined(D_ALIAS_IS_HLIST) + dentry = hlist_entry(cur, struct dentry, d_alias); +#else dentry = list_entry(cur, struct dentry, d_alias); +#endif spin_lock(&dentry->d_lock); if (d_unhashed(dentry)) { diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index 23655e3..f47be0e 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -396,8 +396,13 @@ afs_CheckRootVolume(void) spin_lock(&dp->d_lock); #endif #endif +#if defined(D_ALIAS_IS_HLIST) + hlist_del_init(&dp->d_alias); + hlist_add_head(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); +#else list_del_init(&dp->d_alias); list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); +#endif dp->d_inode = AFSTOV(vcp); #if defined(AFS_LINUX24_ENV) #if defined(AFS_LINUX26_ENV) diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 427c5e1..6b70059 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -699,3 +699,16 @@ AC_DEFUN([LINUX_DENTRY_OPEN_TAKES_PATH], [ [define if dentry_open takes a path argument], [-Werror]) ]) + + +AC_DEFUN([LINUX_D_ALIAS_IS_HLIST], [ + AC_CHECK_LINUX_BUILD([whether dentry->d_alias is an hlist], + [ac_cv_linux_d_alias_is_hlist], + [#include ], + [struct dentry *d = NULL; + struct hlist_node *hn = NULL; + d->d_alias = *hn;], + [D_ALIAS_IS_HLIST], + [define if dentry->d_alias is an hlist], + []) +]) -- 1.8.0 From 10f8f641542d9bc16c9a9c953324fa9d89b81607 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Tue, 14 Aug 2012 17:11:08 -0400 Subject: [PATCH 08/12] Linux: fix variable used to test for the iop create API Use correct variable when testing for the create API to use. This is just for looks - there is no effect since mkdir and create were changed in the same kernel release. Reviewed-on: http://gerrit.openafs.org/7984 Reviewed-by: Alistair Ferguson Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit c633a92a1bc7881f18ee641082ff2efe7da1a8cb) Change-Id: Ib23fe9a34bc07227614c149b0f16d3b0a067501b Reviewed-on: http://gerrit.openafs.org/8081 Reviewed-by: Ken Dreyer Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit aecd183acb34a0a9b850fb69eed472d2c9a27612) --- src/afs/LINUX/osi_vnodeops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 4cda547..b3bf115 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1094,7 +1094,7 @@ struct dentry_operations afs_dentry_operations = { * name is in kernel space at this point. */ static int -#if defined(IOP_MKDIR_TAKES_UMODE_T) +#if defined(IOP_CREATE_TAKES_UMODE_T) afs_linux_create(struct inode *dip, struct dentry *dp, umode_t mode, struct nameidata *nd) #else -- 1.8.0 From 6cbb9a258b73c28c0295f93b75cbd437efe3713a Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Tue, 14 Aug 2012 17:28:50 -0400 Subject: [PATCH 09/12] Linux 3.6: create inode operation API change The nameidata argument is dropped and a flag is added. Reviewed-on: http://gerrit.openafs.org/7985 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 020e32779c103817ca89caa51259fb53bc3dde79) Change-Id: Iae2a0301a1c4acb6835eb0bdca6ae22b143b2cda Reviewed-on: http://gerrit.openafs.org/8082 Reviewed-by: Ken Dreyer Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 5210d97865d974d5e14f68eec6a58b292d6b7893) --- acinclude.m4 | 1 + src/afs/LINUX/osi_vnodeops.c | 9 +++++---- src/cf/linux-test4.m4 | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index d52d149..1c84354 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -962,6 +962,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_KMAP_ATOMIC_TAKES_NO_KM_TYPE LINUX_DENTRY_OPEN_TAKES_PATH LINUX_D_ALIAS_IS_HLIST + LINUX_IOP_I_CREATE_TAKES_BOOL dnl If we are guaranteed that keyrings will work - that is dnl a) The kernel has keyrings enabled diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index b3bf115..8c8045b 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1094,17 +1094,18 @@ struct dentry_operations afs_dentry_operations = { * name is in kernel space at this point. */ static int -#if defined(IOP_CREATE_TAKES_UMODE_T) +#if defined(IOP_CREATE_TAKES_BOOL) +afs_linux_create(struct inode *dip, struct dentry *dp, umode_t mode, + bool excl) +#elif defined(IOP_CREATE_TAKES_UMODE_T) afs_linux_create(struct inode *dip, struct dentry *dp, umode_t mode, struct nameidata *nd) -#else -#ifdef IOP_CREATE_TAKES_NAMEIDATA +#elif defined(IOP_CREATE_TAKES_NAMEIDATA) afs_linux_create(struct inode *dip, struct dentry *dp, int mode, struct nameidata *nd) #else afs_linux_create(struct inode *dip, struct dentry *dp, int mode) #endif -#endif { struct vattr vattr; cred_t *credp = crref(); diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 6b70059..dc30770 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -712,3 +712,18 @@ AC_DEFUN([LINUX_D_ALIAS_IS_HLIST], [ [define if dentry->d_alias is an hlist], []) ]) + + +AC_DEFUN([LINUX_IOP_I_CREATE_TAKES_BOOL], [ + AC_CHECK_LINUX_BUILD([whether inode_operations.create takes a bool], + [ac_cv_linux_func_i_create_takes_bool], + [#include + #include ], + [struct inode _inode = {}; + struct dentry _dentry; + bool b = true; + (void)_inode.i_op->create(&_inode, &_dentry, 0, b);], + [IOP_CREATE_TAKES_BOOL], + [define if your iops.create takes a bool argument], + [-Werror]) +]) -- 1.8.0 From ebfd3de107e0dd97127aa12e572684cc98a457cf Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Tue, 14 Aug 2012 18:08:51 -0400 Subject: [PATCH 10/12] Linux 3.6: revalidate dentry op API change The nameidata argument is dropped, replaced by an unsigned flags value. The configure test is very specific; kernels with the older API with a signed int flags value should fall through. Reviewed-on: http://gerrit.openafs.org/7986 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 7413cd09a53f89882a46fd100bf6c501348f2188) Change-Id: Ie68d70dcf414d24e7e980c8a8f35b83550d2da7c Reviewed-on: http://gerrit.openafs.org/8083 Reviewed-by: Ken Dreyer Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 4ab59d7ee924a6be1d553f75a67b0b253cc85e88) --- acinclude.m4 | 1 + src/afs/LINUX/osi_vnodeops.c | 8 +++++++- src/cf/linux-test4.m4 | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 1c84354..8bb5bf7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -963,6 +963,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_DENTRY_OPEN_TAKES_PATH LINUX_D_ALIAS_IS_HLIST LINUX_IOP_I_CREATE_TAKES_BOOL + LINUX_DOP_D_REVALIDATE_TAKES_UNSIGNED dnl If we are guaranteed that keyrings will work - that is dnl a) The kernel has keyrings enabled diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 8c8045b..49f8b96 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -906,7 +906,9 @@ afs_linux_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *sta * later on, we shouldn't have to do it until later. Perhaps in the future.. */ static int -#ifdef DOP_REVALIDATE_TAKES_NAMEIDATA +#if defined(DOP_REVALIDATE_TAKES_UNSIGNED) +afs_linux_dentry_revalidate(struct dentry *dp, unsigned int flags) +#elif defined(DOP_REVALIDATE_TAKES_NAMEIDATA) afs_linux_dentry_revalidate(struct dentry *dp, struct nameidata *nd) #else afs_linux_dentry_revalidate(struct dentry *dp, int flags) @@ -921,7 +923,11 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags) #ifdef LOOKUP_RCU /* We don't support RCU path walking */ +# if defined(DOP_REVALIDATE_TAKES_UNSIGNED) + if (flags & LOOKUP_RCU) +# else if (nd->flags & LOOKUP_RCU) +# endif return -ECHILD; #endif AFS_GLOCK(); diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index dc30770..4a6ec02 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -727,3 +727,17 @@ AC_DEFUN([LINUX_IOP_I_CREATE_TAKES_BOOL], [ [define if your iops.create takes a bool argument], [-Werror]) ]) + + +AC_DEFUN([LINUX_DOP_D_REVALIDATE_TAKES_UNSIGNED], [ + AC_CHECK_LINUX_BUILD([whether dentry_operations.d_revalidate takes an unsigned int], + [ac_cv_linux_func_d_revalidate_takes_unsigned], + [#include + #include ], + [struct dentry_operations dops; + int reval(struct dentry *d, unsigned int i) { return 0; }; + dops.d_revalidate = reval;], + [DOP_REVALIDATE_TAKES_UNSIGNED], + [define if your dops.d_revalidate takes an unsigned int argument], + [-Werror]) +]) -- 1.8.0 From 208d7925bd59490712bfd6bedc41ba5e3a8f4a6c Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Tue, 14 Aug 2012 18:26:24 -0400 Subject: [PATCH 11/12] Linux 3.6: lookup inode operation API change The nameidata argument is replaced with an unsigned int flags argument. Reviewed-on: http://gerrit.openafs.org/7987 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit ec48dca871ef98adb69792a34047c6be5818f1b2) Change-Id: Ic8be26141ede6e1c4062872c79a846efb0045bda Reviewed-on: http://gerrit.openafs.org/8084 Reviewed-by: Ken Dreyer Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 6c22f2e1de91fa3080221df22fdcd05064b57307) --- acinclude.m4 | 1 + src/afs/LINUX/osi_vnodeops.c | 5 ++++- src/cf/linux-test4.m4 | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 8bb5bf7..4b49449 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -964,6 +964,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_D_ALIAS_IS_HLIST LINUX_IOP_I_CREATE_TAKES_BOOL LINUX_DOP_D_REVALIDATE_TAKES_UNSIGNED + LINUX_IOP_LOOKUP_TAKES_UNSIGNED dnl If we are guaranteed that keyrings will work - that is dnl a) The kernel has keyrings enabled diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 49f8b96..c376bd1 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1147,7 +1147,10 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode) /* afs_linux_lookup */ static struct dentry * -#ifdef IOP_LOOKUP_TAKES_NAMEIDATA +#if defined(IOP_LOOKUP_TAKES_UNSIGNED) +afs_linux_lookup(struct inode *dip, struct dentry *dp, + unsigned flags) +#elif defined(IOP_LOOKUP_TAKES_NAMEIDATA) afs_linux_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) #else diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 4a6ec02..fc0149f 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -741,3 +741,17 @@ AC_DEFUN([LINUX_DOP_D_REVALIDATE_TAKES_UNSIGNED], [ [define if your dops.d_revalidate takes an unsigned int argument], [-Werror]) ]) + + +AC_DEFUN([LINUX_IOP_LOOKUP_TAKES_UNSIGNED], [ + AC_CHECK_LINUX_BUILD([whether inode operation lookup takes an unsigned int], + [ac_cv_linux_func_lookup_takes_unsigned], + [#include + #include ], + [struct inode_operations iops; + struct dentry *look(struct inode *i, struct dentry *d, unsigned int j) { return NULL; }; + iops.lookup = look;], + [IOP_LOOKUP_TAKES_UNSIGNED], + [define if your iops.lookup takes an unsigned int argument], + [-Werror]) +]) -- 1.8.0 From 6c53a1dea7d8fe3174405febf2bf7b98a219824d Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Fri, 12 Oct 2012 16:25:43 -0400 Subject: [PATCH 12/12] Linux: osi_vcache: Fix loop for the hlist case An hlist is not circular, and the end is marked by a NULL next pointer. Reviewed-on: http://gerrit.openafs.org/8233 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 78ae01fb9837d79e7bbdb2918872ab106d4c7e98) Change-Id: I7e4e3ed2515dd8c2ec765d8acbb97eba189d6aeb Reviewed-on: http://gerrit.openafs.org/8239 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 0506af9c058e22e3475f7e152c022571c0823253) --- src/afs/LINUX/osi_vcache.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c index cd61c65..dc3685b 100644 --- a/src/afs/LINUX/osi_vcache.c +++ b/src/afs/LINUX/osi_vcache.c @@ -20,9 +20,9 @@ osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { struct dentry *dentry; struct inode *inode = AFSTOV(avc); #if defined(D_ALIAS_IS_HLIST) - struct hlist_node *cur, *head; + struct hlist_node *cur, *head, *list_end; #else - struct list_head *cur, *head; + struct list_head *cur, *head, *list_end; #endif /* First, see if we can evict the inode from the dcache */ @@ -59,13 +59,15 @@ restart: spin_lock(&inode->i_lock); #if defined(D_ALIAS_IS_HLIST) head = inode->i_dentry.first; + list_end = NULL; #else head = &inode->i_dentry; + list_end = head; #endif restart: cur = head; - while ((cur = cur->next) != head) { + while ((cur = cur->next) != list_end) { #if defined(D_ALIAS_IS_HLIST) dentry = hlist_entry(cur, struct dentry, d_alias); #else -- 1.8.0