lab fs done
This commit is contained in:
parent
408565dc36
commit
4a1d663b39
5
Makefile
5
Makefile
@ -61,7 +61,7 @@ endif
|
||||
|
||||
# riscv64-unknown-elf- or riscv64-linux-gnu-
|
||||
# perhaps in /opt/riscv/bin
|
||||
#TOOLPREFIX =
|
||||
TOOLPREFIX = /opt/riscv/bin/riscv64-unknown-elf-
|
||||
|
||||
# Try to infer the correct TOOLPREFIX if not set
|
||||
ifndef TOOLPREFIX
|
||||
@ -257,7 +257,8 @@ endif
|
||||
|
||||
ifeq ($(LAB),fs)
|
||||
UPROGS += \
|
||||
$U/_bigfile
|
||||
$U/_bigfile\
|
||||
$U/_symlinktest
|
||||
endif
|
||||
|
||||
|
||||
|
||||
@ -238,7 +238,7 @@ def make(*target):
|
||||
post_make()
|
||||
|
||||
def show_command(cmd):
|
||||
from pipes import quote
|
||||
from shlex import quote
|
||||
print("\n$", " ".join(map(quote, cmd)))
|
||||
|
||||
def maybe_unlink(*paths):
|
||||
|
||||
@ -187,3 +187,5 @@ void virtio_disk_intr(void);
|
||||
|
||||
// number of elements in fixed-size array
|
||||
#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
#define DEBUG() printf("File: %s, Line: %d, Function: %s\n", __FILE__, __LINE__, __func__)
|
||||
|
||||
@ -3,3 +3,4 @@
|
||||
#define O_RDWR 0x002
|
||||
#define O_CREATE 0x200
|
||||
#define O_TRUNC 0x400
|
||||
#define O_NOFOLLOW 0x004
|
||||
@ -26,7 +26,7 @@ struct inode {
|
||||
short minor;
|
||||
short nlink;
|
||||
uint size;
|
||||
uint addrs[NDIRECT+1];
|
||||
uint addrs[NDIRECT+2];
|
||||
};
|
||||
|
||||
// map major device number to device functions.
|
||||
|
||||
95
kernel/fs.c
95
kernel/fs.c
@ -398,23 +398,59 @@ bmap(struct inode *ip, uint bn)
|
||||
|
||||
if(bn < NINDIRECT){
|
||||
// Load indirect block, allocating if necessary.
|
||||
if((addr = ip->addrs[NDIRECT]) == 0){
|
||||
addr = balloc(ip->dev);
|
||||
if(addr == 0)
|
||||
return 0;
|
||||
ip->addrs[NDIRECT] = addr;
|
||||
}
|
||||
bp = bread(ip->dev, addr);
|
||||
a = (uint*)bp->data;
|
||||
if((addr = a[bn]) == 0){
|
||||
addr = balloc(ip->dev);
|
||||
if(addr){
|
||||
a[bn] = addr;
|
||||
log_write(bp);
|
||||
if(bn<NINDIRECT1){
|
||||
if((addr = ip->addrs[NDIRECT]) == 0){
|
||||
addr = balloc(ip->dev);
|
||||
if(addr == 0)
|
||||
return 0;
|
||||
ip->addrs[NDIRECT] = addr;
|
||||
}
|
||||
bp = bread(ip->dev, addr);
|
||||
a = (uint*)bp->data;
|
||||
if((addr = a[bn]) == 0){
|
||||
addr = balloc(ip->dev);
|
||||
if(addr){
|
||||
a[bn] = addr;
|
||||
log_write(bp);
|
||||
}
|
||||
}
|
||||
brelse(bp);
|
||||
return addr;
|
||||
}else{
|
||||
bn-=NINDIRECT1;
|
||||
if((addr = ip->addrs[NDIRECT+1])==0){
|
||||
addr = balloc(ip->dev);
|
||||
if(addr == 0)
|
||||
return 0;
|
||||
ip->addrs[NDIRECT+1] = addr;
|
||||
}
|
||||
bp=bread(ip->dev,addr);
|
||||
a = (uint *)bp->data;
|
||||
const uint offset=bn%NINDIRECT1;
|
||||
bn/=NINDIRECT1;
|
||||
if((addr = a[bn])==0){
|
||||
addr=balloc(ip->dev);
|
||||
if(addr){
|
||||
a[bn] = addr;
|
||||
log_write(bp);
|
||||
}
|
||||
}
|
||||
{
|
||||
struct buf *bp=bread(ip->dev,addr);
|
||||
a = (uint *)bp->data;
|
||||
if((addr = a[offset])==0){
|
||||
addr=balloc(ip->dev);
|
||||
if(addr){
|
||||
a[offset]=addr;
|
||||
log_write(bp);
|
||||
}
|
||||
}
|
||||
brelse(bp);
|
||||
}
|
||||
brelse(bp);
|
||||
return addr;
|
||||
}
|
||||
brelse(bp);
|
||||
return addr;
|
||||
|
||||
}
|
||||
|
||||
panic("bmap: out of range");
|
||||
@ -439,7 +475,7 @@ itrunc(struct inode *ip)
|
||||
if(ip->addrs[NDIRECT]){
|
||||
bp = bread(ip->dev, ip->addrs[NDIRECT]);
|
||||
a = (uint*)bp->data;
|
||||
for(j = 0; j < NINDIRECT; j++){
|
||||
for(j = 0; j < NINDIRECT1; j++){
|
||||
if(a[j])
|
||||
bfree(ip->dev, a[j]);
|
||||
}
|
||||
@ -447,7 +483,25 @@ itrunc(struct inode *ip)
|
||||
bfree(ip->dev, ip->addrs[NDIRECT]);
|
||||
ip->addrs[NDIRECT] = 0;
|
||||
}
|
||||
|
||||
if(ip->addrs[NDIRECT+1]){
|
||||
bp = bread(ip->dev,ip->addrs[NDIRECT+1]);
|
||||
a = (uint*)bp->data;
|
||||
for(j = 0;j<NINDIRECT1;++j){
|
||||
if(a[j]){
|
||||
struct buf *bp=bread(ip->dev,a[j]);
|
||||
for(int j=0;j<NINDIRECT1;++j){
|
||||
uint *a=(uint*)bp->data;
|
||||
if(a[j])
|
||||
bfree(ip->dev,a[j]);
|
||||
}
|
||||
brelse(bp);
|
||||
bfree(ip->dev,a[j]);
|
||||
}
|
||||
}
|
||||
brelse(bp);
|
||||
bfree(ip->dev,ip->addrs[NDIRECT+1]);
|
||||
ip->addrs[NDIRECT+1] = 0;
|
||||
}
|
||||
ip->size = 0;
|
||||
iupdate(ip);
|
||||
}
|
||||
@ -508,11 +562,12 @@ writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
|
||||
uint tot, m;
|
||||
struct buf *bp;
|
||||
|
||||
if(off > ip->size || off + n < off)
|
||||
if(off > ip->size || off + n < off){
|
||||
return -1;
|
||||
if(off + n > MAXFILE*BSIZE)
|
||||
}
|
||||
if(off + n > MAXFILE*BSIZE){
|
||||
return -1;
|
||||
|
||||
}
|
||||
for(tot=0; tot<n; tot+=m, off+=m, src+=m){
|
||||
uint addr = bmap(ip, off/BSIZE);
|
||||
if(addr == 0)
|
||||
|
||||
@ -24,8 +24,9 @@ struct superblock {
|
||||
|
||||
#define FSMAGIC 0x10203040
|
||||
|
||||
#define NDIRECT 12
|
||||
#define NINDIRECT (BSIZE / sizeof(uint))
|
||||
#define NDIRECT 11
|
||||
#define NINDIRECT1 (BSIZE / sizeof(uint))
|
||||
#define NINDIRECT (NINDIRECT1 + NINDIRECT1 * NINDIRECT1)
|
||||
#define MAXFILE (NDIRECT + NINDIRECT)
|
||||
|
||||
// On-disk inode structure
|
||||
@ -35,7 +36,7 @@ struct dinode {
|
||||
short minor; // Minor device number (T_DEVICE only)
|
||||
short nlink; // Number of links to inode in file system
|
||||
uint size; // Size of file (bytes)
|
||||
uint addrs[NDIRECT+1]; // Data block addresses
|
||||
uint addrs[NDIRECT+2]; // Data block addresses
|
||||
};
|
||||
|
||||
// Inodes per block.
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#define T_DIR 1 // Directory
|
||||
#define T_FILE 2 // File
|
||||
#define T_DEVICE 3 // Device
|
||||
|
||||
#define T_SYMLINK 4
|
||||
struct stat {
|
||||
int dev; // File system's disk device
|
||||
uint ino; // Inode number
|
||||
|
||||
@ -101,7 +101,7 @@ extern uint64 sys_unlink(void);
|
||||
extern uint64 sys_link(void);
|
||||
extern uint64 sys_mkdir(void);
|
||||
extern uint64 sys_close(void);
|
||||
|
||||
extern uint64 sys_symlink(void);
|
||||
// An array mapping syscall numbers from syscall.h
|
||||
// to the function that handles the system call.
|
||||
static uint64 (*syscalls[])(void) = {
|
||||
@ -126,6 +126,7 @@ static uint64 (*syscalls[])(void) = {
|
||||
[SYS_link] sys_link,
|
||||
[SYS_mkdir] sys_mkdir,
|
||||
[SYS_close] sys_close,
|
||||
[SYS_symlink] sys_symlink
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@ -20,3 +20,4 @@
|
||||
#define SYS_link 19
|
||||
#define SYS_mkdir 20
|
||||
#define SYS_close 21
|
||||
#define SYS_symlink 22
|
||||
@ -327,6 +327,27 @@ sys_open(void)
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
int dep=0;
|
||||
if((omode & O_NOFOLLOW)==0){
|
||||
while(1){
|
||||
ilock(ip);
|
||||
if(ip->type!=T_SYMLINK){
|
||||
iunlock(ip);
|
||||
break;
|
||||
}
|
||||
readi(ip,0,(uint64)path,0,MAXPATH);
|
||||
iunlockput(ip);
|
||||
if((ip = namei(path)) == 0){
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
++dep;
|
||||
if(dep>=10){
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ilock(ip);
|
||||
if(ip->type == T_DIR && omode != O_RDONLY){
|
||||
iunlockput(ip);
|
||||
@ -348,7 +369,7 @@ sys_open(void)
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(ip->type == T_DEVICE){
|
||||
f->type = FD_DEVICE;
|
||||
f->major = ip->major;
|
||||
@ -474,6 +495,31 @@ sys_exec(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64 sys_symlink(){
|
||||
char target[MAXPATH],path[MAXPATH];
|
||||
if(argstr(0, target, MAXPATH) < 0 || argstr(1, path, MAXPATH) < 0)
|
||||
goto ERR1;
|
||||
begin_op();
|
||||
struct inode *ip;
|
||||
if((ip = namei(path)) == 0){
|
||||
if((ip = create(path, T_SYMLINK,0,0))==0)
|
||||
goto ERR2;
|
||||
}else
|
||||
ilock(ip);
|
||||
if(writei(ip,0,(uint64)target,0,MAXPATH)<0){
|
||||
goto ERR3;
|
||||
}
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
return 0;
|
||||
ERR3:
|
||||
iunlockput(ip);
|
||||
ERR2:
|
||||
end_op();
|
||||
ERR1:
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_pipe(void)
|
||||
{
|
||||
|
||||
@ -135,10 +135,10 @@ testsymlink(void)
|
||||
if(c!=c2)
|
||||
fail("Value read from 4 differed from value written to 1\n");
|
||||
|
||||
|
||||
close(fd1);
|
||||
close(fd2);
|
||||
fd1 = fd2 = -1;
|
||||
|
||||
//
|
||||
// check that many symlinks can co-exist.
|
||||
//
|
||||
|
||||
@ -22,7 +22,7 @@ int getpid(void);
|
||||
char* sbrk(int);
|
||||
int sleep(int);
|
||||
int uptime(void);
|
||||
|
||||
int symlink(const char *,const char *);
|
||||
// ulib.c
|
||||
int stat(const char*, struct stat*);
|
||||
char* strcpy(char*, const char*);
|
||||
|
||||
@ -36,3 +36,4 @@ entry("getpid");
|
||||
entry("sbrk");
|
||||
entry("sleep");
|
||||
entry("uptime");
|
||||
entry("symlink");
|
||||
Loading…
Reference in New Issue
Block a user