From 82ed5e94ee42037d9b8b97e5608fe7c2875a2282 Mon Sep 17 00:00:00 2001 From: tjr Date: Thu, 6 Mar 2003 10:48:03 +0000 Subject: Add a temporary workaround for a deadlock in Coda venus 5.3.19 that occurs when mounting the filesystem. The problem is that venus issues the mount() syscall, which calls vfs_mount(), which calls coda_root() which attempts to communicate with venus. --- sys/coda/cnode.h | 1 + sys/coda/coda_vfsops.c | 29 +++++++++++++++++++++++++++-- sys/fs/coda/cnode.h | 1 + sys/fs/coda/coda_vfsops.c | 29 +++++++++++++++++++++++++++-- 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/sys/coda/cnode.h b/sys/coda/cnode.h index 962d329..450adc3 100644 --- a/sys/coda/cnode.h +++ b/sys/coda/cnode.h @@ -154,6 +154,7 @@ struct coda_mntinfo { struct mount *mi_vfsp; struct vcomm mi_vcomm; dev_t dev; + int mi_started; }; extern struct coda_mntinfo coda_mnttbl[]; /* indexed by minor device number */ diff --git a/sys/coda/coda_vfsops.c b/sys/coda/coda_vfsops.c index 5040e68..54ca8bd 100644 --- a/sys/coda/coda_vfsops.c +++ b/sys/coda/coda_vfsops.c @@ -181,6 +181,7 @@ coda_mount(vfsp, path, data, ndp, td) vfs_getnewfsid (vfsp); mi->mi_vfsp = vfsp; + mi->mi_started = 0; /* XXX See coda_root() */ /* * Make a root vnode to placate the Vnode interface, but don't @@ -301,9 +302,21 @@ coda_root(vfsp, vpp) result = NULL; if (vfsp == mi->mi_vfsp) { + /* + * Cache the root across calls. We only need to pass the request + * on to Venus if the root vnode is the dummy we installed in + * coda_mount() with all c_fid members zeroed. + * + * XXX In addition, if we are called between coda_mount() and + * coda_start(), we assume that the request is from vfs_mount() + * (before the call to checkdirs()) and return the dummy root + * node to avoid a deadlock. This bug is fixed in the Coda CVS + * repository but not in any released versions as of 6 Mar 2003. + */ if ((VTOC(mi->mi_rootvp)->c_fid.Volume != 0) || (VTOC(mi->mi_rootvp)->c_fid.Vnode != 0) || - (VTOC(mi->mi_rootvp)->c_fid.Unique != 0)) + (VTOC(mi->mi_rootvp)->c_fid.Unique != 0) || + mi->mi_started == 0) { /* Found valid root. */ *vpp = mi->mi_rootvp; /* On Mach, this is vref. On NetBSD, VOP_LOCK */ @@ -371,6 +384,18 @@ coda_root(vfsp, vpp) return(error); } +int +coda_start(mp, flags, td) + struct mount *mp; + int flags; + struct thread *td; +{ + + /* XXX See coda_root(). */ + vftomi(mp)->mi_started = 1; + return (0); +} + /* * Get filesystem statistics. */ @@ -526,7 +551,7 @@ struct mount *devtomp(dev) struct vfsops coda_vfsops = { coda_mount, - vfs_stdstart, + coda_start, coda_unmount, coda_root, vfs_stdquotactl, diff --git a/sys/fs/coda/cnode.h b/sys/fs/coda/cnode.h index 962d329..450adc3 100644 --- a/sys/fs/coda/cnode.h +++ b/sys/fs/coda/cnode.h @@ -154,6 +154,7 @@ struct coda_mntinfo { struct mount *mi_vfsp; struct vcomm mi_vcomm; dev_t dev; + int mi_started; }; extern struct coda_mntinfo coda_mnttbl[]; /* indexed by minor device number */ diff --git a/sys/fs/coda/coda_vfsops.c b/sys/fs/coda/coda_vfsops.c index 5040e68..54ca8bd 100644 --- a/sys/fs/coda/coda_vfsops.c +++ b/sys/fs/coda/coda_vfsops.c @@ -181,6 +181,7 @@ coda_mount(vfsp, path, data, ndp, td) vfs_getnewfsid (vfsp); mi->mi_vfsp = vfsp; + mi->mi_started = 0; /* XXX See coda_root() */ /* * Make a root vnode to placate the Vnode interface, but don't @@ -301,9 +302,21 @@ coda_root(vfsp, vpp) result = NULL; if (vfsp == mi->mi_vfsp) { + /* + * Cache the root across calls. We only need to pass the request + * on to Venus if the root vnode is the dummy we installed in + * coda_mount() with all c_fid members zeroed. + * + * XXX In addition, if we are called between coda_mount() and + * coda_start(), we assume that the request is from vfs_mount() + * (before the call to checkdirs()) and return the dummy root + * node to avoid a deadlock. This bug is fixed in the Coda CVS + * repository but not in any released versions as of 6 Mar 2003. + */ if ((VTOC(mi->mi_rootvp)->c_fid.Volume != 0) || (VTOC(mi->mi_rootvp)->c_fid.Vnode != 0) || - (VTOC(mi->mi_rootvp)->c_fid.Unique != 0)) + (VTOC(mi->mi_rootvp)->c_fid.Unique != 0) || + mi->mi_started == 0) { /* Found valid root. */ *vpp = mi->mi_rootvp; /* On Mach, this is vref. On NetBSD, VOP_LOCK */ @@ -371,6 +384,18 @@ coda_root(vfsp, vpp) return(error); } +int +coda_start(mp, flags, td) + struct mount *mp; + int flags; + struct thread *td; +{ + + /* XXX See coda_root(). */ + vftomi(mp)->mi_started = 1; + return (0); +} + /* * Get filesystem statistics. */ @@ -526,7 +551,7 @@ struct mount *devtomp(dev) struct vfsops coda_vfsops = { coda_mount, - vfs_stdstart, + coda_start, coda_unmount, coda_root, vfs_stdquotactl, -- cgit v1.1