blob: 4345e70543812aab2e503984c917870c83facb94 [file] [log] [blame]
/* 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;
}