+
+ if (startdir_with_usecount) {
+ vnode_rele_ext(startdir_with_usecount, O_EVTONLY, 0);
+ startdir_with_usecount = NULLVP;
+ }
+ if (rootdir_with_usecount) {
+ vnode_rele_ext(rootdir_with_usecount, O_EVTONLY, 0);
+ rootdir_with_usecount = NULLVP;
+ }
+
+#if CONFIG_VOLFS
+ /*
+ * Deal with volfs fallout.
+ *
+ * At this point, if we were originally given a volfs path that
+ * looks like /.vol/123/456, then we would have had to convert it into
+ * a full path. Assuming that part worked properly, we will now attempt
+ * to conduct a lookup of the item in the namespace. Under normal
+ * circumstances, if a user looked up /tmp/foo and it was not there, it
+ * would be permissible to return ENOENT.
+ *
+ * However, we may not want to do that here. Specifically, the volfs path
+ * uniquely identifies a certain item in the namespace regardless of where it
+ * lives. If the item has moved in between the time we constructed the
+ * path and now, when we're trying to do a lookup/authorization on the full
+ * path, we may have gotten an ENOENT.
+ *
+ * At this point we can no longer tell if the path no longer exists
+ * or if the item in question no longer exists. It could have been renamed
+ * away, in which case the /.vol identifier is still valid.
+ *
+ * Do this dance a maximum of MAX_VOLFS_RESTARTS times.
+ */
+ if ((error == ENOENT) && (ndp->ni_cnd.cn_flags & CN_VOLFSPATH)) {
+ if (volfs_restarts < MAX_VOLFS_RESTARTS) {
+ volfs_restarts++;
+ goto vnode_recycled;
+ }
+ }
+#endif
+
+ if (error == ERECYCLE) {
+ /* vnode was recycled underneath us. re-drive lookup to start at
+ * the beginning again, since recycling invalidated last lookup*/