|  | /* Copyright (c) 2013-2018 Google Inc | 
|  | * Barret Rhoden <brho@cs.berkeley.edu> | 
|  | * Ron Minnich <rminnich@google.com> | 
|  | * | 
|  | * See LICENSE for details.  */ | 
|  |  | 
|  | #include <slab.h> | 
|  | #include <kmalloc.h> | 
|  | #include <kref.h> | 
|  | #include <string.h> | 
|  | #include <stdio.h> | 
|  | #include <assert.h> | 
|  | #include <error.h> | 
|  | #include <cpio.h> | 
|  | #include <pmap.h> | 
|  | #include <smp.h> | 
|  | #include <net/ip.h> | 
|  |  | 
|  | /* Special akaros edition. */ | 
|  | unsigned int convM2kdirent(uint8_t * buf, unsigned int nbuf, struct kdirent *kd, | 
|  | char *strs) | 
|  | { | 
|  | struct dir *dir; | 
|  | size_t conv_sz, name_sz; | 
|  |  | 
|  | if (nbuf < STAT_FIX_LEN_9P) | 
|  | return 0; | 
|  | dir = kmalloc(sizeof(struct dir) + nbuf, MEM_WAIT); | 
|  | conv_sz = convM2D(buf, nbuf, dir, (char*)&dir[1]); | 
|  |  | 
|  | kd->d_ino = dir->qid.path; | 
|  | kd->d_off = 0;		/* ignored for 9ns readdir */ | 
|  | kd->d_type = 0;		/* TODO: might need this; never used this in the VFS */ | 
|  | name_sz = dir->name ? strlen(dir->name) : 0; | 
|  | kd->d_reclen = name_sz; | 
|  | /* Our caller should have made sure kd was big enough... */ | 
|  | memcpy(kd->d_name, dir->name, name_sz); | 
|  | kd->d_name[name_sz] = 0; | 
|  |  | 
|  | kfree(dir); | 
|  | return conv_sz; | 
|  | } | 
|  |  | 
|  | static int mode_9ns_to_posix(int mode_9ns) | 
|  | { | 
|  | int mode_posix = 0; | 
|  |  | 
|  | if (mode_9ns & DMDIR) | 
|  | mode_posix |= __S_IFDIR; | 
|  | else if (mode_9ns & DMSYMLINK) | 
|  | mode_posix |= __S_IFLNK; | 
|  | else | 
|  | mode_posix |= __S_IFREG; | 
|  | if (mode_9ns & DMREADABLE) | 
|  | mode_posix |= __S_READABLE; | 
|  | if (mode_9ns & DMWRITABLE) | 
|  | mode_posix |= __S_WRITABLE; | 
|  | mode_posix |= mode_9ns & 0777; | 
|  | return mode_posix; | 
|  | } | 
|  |  | 
|  | unsigned int convM2kstat(uint8_t * buf, unsigned int nbuf, struct kstat *ks) | 
|  | { | 
|  | struct dir *dir; | 
|  | size_t conv_sz, name_sz; | 
|  |  | 
|  | if (nbuf < STAT_FIX_LEN_9P) | 
|  | return 0; | 
|  | dir = kmalloc(sizeof(struct dir) + nbuf, MEM_WAIT); | 
|  | conv_sz = convM2D(buf, nbuf, dir, (char*)&dir[1]); | 
|  |  | 
|  | ks->st_dev = dir->type; | 
|  | ks->st_ino = dir->qid.path; | 
|  | ks->st_mode = mode_9ns_to_posix(dir->mode); | 
|  | ks->st_nlink = dir->mode & DMDIR ? 2 : 1; | 
|  | ks->st_uid = dir->n_uid; | 
|  | ks->st_gid = dir->n_gid; | 
|  | ks->st_rdev = dir->dev; | 
|  | ks->st_size = dir->length; | 
|  | ks->st_blksize = 1; | 
|  | ks->st_blocks = dir->length; | 
|  | ks->st_atim = dir->atime; | 
|  | ks->st_mtim = dir->mtime; | 
|  | ks->st_ctim = dir->ctime; | 
|  |  | 
|  | kfree(dir); | 
|  | return conv_sz; | 
|  | } |