Print this page
XXXX don't fail device detach when it's physically removed
@@ -16,15 +16,20 @@
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
+ * Copyright 2018 Nexenta Systems, Inc.
+ */
+
+/*
* miscellaneous routines for the devfs
*/
#include <sys/types.h>
#include <sys/param.h>
@@ -401,17 +406,14 @@
vp->v_type = dmd->ddm_spec_type == S_IFCHR ? VCHR : VBLK;
vp->v_rdev = dmd->ddm_dev;
vn_setops(vp, vn_getops(DVTOV(ddv)));
vn_exists(vp);
- /* increment dev_ref with devi_lock held */
ASSERT(DEVI_BUSY_OWNED(devi));
- mutex_enter(&DEVI(devi)->devi_lock);
- dv->dv_devi = devi;
- DEVI(devi)->devi_ref++; /* ndi_hold_devi(dip) */
- mutex_exit(&DEVI(devi)->devi_lock);
+ ndi_hold_devi(devi);
+ dv->dv_devi = devi;
dv->dv_ino = dv_mkino(devi, vp->v_type, vp->v_rdev);
dv->dv_nlink = 0; /* updated on insert */
dv->dv_dotdot = ddv;
dv->dv_attrvp = NULLVP;
dv->dv_attr = NULL;
@@ -1443,14 +1445,30 @@
} else {
ASSERT((vp->v_type == VCHR) || (vp->v_type == VBLK));
ASSERT(dv->dv_nlink == 1); /* no hard links */
mutex_enter(&vp->v_lock);
if (vp->v_count > 0) {
+ /*
+ * The file still has references to it. If
+ * DV_DEVI_GONE is *not* specified then a
+ * referenced file is considered busy.
+ */
+ if (!(flags & DV_DEVI_GONE)) {
mutex_exit(&vp->v_lock);
goto set_busy;
}
+
+ /*
+ * Mark referenced file stale so that DR will
+ * succeed even if there are userland opens.
+ */
+ ASSERT(!DV_STALE(dv));
+ ndi_rele_devi(dv->dv_devi);
+ DEVI(dv->dv_devi)->devi_gone = 1;
+ dv->dv_devi = NULL;
}
+ }
/* unlink from directory */
dv_unlink(ddv, dv);
/* drop locks */