Fix missing poperror() calls
authorFergus Simpson <afergs@google.com>
Thu, 8 Dec 2016 19:41:08 +0000 (11:41 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 10 Dec 2016 01:02:15 +0000 (20:02 -0500)
The AHCI driver was ported from plan 9 which did not have poperror. As a
result of the port poperror needed to be added, but there were some
mistakes. After a waserror every path out of a function must call
poperror or nexterror. This didn't always happen previously, so this
commit adds or moves poperror calls to make sure that a function's
ERRSTACK always gets cleared before returning.

Additionally, ERRSTACK must be deep enough for the number of waserror
calls in a function not separeted by poperror or nexterror. It was deeper
than it needed to be in a number of places so that was also fixed.

Change-Id: I4bbe5fd066ff890dc817e7d0e313ca6e07fe99bb
Signed-off-by: Fergus Simpson <afergs@google.com>
[checkpatch nit]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/drivers/dev/sd.c
kern/drivers/dev/sdiahci.c

index cc1960d..84a1092 100644 (file)
@@ -255,10 +255,9 @@ static int sdinitpart(struct sdunit *unit)
 
                        start = strtoull(f[1], 0, 0);
                        end = strtoull(f[2], 0, 0);
-                       if(!waserror()){
+                       if (!waserror())
                                sdaddpart(unit, f[0], start, end);
-                               poperror();
-                       }
+                       poperror();
                }
 #endif
        }
@@ -793,6 +792,7 @@ static int32_t sdbio(struct chan *c, int write, char *a, int32_t len,
                 * if (strcmp(up->errstr, Eio) == 0 ... */
                if ((get_errno() == EIO) && (unit->sectors == 0) && (nchange++ == 0)) {
                        sdinitpart(unit);
+                       poperror();
                        continue;
                }
 
@@ -894,7 +894,7 @@ static int32_t sdbio(struct chan *c, int write, char *a, int32_t len,
 
 static int32_t sdrio(struct sdreq *r, void *a, int32_t n)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        void *data;
 
        if (n >= SDmaxio || n < 0)
@@ -1120,7 +1120,7 @@ int sdfakescsi(struct sdreq *r, void *info, int ilen)
 
 static long sdread(struct chan *c, void *a, long n, int64_t off)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        char *p, *e, *buf;
        struct sdpart *pp;
        struct sdunit *unit;
index 367f6d8..746d210 100644 (file)
@@ -365,9 +365,12 @@ static void dreg(char *s, void *p)
 
 static void esleep(int ms)
 {
-       ERRSTACK(2);
-       if (waserror())
+       ERRSTACK(1);
+
+       if (waserror()) {
+               poperror();
                return;
+       }
        kthread_usleep(ms * 1000);
        poperror();
 }
@@ -382,9 +385,12 @@ static int ahciclear(void *v)
 
 static void aesleep(struct aportm *pm, struct Asleep *a, int ms)
 {
-       ERRSTACK(2);
-       if (waserror())
+       ERRSTACK(1);
+
+       if (waserror()) {
+               poperror();
                return;
+       }
        rendez_sleep_timeout(&pm->Rendez, ahciclear, a, ms * 1000);
        poperror();
 }
@@ -1871,7 +1877,7 @@ retry:
        d->active++;
 
        while (waserror())
-               ;
+               poperror();
        /* don't sleep here forever */
        rendez_sleep_timeout(&d->portm.Rendez, ahciclear, &as, (3 * 1000) * 1000);
        poperror();
@@ -1941,7 +1947,7 @@ retry:
 
 static int iario(struct sdreq *r)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        int i, n, count, try, max, flag, task;
        uint64_t lba;
        char *name;
@@ -2017,7 +2023,7 @@ retry:
                d->active++;
 
                while (waserror())
-                       ;
+                       poperror();
                /* don't sleep here forever */
                rendez_sleep_timeout(&d->portm.Rendez, ahciclear, &as,
                                     (3 * 1000) * 1000);
@@ -2351,7 +2357,8 @@ static void forcemode(struct drive *d, char *mode)
 
 static void runsmartable(struct drive *d, int i)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
+
        if (waserror()) {
                qunlock(&d->portm.ql);
                d->smartrs = 0;
@@ -2396,7 +2403,7 @@ static void changemedia(struct sdunit *u)
 
 static int iawctl(struct sdunit *u, struct cmdbuf *cmd)
 {
-       ERRSTACK(2);
+       ERRSTACK(1);
        char **f;
        struct ctlr *c;
        struct drive *d;