From 2c9bc3ec349ae550bf60d0c46f15bdabe2b0fd9e Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Thu, 18 Dec 2014 06:57:22 -0500 Subject: [PATCH 1/2] Linux: Move code to reset the root to afs/LINUX Move the Linux specific bit of code to reset the root to afs/LINUX platform specific files. Things that play with the Linux vfs internals should not be exposed here. No functional change, but this helps cleanup some ifdef mess. Change-Id: Ia27fca3d8052ead45783cb2332c04fe6e99e5d9f --- src/afs/LINUX/osi_prototypes.h | 3 ++ src/afs/LINUX/osi_vcache.c | 61 ++++++++++++++++++++++++++++++++++++ src/afs/LINUX24/osi_prototypes.h | 3 ++ src/afs/LINUX24/osi_vcache.c | 36 +++++++++++++++++++++ src/afs/afs_daemons.c | 67 +++------------------------------------- 5 files changed, 108 insertions(+), 62 deletions(-) diff --git a/src/afs/LINUX/osi_prototypes.h b/src/afs/LINUX/osi_prototypes.h index 277b50a..5002af1 100644 --- a/src/afs/LINUX/osi_prototypes.h +++ b/src/afs/LINUX/osi_prototypes.h @@ -82,6 +82,9 @@ extern void osi_VM_FlushPages(struct vcache *avc, afs_ucred_t *credp); extern void osi_VM_Truncate(struct vcache *avc, int alen, afs_ucred_t *acred); +/* osi_vcache.c */ +extern void osi_ResetRootVCache(afs_uint32 volid); + /* osi_vfsops.c */ extern void vattr2inode(struct inode *ip, struct vattr *vp); extern int afs_init_inodecache(void); diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c index 1d0db82..391e7d4 100644 --- a/src/afs/LINUX/osi_vcache.c +++ b/src/afs/LINUX/osi_vcache.c @@ -143,3 +143,64 @@ osi_PostPopulateVCache(struct vcache *avc) { vSetType(avc, VREG); } +/** + * osi_ResetRootVCache - Reset the root vcache + * Reset the dentry associated with the afs root. + * Called from afs_CheckRootVolume when we notice that + * the root volume ID has changed. + * + * @volid: volume ID for the afs root + */ +void +osi_ResetRootVCache(afs_uint32 volid) +{ + struct vrequest *treq = NULL; + struct vattr vattr; + cred_t *credp; + struct dentry *dp; + struct vcache *vcp; + struct inode *root = AFSTOV(afs_globalVp); + + afs_rootFid.Fid.Volume = volid; + afs_rootFid.Fid.Vnode = 1; + afs_rootFid.Fid.Unique = 1; + + credp = crref(); + if (afs_CreateReq(&treq, credp)) + goto out; + vcp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL); + if (!vcp) + goto out; + afs_getattr(vcp, &vattr, credp); + afs_fill_inode(AFSTOV(vcp), &vattr); + + dp = d_find_alias(root); + +#if defined(HAVE_DCACHE_LOCK) + spin_lock(&dcache_lock); +#else + spin_lock(&AFSTOV(vcp)->i_lock); +#endif + spin_lock(&dp->d_lock); +#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); + spin_unlock(&dp->d_lock); +#if defined(HAVE_DCACHE_LOCK) + spin_unlock(&dcache_lock); +#else + spin_unlock(&AFSTOV(vcp)->i_lock); +#endif + dput(dp); + + AFS_RELE(root); + afs_globalVp = vcp; +out: + crfree(credp); + afs_DestroyReq(treq); +} diff --git a/src/afs/LINUX24/osi_prototypes.h b/src/afs/LINUX24/osi_prototypes.h index cb4bee1..cd748f1 100644 --- a/src/afs/LINUX24/osi_prototypes.h +++ b/src/afs/LINUX24/osi_prototypes.h @@ -69,6 +69,9 @@ extern void osi_syscall_clean(void); extern int osi_sysctl_init(void); extern void osi_sysctl_clean(void); +/* osi_vcache.c */ +extern void osi_ResetRootVCache(afs_uint32 volid); + /* osi_vm.c */ extern int osi_VM_FlushVCache(struct vcache *avc); extern void osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, diff --git a/src/afs/LINUX24/osi_vcache.c b/src/afs/LINUX24/osi_vcache.c index bbaf5ce..853a357 100644 --- a/src/afs/LINUX24/osi_vcache.c +++ b/src/afs/LINUX24/osi_vcache.c @@ -119,3 +119,39 @@ osi_PostPopulateVCache(struct vcache *avc) { vSetType(avc, VREG); } +void +osi_ResetRootVCache(afs_uint32 volid) +{ + struct vrequest *treq = NULL; + struct vattr vattr; + cred_t *credp; + struct dentry *dp; + struct vcache *vcp; + + afs_rootFid.Fid.Volume = volid; + afs_rootFid.Fid.Vnode = 1; + afs_rootFid.Fid.Unique = 1; + + credp = crref(); + if (afs_CreateReq(&treq, credp)) + goto out; + vcp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL); + if (!vcp) + goto out; + afs_getattr(vcp, &vattr, credp); + afs_fill_inode(AFSTOV(vcp), &vattr); + + dp = d_find_alias(AFSTOV(afs_globalVp)); + spin_lock(&dcache_lock); + list_del_init(&dp->d_alias); + list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); + dp->d_inode = AFSTOV(vcp); + spin_unlock(&dcache_lock); + dput(dp); + + AFS_FAST_RELE(afs_globalVp); + afs_globalVp = vcp; +out: + crfree(credp); + afs_DestroyReq(treq); +} diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index a78aaaa..dd943a7 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -351,71 +351,14 @@ afs_CheckRootVolume(void) * count to zero and fs checkv is executed when the current * directory is /afs. */ -#ifdef AFS_LINUX20_ENV - { - struct vrequest *treq = NULL; - struct vattr vattr; - cred_t *credp; - struct dentry *dp; - struct vcache *vcp; - - afs_rootFid.Fid.Volume = volid; - afs_rootFid.Fid.Vnode = 1; - afs_rootFid.Fid.Unique = 1; - - credp = crref(); - if (afs_CreateReq(&treq, credp)) - goto out; - vcp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL); - if (!vcp) - goto out; - afs_getattr(vcp, &vattr, credp); - afs_fill_inode(AFSTOV(vcp), &vattr); - - dp = d_find_alias(AFSTOV(afs_globalVp)); - -#if defined(AFS_LINUX24_ENV) -#if defined(HAVE_DCACHE_LOCK) - spin_lock(&dcache_lock); -#else - spin_lock(&AFSTOV(vcp)->i_lock); -#endif -#if defined(AFS_LINUX26_ENV) - 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) - spin_unlock(&dp->d_lock); -#endif -#if defined(HAVE_DCACHE_LOCK) - spin_unlock(&dcache_lock); -#else - spin_unlock(&AFSTOV(vcp)->i_lock); -#endif -#endif - dput(dp); - - AFS_FAST_RELE(afs_globalVp); - afs_globalVp = vcp; - out: - crfree(credp); - afs_DestroyReq(treq); - } +#ifdef AFS_LINUX22_ENV + osi_ResetRootVCache(volid); #else -#ifdef AFS_DARWIN80_ENV +# ifdef AFS_DARWIN80_ENV afs_PutVCache(afs_globalVp); -#else +# else AFS_FAST_RELE(afs_globalVp); -#endif +# endif afs_globalVp = 0; #endif } -- 2.2.1 From 4ba5cbd90e96edd63bd0178df8ce615c1efe1b2c Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Thu, 18 Dec 2014 07:13:46 -0500 Subject: [PATCH 2/2] Linux: d_alias becomes d_u.d_alias The fields in struct dentry are re-arranged so that d_alias shares space wth d_rcu inside the d_u union. Some references need to change from d_alias to d_u.d_alias. The kernel change was introduced for 3.19 but was also backported to the 3.18 stable series in 3.18.1, so this commit is required for 3.19 and current 3.18 kernels. Change-Id: I711a5a3a89af6e0055381dfd4474ddca2868bb9c --- acinclude.m4 | 1 + src/afs/LINUX/osi_compat.h | 4 ++++ src/cf/linux-test4.m4 | 9 ++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 96adde0..e8e238b 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -899,6 +899,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) [backing-dev.h]) AC_CHECK_LINUX_STRUCT([cred], [session_keyring], [cred.h]) AC_CHECK_LINUX_STRUCT([ctl_table], [ctl_name], [sysctl.h]) + AC_CHECK_LINUX_STRUCT([dentry], [d_u.d_alias], [dcache.h]) AC_CHECK_LINUX_STRUCT([dentry_operations], [d_automount], [dcache.h]) AC_CHECK_LINUX_STRUCT([inode], [i_alloc_sem], [fs.h]) AC_CHECK_LINUX_STRUCT([inode], [i_blkbits], [fs.h]) diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index 57f6ea7..497b1ef 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -37,6 +37,10 @@ typedef struct vfs_path afs_linux_path_t; typedef struct path afs_linux_path_t; #endif +#if defined(STRUCT_DENTRY_HAS_D_U_D_ALIAS) +# define d_alias d_u.d_alias +#endif + #ifndef HAVE_LINUX_DO_SYNC_READ static inline int do_sync_read(struct file *fp, char *buf, size_t count, loff_t *offp) { diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index f0269b3..9dd55b3 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -713,7 +713,11 @@ AC_DEFUN([LINUX_D_ALIAS_IS_HLIST], [ [#include ], [struct dentry *d = NULL; struct hlist_node *hn = NULL; - d->d_alias = *hn;], + #if defined(STRUCT_DENTRY_HAS_D_U_D_ALIAS) + d->d_u.d_alias = *hn; + #else + d->d_alias = *hn; + #endif], [D_ALIAS_IS_HLIST], [define if dentry->d_alias is an hlist], []) @@ -727,6 +731,9 @@ AC_DEFUN([LINUX_HLIST_ITERATOR_NO_NODE], [ #include ], [struct dentry *d = NULL, *cur; struct inode *ip; + #if defined(STRUCT_DENTRY_HAS_D_U_D_ALIAS) + # define d_alias d_u.d_alias + #endif hlist_for_each_entry(cur, &ip->i_dentry, d_alias) { } ], [HLIST_ITERATOR_NO_NODE], -- 2.2.1