diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-10-16 12:26:56 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-10-16 12:26:56 +0200 |
commit | 965bb2d2480363bf02ad0c10f92b7a6b4962e38f (patch) | |
tree | 6b208c761f464ca6b5bb24aab9f6e7620e7d2337 | |
parent | 1cd4579cdc9bbfc9001ed15af6bf01e331e07493 (diff) | |
download | plan9front-965bb2d2480363bf02ad0c10f92b7a6b4962e38f.tar.xz |
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.
-rw-r--r-- | sys/src/cmd/nusb/disk/disk.c | 26 | ||||
-rw-r--r-- | sys/src/cmd/nusb/disk/ums.h | 2 |
2 files changed, 26 insertions, 2 deletions
diff --git a/sys/src/cmd/nusb/disk/disk.c b/sys/src/cmd/nusb/disk/disk.c index b9bbe6cf6..0b964f052 100644 --- a/sys/src/cmd/nusb/disk/disk.c +++ b/sys/src/cmd/nusb/disk/disk.c @@ -619,7 +619,11 @@ dopen(Req *req) 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 @@ dread(Req *req) long count; void *data; vlong offset; + Srv *srv; q = req->fid->qid; if(q.path == 0){ @@ -701,13 +706,19 @@ dread(Req *req) 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 @@ dread(Req *req) respond(req, nil); break; } + + qunlock(lun); + srvacquire(srv); } static void @@ -786,6 +800,7 @@ dwrite(Req *req) 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 @@ dwrite(Req *req) 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 @@ dwrite(Req *req) respond(req, nil); break; } + + qunlock(lun); + srvacquire(srv); } int diff --git a/sys/src/cmd/nusb/disk/ums.h b/sys/src/cmd/nusb/disk/ums.h index f8dbfa4fc..95f1929a3 100644 --- a/sys/src/cmd/nusb/disk/ums.h +++ b/sys/src/cmd/nusb/disk/ums.h @@ -76,6 +76,8 @@ struct Umsc long off; /* offset within a block */ long nb; /* byte count */ + QLock; + /* partitions */ Part part[Maxparts]; |