diff options
| author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-12-26 17:53:12 +0100 |
|---|---|---|
| committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-12-26 17:53:12 +0100 |
| commit | 4a4c8218eed10132c7e37a603575ee7d2a7e6a9f (patch) | |
| tree | b05adf77cfa165e736f9efcdd0f8afd868c3aae7 | |
| parent | 7ceff03db37d98e1dc634198fcee4206d8318499 (diff) | |
| download | plan9front-4a4c8218eed10132c7e37a603575ee7d2a7e6a9f.tar.xz | |
devsd: fix possible sdbio() race with inquiry data changing (due to ahci hotplug)
the unit inquiry data might change in case the drive got pulled
with ahci. so keep track if we locked the ctl in a local stack
variable instead of relying on that the inquiry data stays the
same.
| -rw-r--r-- | sys/src/9/port/devsd.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/src/9/port/devsd.c b/sys/src/9/port/devsd.c index b4cbd71f5..0d2a32319 100644 --- a/sys/src/9/port/devsd.c +++ b/sys/src/9/port/devsd.c @@ -770,7 +770,7 @@ sdclose(Chan* c) static long sdbio(Chan* c, int write, char* a, long len, uvlong off) { - int nchange, hard, allocd; + int nchange, hard, allocd, locked; long l; uchar *b; SDpart *pp; @@ -832,7 +832,8 @@ sdbio(Chan* c, int write, char* a, long len, uvlong off) poperror(); return 0; } - if(!(unit->inquiry[1] & 0x80)){ + locked = (unit->inquiry[1] & 0x80) != 0; + if(!locked){ qunlock(&unit->ctl); poperror(); } @@ -854,7 +855,7 @@ sdbio(Chan* c, int write, char* a, long len, uvlong off) if(waserror()){ if(allocd) sdfree(b); - if(!(unit->inquiry[1] & 0x80)) + if(!locked) decref(&sdev->r); /* gadverdamme! */ nexterror(); } @@ -896,7 +897,7 @@ sdbio(Chan* c, int write, char* a, long len, uvlong off) sdfree(b); poperror(); - if(unit->inquiry[1] & 0x80){ + if(locked){ qunlock(&unit->ctl); poperror(); } |
