Skip to content
Snippets Groups Projects
Commit 9e5970d5 authored by rtm's avatar rtm
Browse files

link()

parent 05e97551
No related branches found
No related tags found
No related merge requests found
......@@ -355,8 +355,6 @@ HMM maybe the variables at the end of struct cpu are being overwritten
OH! recursive interrupts will use up any amount of cpu[].stack!
underflow and wrecks *previous* cpu's struct
better buffer cache replacement
read/write of open file that's been unlinked
disk scheduling
mkdir
more than one directory content block
......@@ -365,3 +363,5 @@ sh redirection
indirect blocks
two bugs in unlink: don't just return if nlink > 0,
and search for name, not inum
is there a create/create race for same file name?
resulting in two entries w/ same name in directory?
......@@ -123,3 +123,4 @@ int writei(struct inode *ip, char *addr, uint off, uint n);
struct inode *mknod(char *, short, short, short);
int unlink(char *cp);
void iupdate (struct inode *ip);
int link(char *file1, char *file2);
......@@ -439,14 +439,41 @@ namei(char *path, uint *ret_pinum)
}
}
void
wdir(struct inode *dp, char *name, uint ino)
{
uint off;
struct buf *bp = 0;
struct dirent *ep = 0;
int i;
for(off = 0; off < dp->size; off += BSIZE) {
bp = bread(dp->dev, bmap(dp, off / BSIZE));
for(ep = (struct dirent *) bp->data;
ep < (struct dirent *) (bp->data + BSIZE);
ep++){
if(ep->inum == 0)
goto found;
}
brelse(bp);
}
panic("mknod: XXXX no dir entry free\n");
found:
ep->inum = ino;
for(i = 0; i < DIRSIZ && name[i]; i++)
ep->name[i] = name[i];
for( ; i < DIRSIZ; i++)
ep->name[i] = '\0';
bwrite (bp, bmap(dp, off/BSIZE)); // write directory block
brelse(bp);
}
struct inode *
mknod(char *cp, short type, short major, short minor)
{
struct inode *ip, *dp;
struct dirent *ep = 0;
int off;
int i;
struct buf *bp = 0;
uint pinum = 0;
cprintf("mknod: %s %d %d %d\n", cp, type, major, minor);
......@@ -469,27 +496,7 @@ mknod(char *cp, short type, short major, short minor)
iupdate (ip); // write new inode to disk
for(off = 0; off < dp->size; off += BSIZE) {
bp = bread(dp->dev, bmap(dp, off / BSIZE));
for(ep = (struct dirent *) bp->data;
ep < (struct dirent *) (bp->data + BSIZE);
ep++){
if(ep->inum == 0) {
goto found;
}
}
brelse(bp);
}
panic("mknod: XXXX no dir entry free\n");
found:
ep->inum = ip->inum;
for(i = 0; i < DIRSIZ && cp[i]; i++)
ep->name[i] = cp[i];
for( ; i < DIRSIZ; i++)
ep->name[i] = '\0';
bwrite (bp, bmap(dp, off/BSIZE)); // write directory block
brelse(bp);
wdir(dp, cp, ip->inum);
iput(dp);
......@@ -541,3 +548,35 @@ unlink(char *cp)
iput(ip);
return 0;
}
int
link(char *name1, char *name2)
{
struct inode *ip, *dp, *xip;
uint pinum = 0;
cprintf("link(%s, %s)\n", name1, name2);
if ((xip = namei(name2, &pinum)) != 0) {
cprintf(" failed %s exists\n", name2);
iput(xip);
return -1;
}
if ((ip = namei(name1, &pinum)) == 0){
cprintf(" failed %s does not exist\n", name1);
return -1;
}
ip->nlink += 1;
iupdate (ip);
dp = iget(rootdev, pinum);
wdir(dp, name2, ip->inum);
iput(dp);
iput(ip);
cprintf(" succeeded\n");
return 0;
}
......@@ -52,14 +52,12 @@ ide_init(void)
}
ioapic_enable (IRQ_IDE, 1);
ide_wait_ready(0);
cprintf ("cpu%d: ide_init:done\n", cpu());
}
void
ide_intr(void)
{
acquire(&ide_lock);
// cprintf("cpu%d: ide_intr\n", cpu());
wakeup(&request[tail]);
release(&ide_lock);
}
......
......@@ -87,8 +87,6 @@ main0(void)
lapic_enableintr();
// Enable interrupts on this processor.
cprintf("cpu%d: nlock %d before -- and sti\n",
cpu(), cpus[0].nlock);
cpus[cpu()].nlock--;
sti();
......@@ -98,7 +96,6 @@ main0(void)
//load_icode(p, _binary_userfs_start, (uint) _binary_userfs_size);
load_icode(p, _binary_init_start, (uint) _binary_init_size);
p->state = RUNNABLE;
cprintf("loaded init\n");
scheduler();
}
......@@ -123,7 +120,6 @@ mpmain(void)
cpus[cpu()].booted = 1;
// Enable interrupts on this processor.
cprintf("cpu%d: initial nlock %d\n", cpu(), cpus[cpu()].nlock);
cpus[cpu()].nlock--;
sti();
......@@ -139,7 +135,6 @@ load_icode(struct proc *p, uchar *binary, uint size)
// Check magic number on binary
elf = (struct elfhdr*) binary;
cprintf("elf %x magic %x\n", elf, elf->magic);
if (elf->magic != ELF_MAGIC)
panic("load_icode: not an ELF binary");
......@@ -151,7 +146,6 @@ load_icode(struct proc *p, uchar *binary, uint size)
for (i = 0; i < elf->phnum; i++, ph++) {
if (ph->type != ELF_PROG_LOAD)
continue;
cprintf("va %x memsz %d\n", ph->va, ph->memsz);
if (ph->va + ph->memsz < ph->va)
panic("load_icode: overflow in elf header segment");
if (ph->va + ph->memsz >= p->sz)
......
......@@ -140,9 +140,6 @@ scheduler(void)
struct proc *p;
int i;
cprintf("cpu%d: start scheduler jmpbuf %p\n",
cpu(), &cpus[cpu()].jmpbuf);
if(cpus[cpu()].nlock != 0){
cprintf("la %x lr %x\n", cpus[cpu()].lastacquire, cpus[cpu()].lastrelease );
panic("holding locks at first entry to scheduler");
......
......@@ -303,7 +303,6 @@ sys_unlink(void)
return r;
}
int
sys_fstat(void)
{
......@@ -325,6 +324,21 @@ sys_fstat(void)
return r;
}
int
sys_link(void)
{
struct proc *cp = curproc[cpu()];
uint name1, name2;
int r;
if(fetcharg(0, &name1) < 0 || checkstring(name1) < 0)
return -1;
if(fetcharg(1, &name2) < 0 || checkstring(name2) < 0)
return -1;
r = link(cp->mem + name1, cp->mem + name2);
return r;
}
int
sys_exec(void)
{
......@@ -543,6 +557,9 @@ syscall(void)
case SYS_fstat:
ret = sys_fstat();
break;
case SYS_link:
ret = sys_link();
break;
default:
cprintf("unknown sys call %d\n", num);
// XXX fault
......
......@@ -12,4 +12,5 @@
#define SYS_mknod 15
#define SYS_unlink 16
#define SYS_fstat 17
#define SYS_link 18
......@@ -16,6 +16,7 @@ int mknod (char*,short,short,short);
int unlink (char*);
struct stat;
int fstat (int fd, struct stat *stat);
int link(char *, char *);
int puts(char*);
char* strcpy(char*, char*);
......
......@@ -344,11 +344,72 @@ unlinkread()
puts("unlinkread ok\n");
}
void
linktest()
{
int fd;
unlink("lf1");
unlink("lf2");
fd = open("lf1", O_CREATE|O_RDWR);
if(fd < 0){
puts("create lf1 failed\n");
exit();
}
if(write(fd, "hello", 5) != 5){
puts("write lf1 failed\n");
exit();
}
close(fd);
if(link("lf1", "lf2") < 0){
puts("link lf1 lf2 failed\n");
exit();
}
unlink("lf1");
if(open("lf1", 0) >= 0){
puts("unlinked lf1 but it is still there!\n");
exit();
}
fd = open("lf2", 0);
if(fd < 0){
puts("open lf2 failed\n");
exit();
}
if(read(fd, buf, sizeof(buf)) != 5){
puts("read lf2 failed\n");
exit();
}
close(fd);
if(link("lf2", "lf2") >= 0){
puts("link lf2 lf2 succeeded! oops\n");
exit();
}
unlink("lf2");
if(link("lf2", "lf1") >= 0){
puts("link non-existant succeeded! oops\n");
exit();
}
if(link(".", "lf1") >= 0){
puts("link . lf1 succeeded! oops\n");
exit();
}
puts("linktest ok\n");
}
int
main(int argc, char *argv[])
{
puts("usertests starting\n");
linktest();
unlinkread();
createdelete();
twofiles();
......
......@@ -22,3 +22,4 @@ STUB(open)
STUB(mknod)
STUB(unlink)
STUB(fstat)
STUB(link)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment