Module Name: src Committed By: hannken Date: Thu Jul 18 09:39:40 UTC 2019
Modified Files: src/sys/kern: vfs_lookup.c Log Message: Make namei() work with no root dir yet. >From David Holland with minor tweaks from me. Should fix PR kern/54378 (panic with TLB miss when attempting to reboot) To generate a diff of this commit: cvs rdiff -u -r1.211 -r1.212 src/sys/kern/vfs_lookup.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_lookup.c diff -u src/sys/kern/vfs_lookup.c:1.211 src/sys/kern/vfs_lookup.c:1.212 --- src/sys/kern/vfs_lookup.c:1.211 Sat Jul 6 14:27:38 2019 +++ src/sys/kern/vfs_lookup.c Thu Jul 18 09:39:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_lookup.c,v 1.211 2019/07/06 14:27:38 maxv Exp $ */ +/* $NetBSD: vfs_lookup.c,v 1.212 2019/07/18 09:39:40 hannken Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.211 2019/07/06 14:27:38 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.212 2019/07/18 09:39:40 hannken Exp $"); #ifdef _KERNEL_OPT #include "opt_magiclinks.h" @@ -515,7 +515,8 @@ namei_cleanup(struct namei_state *state) KASSERT(state->cnp == &state->ndp->ni_cnd); if (state->root_referenced) { - vrele(state->ndp->ni_rootdir); + if (state->ndp->ni_rootdir != NULL) + vrele(state->ndp->ni_rootdir); if (state->ndp->ni_erootdir != NULL) vrele(state->ndp->ni_erootdir); } @@ -538,7 +539,8 @@ namei_getstartdir(struct namei_state *st struct vnode *rootdir, *erootdir, *curdir, *startdir; if (state->root_referenced) { - vrele(state->ndp->ni_rootdir); + if (state->ndp->ni_rootdir != NULL) + vrele(state->ndp->ni_rootdir); if (state->ndp->ni_erootdir != NULL) vrele(state->ndp->ni_erootdir); state->root_referenced = 0; @@ -595,8 +597,10 @@ namei_getstartdir(struct namei_state *st * Must hold references to rootdir and erootdir while we're running. * A multithreaded process may chroot during namei. */ - vref(startdir); - vref(state->ndp->ni_rootdir); + if (startdir != NULL) + vref(startdir); + if (state->ndp->ni_rootdir != NULL) + vref(state->ndp->ni_rootdir); if (state->ndp->ni_erootdir != NULL) vref(state->ndp->ni_erootdir); state->root_referenced = 1; @@ -616,6 +620,9 @@ namei_getstartdir_for_nfsd(struct namei_ KASSERT(state->ndp->ni_atdir != NULL); /* always use the real root, and never set an emulation root */ + if (rootvnode == NULL) { + return NULL; + } state->ndp->ni_rootdir = rootvnode; state->ndp->ni_erootdir = NULL; @@ -693,6 +700,10 @@ namei_start(struct namei_state *state, i namei_ktrace(state); } + if (startdir == NULL) { + return ENOENT; + } + /* NDAT may feed us with a non directory namei_getstartdir */ if (startdir->v_type != VDIR) { vrele(startdir);