9ns: Add error_jmp(): jump with an existing error
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 1 Mar 2018 16:43:04 +0000 (11:43 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 30 Apr 2018 18:31:44 +0000 (14:31 -0400)
Some parts of the code set errno and errstr, but defer the jumping.

This is what that old dev.c code wanted to do: set the error, but not
actualy jump.  That is a common pattern in walk code: it's only an error()
for the first name in a walk.  There can be errors on later names that
don't result in a long jump, but we do want to record the errno/errstr.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/err.h
kern/src/ns/chan.c
kern/src/ns/dev.c

index 7c9f14c..c712360 100644 (file)
 extern void set_error(int error, const char *fmt, ...);
 extern struct errbuf *get_cur_errbuf(void);
 
+#define error_jmp() longjmp(&get_cur_errbuf()->jmpbuf, 1)
+
 #define error(e, x, ...)                                                                                               \
        do {                                                                                                                            \
                set_error(e, x, ##__VA_ARGS__);                                                                 \
-               longjmp(&get_cur_errbuf()->jmpbuf, 1);                                                  \
+               error_jmp();                                                                                                    \
        } while(0)
 #define nexterror() longjmp(&(errpop(errstack, ARRAY_SIZE(errstack), &curindex, \
                                                                         prev_errbuf)->jmpbuf), 1)
index 525c772..3194ce1 100644 (file)
@@ -1130,7 +1130,7 @@ static struct chan *__namec_from(struct chan *c, char *aname, int amode,
 NameError:
                if (current_errstr()[0]) {
                        /* errstr is set, we'll just stick with it and error out */
-                       longjmp(&get_cur_errbuf()->jmpbuf, 1);
+                       error_jmp();
                } else {
                        error(EFAIL, "Name to chan lookup failed");
                }
index 5706023..9e04d31 100644 (file)
@@ -270,14 +270,10 @@ Accept:
                                        printd("DEVWALK -1, i was %d, want path %p\n", i,
                                                   c->qid.path);
 Notfound:
-                                       if (j == 0)
-                                               error(ENOENT, "could not find name %s, dev %s", n,
+                                       set_error(ENOENT, "could not find name %s, dev %s", n,
                                                      c->type == -1 ? "no dev" : devtab[c->type].name);
-                                       /* TODO: I think we don't need to just set_error here.  I
-                                        * got this once when hacking on namec/walk and didn't
-                                        * set_error() in an error case.  This was for symlinks on
-                                        * #kfs bound on #root. */
-                                       set_error(ENOENT, "tell brho you saw this in an error");
+                                       if (j == 0)
+                                               error_jmp();
                                        goto Done;
                                case 0:
                                        printd("DEVWALK continue, i was %d\n", i);
@@ -308,6 +304,9 @@ Done:
        } else if (wq->clone) {
                /* attach cloned channel to same device */
                wq->clone->type = c->type;
+       } else {
+               /* Not sure this is possible, would like to know. */
+               warn_once("had enough names, but still no wq->clone");
        }
        return wq;
 }