9ns: Extend struct dir and the stat M bufs
[akaros.git] / kern / src / ns / convM2kdirent.c
1 /* Copyright (c) 2013-2018 Google Inc
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * Ron Minnich <rminnich@google.com>
4  *
5  * See LICENSE for details.  */
6
7 #include <vfs.h>
8 #include <kfs.h>
9 #include <slab.h>
10 #include <kmalloc.h>
11 #include <kref.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <assert.h>
15 #include <error.h>
16 #include <cpio.h>
17 #include <pmap.h>
18 #include <smp.h>
19 #include <net/ip.h>
20
21 /* Special akaros edition. */
22 unsigned int convM2kdirent(uint8_t * buf, unsigned int nbuf, struct kdirent *kd,
23                                                    char *strs)
24 {
25         struct dir *dir;
26         size_t conv_sz, name_sz;
27
28         if (nbuf < STAT_FIX_LEN_9P)
29                 return 0;
30         dir = kmalloc(sizeof(struct dir) + nbuf, MEM_WAIT);
31         conv_sz = convM2D(buf, nbuf, dir, (char*)&dir[1]);
32
33         kd->d_ino = dir->qid.path;
34         kd->d_off = 0;          /* ignored for 9ns readdir */
35         kd->d_type = 0;         /* TODO: might need this; never used this in the VFS */
36         name_sz = dir->name ? strlen(dir->name) : 0;
37         kd->d_reclen = name_sz;
38         /* Our caller should have made sure kd was big enough... */
39         memcpy(kd->d_name, dir->name, name_sz);
40         kd->d_name[name_sz] = 0;
41
42         kfree(dir);
43         return conv_sz;
44 }
45
46 static int mode_9ns_to_posix(int mode_9ns)
47 {
48         int mode_posix = 0;
49
50         if (mode_9ns & DMDIR)
51                 mode_posix |= __S_IFDIR;
52         else if (mode_9ns & DMSYMLINK)
53                 mode_posix |= __S_IFLNK;
54         else
55                 mode_posix |= __S_IFREG;
56         if (mode_9ns & DMREADABLE)
57                 mode_posix |= __S_READABLE;
58         if (mode_9ns & DMWRITABLE)
59                 mode_posix |= __S_WRITABLE;
60         mode_posix |= mode_9ns & 0777;
61         return mode_posix;
62 }
63
64 unsigned int convM2kstat(uint8_t * buf, unsigned int nbuf, struct kstat *ks)
65 {
66         struct dir *dir;
67         size_t conv_sz, name_sz;
68
69         if (nbuf < STAT_FIX_LEN_9P)
70                 return 0;
71         dir = kmalloc(sizeof(struct dir) + nbuf, MEM_WAIT);
72         conv_sz = convM2D(buf, nbuf, dir, (char*)&dir[1]);
73
74         ks->st_dev = dir->type;
75         ks->st_ino = dir->qid.path;
76         ks->st_mode = mode_9ns_to_posix(dir->mode);
77         ks->st_nlink = dir->mode & DMDIR ? 2 : 1;
78         ks->st_uid = dir->n_uid;
79         ks->st_gid = dir->n_gid;
80         ks->st_rdev = dir->dev;
81         ks->st_size = dir->length;
82         ks->st_blksize = 1;
83         ks->st_blocks = dir->length;
84         ks->st_atim = dir->atime;
85         ks->st_mtim = dir->mtime;
86         ks->st_ctim = dir->ctime;
87
88         kfree(dir);
89         return conv_sz;
90 }