Fix up sys*stat
authorRonald G. Minnich <rminnich@google.com>
Fri, 31 Jan 2014 20:02:39 +0000 (12:02 -0800)
committerRonald G. Minnich <rminnich@google.com>
Fri, 31 Jan 2014 20:02:39 +0000 (12:02 -0800)
I'd rather not go into how big a mess I made of these
functions. It's all better now.

Signed-off-by: Ronald G. Minnich <rminnich@google.com>
kern/include/ns.h
kern/src/ns/sysfile.c
kern/src/syscall.c

index 10ec3b8..1bf5855 100644 (file)
@@ -950,8 +950,8 @@ int grpclose(struct fgrp *f, int fd);
 int sysclose(int fd);
 int syscreate(char *path, int mode, uint32_t perm);
 int sysdup(int old, int new);
-int sysfstat(int fd, struct dir *, int n);
-int sysfstatakaros(int fd, uint8_t *buf, int n);
+int sysfstat(int fd, uint8_t*, int n);
+int sysfstatakaros(int fd, struct kstat *);
 char *sysfd2path(int fd);
 int sysfauth(int fd, char *aname);
 int sysfversion(int fd, unsigned int msize, char *vers, unsigned int arglen);
@@ -968,8 +968,8 @@ long syspread(int fd, void *va, long n, int64_t off);
 int sysremove(char *path);
 int64_t sysseek(int fd, int64_t off, int whence);
 void validstat(uint8_t * s, int n);
-int sysstat(char *path, struct dir * buf, int n);
-int sysstatakaros(char *path, uint8_t * buf, int n);
+int sysstat(char *path, uint8_t*, int n);
+int sysstatakaros(char *path, struct kstat *);
 long syswrite(int fd, void *va, long n);
 long syspwrite(int fd, void *va, long n, int64_t off);
 int syswstat(char *path, uint8_t * buf, int n);
index 4275bac..13b46a8 100644 (file)
@@ -938,7 +938,7 @@ void validstat(uint8_t * s, int n)
                validname(buf, 0);
 }
 
-int sysfstat(int fd, struct dir *dir9ns, int n)
+int sysfstat(int fd, uint8_t *buf, int n)
 {
        ERRSTACK(2);
        struct chan *c;
@@ -953,7 +953,7 @@ int sysfstat(int fd, struct dir *dir9ns, int n)
                cclose(c);
                nexterror();
        }
-       devtab[c->type].stat(c, (void *)dir9ns, n);
+       devtab[c->type].stat(c, buf, n);
 
        poperror();
        cclose(c);
@@ -962,16 +962,21 @@ int sysfstat(int fd, struct dir *dir9ns, int n)
        return n;
 }
 
-int sysfstatakaros(int fd, uint8_t *buf, int n)
+int sysfstatakaros(int fd, struct kstat *ks)
 {
-       struct dir dir9ns;
-       if ((n = sysfstat(fd, &dir9ns, sizeof(dir9ns))) < 0)
-               return n;
-       convM2kstat((void *)&dir9ns, sizeof(struct dir), (struct kstat *)buf);
+       int n = 4096;
+       uint8_t *buf;
+       buf = kmalloc(n, KMALLOC_WAIT);
+       n = sysfstat(fd, buf, n);
+       if (n > 0) {
+               convM2kstat(buf, n, ks);
+               n = 0;
+       }
+       kfree(buf);
        return n;
 }
 
-int sysstat(char *path, struct dir *dir9ns, int n)
+int sysstat(char *path, uint8_t *buf, int n)
 {
        ERRSTACK(2);
        struct chan *c;
@@ -986,7 +991,7 @@ int sysstat(char *path, struct dir *dir9ns, int n)
                cclose(c);
                nexterror();
        }
-       devtab[c->type].stat(c, (void *)dir9ns, sizeof(struct dir));
+       devtab[c->type].stat(c, buf, n);
        poperror();
        cclose(c);
 
@@ -995,14 +1000,18 @@ int sysstat(char *path, struct dir *dir9ns, int n)
        return n;
 }
 
-int sysstatakaros(char *path, uint8_t * buf, int n)
+int sysstatakaros(char *path, struct kstat *ks)
 {
-       struct dir dir9ns;
-       n = sysstat(path, &dir9ns, sizeof(dir9ns));
-       if (n < 0)
-               return n;
-       convM2kstat((void *)&dir9ns, sizeof(struct dir), (struct kstat *)buf);
-       return 0;
+       int n = 4096;
+       uint8_t *buf;
+       buf = kmalloc(n, KMALLOC_WAIT);
+       n = sysstat(path, buf, n);
+       if (n > 0) {
+               convM2kstat(buf, n, ks);
+               n = 0;
+       }
+       kfree(buf);
+       return n;
 }
 
 static long rwrite(int fd, void *va, long n, int64_t * offp)
index 064217e..9976f72 100644 (file)
@@ -1134,7 +1134,7 @@ static intreg_t sys_fstat(struct proc *p, int fd, struct kstat *u_stat)
                kref_put(&file->f_kref);
        } else {
                unset_errno();  /* Go can't handle extra errnos */
-           if (sysfstatakaros(fd, (uint8_t*)kbuf, sizeof(*kbuf)) < 0) {
+           if (sysfstatakaros(fd, (struct kstat *)kbuf) < 0) {
                        kfree(kbuf);
                        return -1;
                }
@@ -1174,7 +1174,7 @@ static intreg_t stat_helper(struct proc *p, const char *path, size_t path_l,
        } else {
                /* VFS failed, checking 9ns */
                unset_errno();  /* Go can't handle extra errnos */
-               retval = sysstatakaros(t_path, (uint8_t*)kbuf, sizeof(*kbuf));
+               retval = sysstatakaros(t_path, (struct stat *)kbuf);
                printd("sysstat returns %d\n", retval);
                /* both VFS and 9ns failed, bail out */
                if (retval < 0)