提交 cfd454fc 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Merge branch 'scale-amd64' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale-amd64

UPROGS= \
cat \
du \
echo \
init \
forkexectree \
......
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
static int
du(int fd)
{
struct stat st;
if (fstat(fd, &st) < 0) {
fprintf(2, "du: cannot stat\n");
close(fd);
return 0;
}
int size = st.size;
if (st.type == T_DIR) {
struct dirent de;
while (read(fd, &de, sizeof(de)) == sizeof(de)) {
if (de.inum == 0)
continue;
char buf[DIRSIZ+1];
memmove(buf, de.name, DIRSIZ);
buf[DIRSIZ] = 0;
if (!strcmp(buf, ".") || !strcmp(buf, ".."))
continue;
int nfd = openat(fd, buf, 0);
if (nfd >= 0)
size += du(nfd); // should go into work queue
}
}
close(fd);
return size;
}
int
main(int ac, char **av)
{
printf("%d\n", du(open(".", 0)));
exit();
}
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
const char*
fmtname(const char *path)
{
static char buf[DIRSIZ+1];
const char *p;
// Find first character after last slash.
for(p=path+strlen(path); p >= path && *p != '/'; p--)
;
p++;
// Return blank-padded name.
if(strlen(p) >= DIRSIZ)
return p;
memmove(buf, p, strlen(p));
memset(buf+strlen(p), ' ', DIRSIZ-strlen(p));
return buf;
}
void
ls(const char *path)
{
char buf[512], *p;
int fd;
struct dirent de;
struct stat st;
if((fd = open(path, 0)) < 0){
fprintf(2, "ls: cannot open %s\n", path);
return;
}
if(fstat(fd, &st) < 0){
fprintf(2, "ls: cannot stat %s\n", path);
close(fd);
return;
}
switch(st.type){
case T_FILE:
fprintf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size);
break;
case T_DIR:
if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
fprintf(1, "ls: path too long\n");
break;
}
strcpy(buf, path);
p = buf+strlen(buf);
*p++ = '/';
while(read(fd, &de, sizeof(de)) == sizeof(de)){
if(de.inum == 0)
continue;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;
if(stat(buf, &st) < 0){
fprintf(1, "ls: cannot stat %s\n", buf);
continue;
}
fprintf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size);
}
break;
}
close(fd);
}
void
work(void *arg)
{
u64 tid = (u64)arg;
// grab and push work (may divide into blocks? and call ls on a block)?
// maybe implement getdirent sys call that gives you some unread dir entry
}
int
main(int argc, char *argv[])
{
int i;
int nthread = 4;
for(int i = 0; i < nthread; i++) {
sbrk(8192);
void *tstack = sbrk(0);
// fprintf(1, "tstack %lx\n", tstack);
int tid = forkt(tstack, (void*) thr, (void *)(u64)i);
if (0) fprintf(1, "pls[%d]: child %d\n", getpid(), tid);
}
// push work wq.cc
if(argc < 2){
ls(".");
exit();
}
for(i=1; i<argc; i++)
ls(argv[i]);
for(int i = 0; i < nthread; i++)
wait();
exit();
}
......@@ -2,3 +2,5 @@
#define O_WRONLY 0x001
#define O_RDWR 0x002
#define O_CREATE 0x200
#define AT_FDCWD -100
......@@ -31,7 +31,7 @@ long sys_kill(int);
long sys_link(const char*, const char*);
long sys_mkdir(const char*);
long sys_mknod(const char*, int, int);
long sys_open(const char*, int);
long sys_openat(int, const char*, int);
long sys_pipe(int*);
long sys_read(int, char*, int);
long sys_sbrk(int);
......
......@@ -99,7 +99,7 @@ int filewrite(struct file*, char*, int n);
int namecmp(const char*, const char*);
struct inode* dirlookup(struct inode*, char*);
struct inode* ialloc(u32, short);
struct inode* namei(const char*);
struct inode* namei(inode *cwd, const char*);
void iput(struct inode*);
struct inode* iget(u32 dev, u32 inum);
void ilock(struct inode*, int writer);
......@@ -110,7 +110,7 @@ int readi(struct inode*, char*, u32, u32);
void stati(struct inode*, struct stat*);
int writei(struct inode*, char*, u32, u32);
struct inode* idup(struct inode*);
struct inode* nameiparent(const char*, char*);
struct inode* nameiparent(inode *cwd, const char*, char*);
int dirlink(struct inode*, const char*, u32);
void dir_init(struct inode *dp);
void dir_flush(struct inode *dp);
......
......@@ -8,7 +8,7 @@
#define SYS_close 7
#define SYS_kill 8
#define SYS_exec 9
#define SYS_open 10
#define SYS_openat 10
#define SYS_mknod 11
#define SYS_unlink 12
#define SYS_fstat 13
......
......@@ -30,6 +30,7 @@ void halt(void);
ssize_t pread(int, void*, size_t, off_t);
int async(int, size_t, off_t, u32, u32);
int script(void *addr, u64 len, u64 chunk);
int openat(int dirfd, const char *pathname, int omode);
// ulib.c
int stat(char*, struct stat*);
......
......@@ -41,7 +41,7 @@ long (*syscalls[])(u64, u64, u64, u64, u64) = {
SYSCALL(link),
SYSCALL(mkdir),
SYSCALL(mknod),
SYSCALL(open),
SYSCALL(openat),
SYSCALL(pipe),
SYSCALL(read),
SYSCALL(sbrk),
......
......@@ -154,7 +154,7 @@ exec(const char *path, char **argv)
struct vmap *oldvmap;
prof_start(exec_prof);
if((ip = namei(path)) == 0)
if((ip = namei(myproc()->cwd, path)) == 0)
return -1;
gc_begin_epoch();
......
......@@ -15,6 +15,7 @@ filealloc(void)
{
struct file *f = (file*) kmalloc(sizeof(struct file));
f->ref = 1;
f->type = file::FD_NONE;
return f;
}
......@@ -40,7 +41,7 @@ fileclose(struct file *f)
iput(f->ip);
else if(f->type == file::FD_SOCKET)
netclose(f->socket);
else
else if(f->type != file::FD_NONE)
panic("fileclose bad type");
kmfree(f, sizeof(struct file));
}
......
......@@ -745,7 +745,7 @@ skipelem(const char **rpath, char *name)
// If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes.
static struct inode*
namex(const char *path, int nameiparent, char *name)
namex(inode *cwd, const char *path, int nameiparent, char *name)
{
struct inode *ip, *next;
int r;
......@@ -754,7 +754,7 @@ namex(const char *path, int nameiparent, char *name)
if(*path == '/')
ip = iget(ROOTDEV, ROOTINO);
else
ip = idup(myproc()->cwd);
ip = idup(cwd);
while((r = skipelem(&path, name)) == 1){
next = 0;
......@@ -790,17 +790,17 @@ namex(const char *path, int nameiparent, char *name)
}
struct inode*
namei(const char *path)
namei(inode *cwd, const char *path)
{
char name[DIRSIZ];
struct inode *r = namex(path, 0, name);
struct inode *r = namex(cwd, path, 0, name);
//cprintf("namei: %s -> %x (%d)\n", path, r, r?r->inum:0);
return r;
}
struct inode*
nameiparent(const char *path, char *name)
nameiparent(inode *cwd, const char *path, char *name)
{
return namex(path, 1, name);
return namex(cwd, path, 1, name);
}
......@@ -101,7 +101,7 @@ forkret(void)
// in which to call cv_sleep().
if(myproc()->cwd == nullptr) {
mtstart(forkret, myproc());
myproc()->cwd = namei("/");
myproc()->cwd = namei(myproc()->cwd, "/");
mtstop(myproc());
}
......
......@@ -132,7 +132,7 @@ sys_link(const char *old, const char *newn)
if(argcheckstr(old) < 0 || argcheckstr(newn) < 0)
return -1;
if((ip = namei(old)) == 0)
if((ip = namei(myproc()->cwd, old)) == 0)
return -1;
ilock(ip, 1);
if(ip->type == T_DIR){
......@@ -143,7 +143,7 @@ sys_link(const char *old, const char *newn)
iupdate(ip);
iunlock(ip);
if((dp = nameiparent(newn, name)) == 0)
if((dp = nameiparent(myproc()->cwd, newn, name)) == 0)
goto bad;
if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0)
goto bad;
......@@ -185,7 +185,7 @@ sys_unlink(const char *path)
if(argcheckstr(path) < 0)
return -1;
if((dp = nameiparent(path, name)) == 0)
if((dp = nameiparent(myproc()->cwd, path, name)) == 0)
return -1;
if(dp->type != T_DIR)
panic("sys_unlink");
......@@ -234,13 +234,13 @@ sys_unlink(const char *path)
}
static struct inode*
create(const char *path, short type, short major, short minor)
create(inode *cwd, const char *path, short type, short major, short minor)
{
struct inode *ip, *dp;
char name[DIRSIZ];
retry:
if((dp = nameiparent(path, name)) == 0)
if((dp = nameiparent(cwd, path, name)) == 0)
return 0;
if(dp->type != T_DIR)
panic("create");
......@@ -284,20 +284,32 @@ create(const char *path, short type, short major, short minor)
}
long
sys_open(const char *path, int omode)
sys_openat(int dirfd, const char *path, int omode)
{
int fd;
struct file *f;
struct inode *ip;
struct inode *cwd;
if (dirfd == AT_FDCWD) {
cwd = myproc()->cwd;
} else if (dirfd < 0 || dirfd >= NOFILE) {
return -1;
} else {
struct file *fdir = myproc()->ofile[dirfd];
if (fdir->type != file::FD_INODE)
return -1;
cwd = fdir->ip;
}
if(argcheckstr(path) < 0)
return -1;
if(omode & O_CREATE){
if((ip = create(path, T_FILE, 0, 0)) == 0)
if((ip = create(cwd, path, T_FILE, 0, 0)) == 0)
return -1;
} else {
retry:
if((ip = namei(path)) == 0)
if((ip = namei(cwd, path)) == 0)
return -1;
ilock(ip, 0);
if(ip->type == 0) {
......@@ -335,7 +347,7 @@ sys_mkdir(const char *path)
{
struct inode *ip;
if(argcheckstr(path) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0)
if(argcheckstr(path) < 0 || (ip = create(myproc()->cwd, path, T_DIR, 0, 0)) == 0)
return -1;
iunlockput(ip);
return 0;
......@@ -348,7 +360,7 @@ sys_mknod(const char *path, int major, int minor)
int len;
if((len=argcheckstr(path)) < 0 ||
(ip = create(path, T_DEV, major, minor)) == 0)
(ip = create(myproc()->cwd, path, T_DEV, major, minor)) == 0)
return -1;
iunlockput(ip);
return 0;
......@@ -359,7 +371,7 @@ sys_chdir(const char *path)
{
struct inode *ip;
if(argcheckstr(path) < 0 || (ip = namei(path)) == 0)
if(argcheckstr(path) < 0 || (ip = namei(myproc()->cwd, path)) == 0)
return -1;
ilock(ip, 0);
if(ip->type != T_DIR){
......
......@@ -130,3 +130,9 @@ memmove(void *vdst, const void *vsrc, int n)
*dst++ = *src++;
return vdst;
}
int
open(const char *path, int omode)
{
return openat(AT_FDCWD, path, omode);
}
......@@ -25,7 +25,7 @@ SYSCALL(write)
SYSCALL(close)
SYSCALL(kill)
SYSCALL_INT(exec)
SYSCALL(open)
SYSCALL(openat)
SYSCALL(mknod)
SYSCALL(unlink)
SYSCALL(fstat)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论