lab fs done

This commit is contained in:
whatever 2024-12-09 14:50:39 +08:00
parent 408565dc36
commit 4a1d663b39
15 changed files with 142 additions and 32 deletions

View File

@ -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

View File

@ -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):

View File

@ -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__)

View File

@ -3,3 +3,4 @@
#define O_RDWR 0x002
#define O_CREATE 0x200
#define O_TRUNC 0x400
#define O_NOFOLLOW 0x004

View File

@ -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.

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -20,3 +20,4 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_symlink 22

View File

@ -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)
{

1
time.txt Normal file
View File

@ -0,0 +1 @@
6

View File

@ -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.
//

View File

@ -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*);

View File

@ -36,3 +36,4 @@ entry("getpid");
entry("sbrk");
entry("sleep");
entry("uptime");
entry("symlink");