From: Matthew Dillon Date: Fri, 5 Sep 2008 23:27:12 +0000 (+0000) Subject: Fix an endless recursion and double fault which could occur when accessing X-Git-Tag: v2.1.1~488 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/3ea4f8fe707f9f90013c5890c267343c6b382d59?ds=sidebyside Fix an endless recursion and double fault which could occur when accessing a filesystem mounted via nullfs where the mount itself used a path through another nullfs filesystem. The forwarding nullm_vfs mount pointer must be set to the actual mount point and not the governing nullfs. Any read-only status from the governing nullfs mount will still be inherited. --- diff --git a/sys/vfs/nullfs/null_vfsops.c b/sys/vfs/nullfs/null_vfsops.c index 7e646ed4cc..093ebe33a5 100644 --- a/sys/vfs/nullfs/null_vfsops.c +++ b/sys/vfs/nullfs/null_vfsops.c @@ -37,7 +37,7 @@ * * @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92 * $FreeBSD: src/sys/miscfs/nullfs/null_vfsops.c,v 1.35.2.3 2001/07/26 20:37:11 iedowse Exp $ - * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.29 2006/10/27 04:56:34 dillon Exp $ + * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.30 2008/09/05 23:27:12 dillon Exp $ */ /* @@ -121,8 +121,26 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) * want to set it on the base directory being mounted to prevent * that directory from being destroyed out from under the nullfs * mount. + * + * The forwarding mount pointer (xmp->nullm_vfs) must be set to + * the actual target filesystem. If the target filesystem was + * resolved via a nullfs mount nd.nl_nch.mount will be pointing + * to the nullfs mount structure instead of the target filesystem, + * which would otherwise cause the mount VOPS and VFSOPS to recurse + * endlessly. If we are mounting via a nullfs mount we inherit + * its read-only state, if set. */ xmp->nullm_vfs = nd.nl_nch.mount; + if (xmp->nullm_vfs != rootvp->v_mount) { + if (xmp->nullm_vfs->mnt_flag & MNT_RDONLY) + mp->mnt_flag |= MNT_RDONLY; + xmp->nullm_vfs = rootvp->v_mount; + } + + /* + * ncmountpt is the parent glue. When mounting a nullfs via a nullfs + * we retain the parent nullfs to create a unique chain tuple. + */ mp->mnt_ncmountpt = nd.nl_nch; cache_changemount(&mp->mnt_ncmountpt, mp); mp->mnt_ncmountpt.ncp->nc_flag |= NCF_ISMOUNTPT; diff --git a/sys/vfs/nullfs/null_vnops.c b/sys/vfs/nullfs/null_vnops.c index f46b3deeca..ac320e6a30 100644 --- a/sys/vfs/nullfs/null_vnops.c +++ b/sys/vfs/nullfs/null_vnops.c @@ -38,7 +38,7 @@ * Ancestors: * @(#)lofs_vnops.c 1.2 (Berkeley) 6/18/92 * $FreeBSD: src/sys/miscfs/nullfs/null_vnops.c,v 1.38.2.6 2002/07/31 00:32:28 semenu Exp $ - * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.28 2006/10/27 04:56:34 dillon Exp $ + * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.29 2008/09/05 23:27:12 dillon Exp $ * ...and... * @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project * @@ -88,7 +88,7 @@ * passed on operation to their underlying peer. * * However, with the current implementation nullfs doesn't have any private - * vnodes, it rather relies on DragonFly's namecache API. That gives a much + * vnodes, rather it relies on DragonFly's namecache API. That gives a much * more lightweight null layer, as namecache structures are pure data, with * no private operations, so there is no need of subtle dispatching routines. *