summaryrefslogtreecommitdiff
path: root/fs.c
diff options
context:
space:
mode:
authorrtm <rtm>2006-08-13 02:12:44 +0000
committerrtm <rtm>2006-08-13 02:12:44 +0000
commit9e5970d596d7b1634200d50e96130886f593cede (patch)
tree994e11ccb4a3a33c1963a8f1fb3f7464d3d9e363 /fs.c
parent05e975511bcf7f33955208319655dbfc687a7b0c (diff)
downloadxv6-labs-9e5970d596d7b1634200d50e96130886f593cede.tar.gz
xv6-labs-9e5970d596d7b1634200d50e96130886f593cede.tar.bz2
xv6-labs-9e5970d596d7b1634200d50e96130886f593cede.zip
link()
Diffstat (limited to 'fs.c')
-rw-r--r--fs.c89
1 files changed, 64 insertions, 25 deletions
diff --git a/fs.c b/fs.c
index e01b4fb..7f0d2ea 100644
--- a/fs.c
+++ b/fs.c
@@ -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;
+}