Subject: | fix panic during shutdown after switching root volumes on linux client |
Date: | Tue, 6 Sep 2005 07:42:09 -0400 |
To: | openafs-bugs@openafs.org |
From: | chas williams - CONTRACTOR <chas@cmf.nrl.navy.mil> |
when afs switches from the r/w to the r/o /afs during installations
(this could happen at other times but its unlikely) the linux client
needs special help with the "/" dentry. "/" is always considered valid,
so we need to handle updating during the switch.
Index: src/afs/afs_daemons.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_daemons.c,v
retrieving revision 1.33
diff -u -u -r1.33 afs_daemons.c
--- src/afs/afs_daemons.c 3 Apr 2005 18:13:30 -0000 1.33
+++ src/afs/afs_daemons.c 6 Sep 2005 01:04:48 -0000
@@ -309,8 +309,55 @@
* count to zero and fs checkv is executed when the current
* directory is /afs.
*/
+
+#ifdef AFS_LINUX20_ENV
+ {
+ struct vrequest treq;
+ 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_InitReq(&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)
+ spin_lock(&dcache_lock);
+#if defined(AFS_LINUX26_ENV)
+ spin_lock(&dp->d_lock);
+#endif
+#endif
+ list_del_init(&dp->d_alias);
+ list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry));
+ dp->d_inode = AFSTOV(vcp);
+#if defined(AFS_LINUX24_ENV)
+#if defined(AFS_LINUX26_ENV)
+ spin_unlock(&dp->d_lock);
+#endif
+ spin_unlock(&dcache_lock);
+#endif
+
+ AFS_FAST_RELE(afs_globalVp);
+ afs_globalVp = vcp;
+out:
+ crfree(credp);
+ }
+#else
AFS_FAST_RELE(afs_globalVp);
afs_globalVp = 0;
+#endif
}
afs_rootFid.Fid.Volume = volid;
afs_rootFid.Fid.Vnode = 1;
(this could happen at other times but its unlikely) the linux client
needs special help with the "/" dentry. "/" is always considered valid,
so we need to handle updating during the switch.
Index: src/afs/afs_daemons.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_daemons.c,v
retrieving revision 1.33
diff -u -u -r1.33 afs_daemons.c
--- src/afs/afs_daemons.c 3 Apr 2005 18:13:30 -0000 1.33
+++ src/afs/afs_daemons.c 6 Sep 2005 01:04:48 -0000
@@ -309,8 +309,55 @@
* count to zero and fs checkv is executed when the current
* directory is /afs.
*/
+
+#ifdef AFS_LINUX20_ENV
+ {
+ struct vrequest treq;
+ 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_InitReq(&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)
+ spin_lock(&dcache_lock);
+#if defined(AFS_LINUX26_ENV)
+ spin_lock(&dp->d_lock);
+#endif
+#endif
+ list_del_init(&dp->d_alias);
+ list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry));
+ dp->d_inode = AFSTOV(vcp);
+#if defined(AFS_LINUX24_ENV)
+#if defined(AFS_LINUX26_ENV)
+ spin_unlock(&dp->d_lock);
+#endif
+ spin_unlock(&dcache_lock);
+#endif
+
+ AFS_FAST_RELE(afs_globalVp);
+ afs_globalVp = vcp;
+out:
+ crfree(credp);
+ }
+#else
AFS_FAST_RELE(afs_globalVp);
afs_globalVp = 0;
+#endif
}
afs_rootFid.Fid.Volume = volid;
afs_rootFid.Fid.Vnode = 1;