Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Oct 2012 17:52:43 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r242322 - in head/sys: cam/scsi geom
Message-ID:  <201210291752.q9THqhBo012848@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Mon Oct 29 17:52:43 2012
New Revision: 242322
URL: http://svn.freebsd.org/changeset/base/242322

Log:
  Fix locking problem in disk_resize(); previously it would run without
  topology lock, resulting in assertion when running with DIAGNOSTIC.
  
  Reviewed by:	mav (earlier version)

Modified:
  head/sys/cam/scsi/scsi_da.c
  head/sys/geom/geom_disk.c
  head/sys/geom/geom_disk.h

Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c	Mon Oct 29 17:23:45 2012	(r242321)
+++ head/sys/cam/scsi/scsi_da.c	Mon Oct 29 17:52:43 2012	(r242322)
@@ -2673,6 +2673,7 @@ dasetgeom(struct cam_periph *periph, uin
 	struct da_softc *softc;
 	struct disk_params *dp;
 	u_int lbppbe, lalba;
+	int error;
 
 	softc = (struct da_softc *)periph->softc;
 
@@ -2779,10 +2780,9 @@ dasetgeom(struct cam_periph *periph, uin
 	else
 		softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
 
-/* Currently as of 6/13/2012, panics if DIAGNOSTIC is set */
-#ifndef	DIAGNOSTIC
-	disk_resize(softc->disk);
-#endif
+	error = disk_resize(softc->disk, M_NOWAIT);
+	if (error != 0)
+		xpt_print(periph->path, "disk_resize(9) failed, error = %d\n", error);
 }
 
 static void

Modified: head/sys/geom/geom_disk.c
==============================================================================
--- head/sys/geom/geom_disk.c	Mon Oct 29 17:23:45 2012	(r242321)
+++ head/sys/geom/geom_disk.c	Mon Oct 29 17:52:43 2012	(r242322)
@@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/sbuf.h>
 #include <sys/sysctl.h>
-#include <sys/taskqueue.h>
 #include <sys/devicestat.h>
 #include <machine/md_var.h>
 
@@ -66,7 +65,6 @@ struct g_disk_softc {
 	struct sysctl_oid	*sysctl_tree;
 	char			led[64];
 	uint32_t		state;
-	struct task		resize_task;
 };
 
 static struct mtx g_disk_done_mtx;
@@ -443,17 +441,22 @@ g_disk_dumpconf(struct sbuf *sb, const c
 }
 
 static void
-g_disk_resize_task(void *context, int pending)
+g_disk_resize(void *ptr, int flag)
 {
+	struct disk *dp;
 	struct g_geom *gp;
 	struct g_provider *pp;
-	struct disk *dp;
-	struct g_disk_softc *sc;
 
-	sc = (struct g_disk_softc *)context;
-	dp = sc->dp;
+	if (flag == EV_CANCEL)
+		return;
+	g_topology_assert();
+
+	dp = ptr;
 	gp = dp->d_geom;
 
+	if (dp->d_destroyed || gp == NULL)
+		return;
+
 	LIST_FOREACH(pp, &gp->provider, provider) {
 		if (pp->sectorsize != 0 &&
 		    pp->sectorsize != dp->d_sectorsize)
@@ -501,7 +504,6 @@ g_disk_create(void *arg, int flag)
 		    CTLFLAG_RW | CTLFLAG_TUN, sc->led, sizeof(sc->led),
 		    "LED name");
 	}
-	TASK_INIT(&sc->resize_task, 0, g_disk_resize_task, sc);
 	pp->private = sc;
 	dp->d_geom = gp;
 	g_error_provider(pp, 0);
@@ -684,22 +686,14 @@ disk_media_gone(struct disk *dp, int fla
 	}
 }
 
-void
-disk_resize(struct disk *dp)
+int
+disk_resize(struct disk *dp, int flag)
 {
-	struct g_geom *gp;
-	struct g_disk_softc *sc;
-	int error;
 
-	gp = dp->d_geom;
-
-	if (gp == NULL)
-		return;
-
-	sc = gp->softc;
+	if (dp->d_destroyed || dp->d_geom == NULL)
+		return (0);
 
-	error = taskqueue_enqueue(taskqueue_thread, &sc->resize_task);
-	KASSERT(error == 0, ("taskqueue_enqueue(9) failed."));
+	return (g_post_event(g_disk_resize, dp, flag, NULL));
 }
 
 static void

Modified: head/sys/geom/geom_disk.h
==============================================================================
--- head/sys/geom/geom_disk.h	Mon Oct 29 17:23:45 2012	(r242321)
+++ head/sys/geom/geom_disk.h	Mon Oct 29 17:52:43 2012	(r242322)
@@ -111,7 +111,7 @@ void disk_gone(struct disk *disk);
 void disk_attr_changed(struct disk *dp, const char *attr, int flag);
 void disk_media_changed(struct disk *dp, int flag);
 void disk_media_gone(struct disk *dp, int flag);
-void disk_resize(struct disk *dp);
+int disk_resize(struct disk *dp, int flag);
 
 #define DISK_VERSION_00		0x58561059
 #define DISK_VERSION_01		0x5856105a



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210291752.q9THqhBo012848>