shithub: riscv

Download patch

ref: 965bb2d2480363bf02ad0c10f92b7a6b4962e38f
parent: 1cd4579cdc9bbfc9001ed15af6bf01e331e07493
author: cinap_lenrek <[email protected]>
date: Wed Oct 16 08:26:56 EDT 2013

nusb/disk: handle blocking usb access with srv released

usb is bound after /dev, so a hanging usb device will hang
access to /dev. we avoid this by releasing the srv, which
allows the fs to still handle reads and walks of the
directories.

ios are serialized by a qlock in the Umsc structure.

--- a/sys/src/cmd/nusb/disk/disk.c
+++ b/sys/src/cmd/nusb/disk/disk.c
@@ -619,7 +619,11 @@
 	lun = ums->lun + (req->ofcall.qid.path >> 16) - 1;
 	switch(path){
 	case Qraw:
+		srvrelease(req->srv);
+		qlock(lun);
 		lun->phase = Pcmd;
+		qunlock(lun);
+		srvacquire(req->srv);
 		break;
 	}
 	respond(req, nil);
@@ -684,6 +688,7 @@
 	long count;
 	void *data;
 	vlong offset;
+	Srv *srv;
 
 	q = req->fid->qid;
 	if(q.path == 0){
@@ -701,13 +706,19 @@
 	case Qdir:
 		dirread9p(req, dirgen, lun);
 		respond(req, nil);
-		break;
+		return;
 	case Qctl:
 		s = ctlstring(lun);
 		readstr(req, s);
 		free(s);
 		respond(req, nil);
-		break;
+		return;
+	}
+
+	srv = req->srv;
+	srvrelease(srv);
+	qlock(lun);
+	switch(path){
 	case Qraw:
 		if(lun->lbsize <= 0 && umscapacity(lun) < 0){
 			respond(req, "phase error");
@@ -772,6 +783,9 @@
 		respond(req, nil);
 		break;
 	}
+
+	qunlock(lun);
+	srvacquire(srv);
 }
 
 static void
@@ -786,6 +800,7 @@
 	long count;
 	void *data;
 	vlong offset;
+	Srv *srv;
 
 	lun = ums->lun + (req->fid->qid.path >> 16) - 1;
 	path = req->fid->qid.path & 0xFFFF;
@@ -793,6 +808,10 @@
 	data = req->ifcall.data;
 	offset = req->ifcall.offset;
 
+	srv = req->srv;
+	srvrelease(srv);
+	qlock(lun);
+
 	switch(path){
 	case Qctl:
 		s = emallocz(count+1, 1);
@@ -896,6 +915,9 @@
 		respond(req, nil);
 		break;
 	}
+
+	qunlock(lun);
+	srvacquire(srv);
 }
 
 int
--- a/sys/src/cmd/nusb/disk/ums.h
+++ b/sys/src/cmd/nusb/disk/ums.h
@@ -76,6 +76,8 @@
 	long	off;		/* offset within a block */
 	long	nb;		/* byte count */
 
+	QLock;
+
 	/* partitions */
 	Part part[Maxparts];