提交 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= \ UPROGS= \
cat \ cat \
du \
echo \ echo \
init \ init \
forkexectree \ 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 @@ ...@@ -2,3 +2,5 @@
#define O_WRONLY 0x001 #define O_WRONLY 0x001
#define O_RDWR 0x002 #define O_RDWR 0x002
#define O_CREATE 0x200 #define O_CREATE 0x200
#define AT_FDCWD -100
...@@ -31,7 +31,7 @@ long sys_kill(int); ...@@ -31,7 +31,7 @@ long sys_kill(int);
long sys_link(const char*, const char*); long sys_link(const char*, const char*);
long sys_mkdir(const char*); long sys_mkdir(const char*);
long sys_mknod(const char*, int, int); 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_pipe(int*);
long sys_read(int, char*, int); long sys_read(int, char*, int);
long sys_sbrk(int); long sys_sbrk(int);
......
...@@ -99,7 +99,7 @@ int filewrite(struct file*, char*, int n); ...@@ -99,7 +99,7 @@ int filewrite(struct file*, char*, int n);
int namecmp(const char*, const char*); int namecmp(const char*, const char*);
struct inode* dirlookup(struct inode*, char*); struct inode* dirlookup(struct inode*, char*);
struct inode* ialloc(u32, short); struct inode* ialloc(u32, short);
struct inode* namei(const char*); struct inode* namei(inode *cwd, const char*);
void iput(struct inode*); void iput(struct inode*);
struct inode* iget(u32 dev, u32 inum); struct inode* iget(u32 dev, u32 inum);
void ilock(struct inode*, int writer); void ilock(struct inode*, int writer);
...@@ -110,7 +110,7 @@ int readi(struct inode*, char*, u32, u32); ...@@ -110,7 +110,7 @@ int readi(struct inode*, char*, u32, u32);
void stati(struct inode*, struct stat*); void stati(struct inode*, struct stat*);
int writei(struct inode*, char*, u32, u32); int writei(struct inode*, char*, u32, u32);
struct inode* idup(struct inode*); 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); int dirlink(struct inode*, const char*, u32);
void dir_init(struct inode *dp); void dir_init(struct inode *dp);
void dir_flush(struct inode *dp); void dir_flush(struct inode *dp);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define SYS_close 7 #define SYS_close 7
#define SYS_kill 8 #define SYS_kill 8
#define SYS_exec 9 #define SYS_exec 9
#define SYS_open 10 #define SYS_openat 10
#define SYS_mknod 11 #define SYS_mknod 11
#define SYS_unlink 12 #define SYS_unlink 12
#define SYS_fstat 13 #define SYS_fstat 13
......
...@@ -30,6 +30,7 @@ void halt(void); ...@@ -30,6 +30,7 @@ void halt(void);
ssize_t pread(int, void*, size_t, off_t); ssize_t pread(int, void*, size_t, off_t);
int async(int, size_t, off_t, u32, u32); int async(int, size_t, off_t, u32, u32);
int script(void *addr, u64 len, u64 chunk); int script(void *addr, u64 len, u64 chunk);
int openat(int dirfd, const char *pathname, int omode);
// ulib.c // ulib.c
int stat(char*, struct stat*); int stat(char*, struct stat*);
......
...@@ -41,7 +41,7 @@ long (*syscalls[])(u64, u64, u64, u64, u64) = { ...@@ -41,7 +41,7 @@ long (*syscalls[])(u64, u64, u64, u64, u64) = {
SYSCALL(link), SYSCALL(link),
SYSCALL(mkdir), SYSCALL(mkdir),
SYSCALL(mknod), SYSCALL(mknod),
SYSCALL(open), SYSCALL(openat),
SYSCALL(pipe), SYSCALL(pipe),
SYSCALL(read), SYSCALL(read),
SYSCALL(sbrk), SYSCALL(sbrk),
......
...@@ -154,7 +154,7 @@ exec(const char *path, char **argv) ...@@ -154,7 +154,7 @@ exec(const char *path, char **argv)
struct vmap *oldvmap; struct vmap *oldvmap;
prof_start(exec_prof); prof_start(exec_prof);
if((ip = namei(path)) == 0) if((ip = namei(myproc()->cwd, path)) == 0)
return -1; return -1;
gc_begin_epoch(); gc_begin_epoch();
......
...@@ -15,6 +15,7 @@ filealloc(void) ...@@ -15,6 +15,7 @@ filealloc(void)
{ {
struct file *f = (file*) kmalloc(sizeof(struct file)); struct file *f = (file*) kmalloc(sizeof(struct file));
f->ref = 1; f->ref = 1;
f->type = file::FD_NONE;
return f; return f;
} }
...@@ -40,7 +41,7 @@ fileclose(struct file *f) ...@@ -40,7 +41,7 @@ fileclose(struct file *f)
iput(f->ip); iput(f->ip);
else if(f->type == file::FD_SOCKET) else if(f->type == file::FD_SOCKET)
netclose(f->socket); netclose(f->socket);
else else if(f->type != file::FD_NONE)
panic("fileclose bad type"); panic("fileclose bad type");
kmfree(f, sizeof(struct file)); kmfree(f, sizeof(struct file));
} }
......
...@@ -745,7 +745,7 @@ skipelem(const char **rpath, char *name) ...@@ -745,7 +745,7 @@ skipelem(const char **rpath, char *name)
// If parent != 0, return the inode for the parent and copy the final // If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes. // path element into name, which must have room for DIRSIZ bytes.
static struct inode* 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; struct inode *ip, *next;
int r; int r;
...@@ -754,7 +754,7 @@ namex(const char *path, int nameiparent, char *name) ...@@ -754,7 +754,7 @@ namex(const char *path, int nameiparent, char *name)
if(*path == '/') if(*path == '/')
ip = iget(ROOTDEV, ROOTINO); ip = iget(ROOTDEV, ROOTINO);
else else
ip = idup(myproc()->cwd); ip = idup(cwd);
while((r = skipelem(&path, name)) == 1){ while((r = skipelem(&path, name)) == 1){
next = 0; next = 0;
...@@ -790,17 +790,17 @@ namex(const char *path, int nameiparent, char *name) ...@@ -790,17 +790,17 @@ namex(const char *path, int nameiparent, char *name)
} }
struct inode* struct inode*
namei(const char *path) namei(inode *cwd, const char *path)
{ {
char name[DIRSIZ]; 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); //cprintf("namei: %s -> %x (%d)\n", path, r, r?r->inum:0);
return r; return r;
} }
struct inode* 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) ...@@ -101,7 +101,7 @@ forkret(void)
// in which to call cv_sleep(). // in which to call cv_sleep().
if(myproc()->cwd == nullptr) { if(myproc()->cwd == nullptr) {
mtstart(forkret, myproc()); mtstart(forkret, myproc());
myproc()->cwd = namei("/"); myproc()->cwd = namei(myproc()->cwd, "/");
mtstop(myproc()); mtstop(myproc());
} }
......
...@@ -132,7 +132,7 @@ sys_link(const char *old, const char *newn) ...@@ -132,7 +132,7 @@ sys_link(const char *old, const char *newn)
if(argcheckstr(old) < 0 || argcheckstr(newn) < 0) if(argcheckstr(old) < 0 || argcheckstr(newn) < 0)
return -1; return -1;
if((ip = namei(old)) == 0) if((ip = namei(myproc()->cwd, old)) == 0)
return -1; return -1;
ilock(ip, 1); ilock(ip, 1);
if(ip->type == T_DIR){ if(ip->type == T_DIR){
...@@ -143,7 +143,7 @@ sys_link(const char *old, const char *newn) ...@@ -143,7 +143,7 @@ sys_link(const char *old, const char *newn)
iupdate(ip); iupdate(ip);
iunlock(ip); iunlock(ip);
if((dp = nameiparent(newn, name)) == 0) if((dp = nameiparent(myproc()->cwd, newn, name)) == 0)
goto bad; goto bad;
if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0) if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0)
goto bad; goto bad;
...@@ -185,7 +185,7 @@ sys_unlink(const char *path) ...@@ -185,7 +185,7 @@ sys_unlink(const char *path)
if(argcheckstr(path) < 0) if(argcheckstr(path) < 0)
return -1; return -1;
if((dp = nameiparent(path, name)) == 0) if((dp = nameiparent(myproc()->cwd, path, name)) == 0)
return -1; return -1;
if(dp->type != T_DIR) if(dp->type != T_DIR)
panic("sys_unlink"); panic("sys_unlink");
...@@ -234,13 +234,13 @@ sys_unlink(const char *path) ...@@ -234,13 +234,13 @@ sys_unlink(const char *path)
} }
static struct inode* 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; struct inode *ip, *dp;
char name[DIRSIZ]; char name[DIRSIZ];
retry: retry:
if((dp = nameiparent(path, name)) == 0) if((dp = nameiparent(cwd, path, name)) == 0)
return 0; return 0;
if(dp->type != T_DIR) if(dp->type != T_DIR)
panic("create"); panic("create");
...@@ -284,20 +284,32 @@ create(const char *path, short type, short major, short minor) ...@@ -284,20 +284,32 @@ create(const char *path, short type, short major, short minor)
} }
long long
sys_open(const char *path, int omode) sys_openat(int dirfd, const char *path, int omode)
{ {
int fd; int fd;
struct file *f; struct file *f;
struct inode *ip; 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) if(argcheckstr(path) < 0)
return -1; return -1;
if(omode & O_CREATE){ 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; return -1;
} else { } else {
retry: retry:
if((ip = namei(path)) == 0) if((ip = namei(cwd, path)) == 0)
return -1; return -1;
ilock(ip, 0); ilock(ip, 0);
if(ip->type == 0) { if(ip->type == 0) {
...@@ -335,7 +347,7 @@ sys_mkdir(const char *path) ...@@ -335,7 +347,7 @@ sys_mkdir(const char *path)
{ {
struct inode *ip; 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; return -1;
iunlockput(ip); iunlockput(ip);
return 0; return 0;
...@@ -348,7 +360,7 @@ sys_mknod(const char *path, int major, int minor) ...@@ -348,7 +360,7 @@ sys_mknod(const char *path, int major, int minor)
int len; int len;
if((len=argcheckstr(path)) < 0 || 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; return -1;
iunlockput(ip); iunlockput(ip);
return 0; return 0;
...@@ -359,7 +371,7 @@ sys_chdir(const char *path) ...@@ -359,7 +371,7 @@ sys_chdir(const char *path)
{ {
struct inode *ip; struct inode *ip;
if(argcheckstr(path) < 0 || (ip = namei(path)) == 0) if(argcheckstr(path) < 0 || (ip = namei(myproc()->cwd, path)) == 0)
return -1; return -1;
ilock(ip, 0); ilock(ip, 0);
if(ip->type != T_DIR){ if(ip->type != T_DIR){
......
...@@ -130,3 +130,9 @@ memmove(void *vdst, const void *vsrc, int n) ...@@ -130,3 +130,9 @@ memmove(void *vdst, const void *vsrc, int n)
*dst++ = *src++; *dst++ = *src++;
return vdst; return vdst;
} }
int
open(const char *path, int omode)
{
return openat(AT_FDCWD, path, omode);
}
...@@ -25,7 +25,7 @@ SYSCALL(write) ...@@ -25,7 +25,7 @@ SYSCALL(write)
SYSCALL(close) SYSCALL(close)
SYSCALL(kill) SYSCALL(kill)
SYSCALL_INT(exec) SYSCALL_INT(exec)
SYSCALL(open) SYSCALL(openat)
SYSCALL(mknod) SYSCALL(mknod)
SYSCALL(unlink) SYSCALL(unlink)
SYSCALL(fstat) SYSCALL(fstat)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论