summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMole Shang <[email protected]>2024-02-17 12:23:15 +0800
committerMole Shang <[email protected]>2024-02-17 12:39:50 +0800
commit659b978caa5c97bbc2477d1393461c944544a1a7 (patch)
tree9c1920f3e65443f838d0f6e8af020d0903ab3fcd /kernel
parente8e0a7b4c97064eb5e9415726d7e38aaceccd3fd (diff)
downloadxv6-labs-659b978caa5c97bbc2477d1393461c944544a1a7.tar.gz
xv6-labs-659b978caa5c97bbc2477d1393461c944544a1a7.tar.bz2
xv6-labs-659b978caa5c97bbc2477d1393461c944544a1a7.zip
lab fs/bigfile: finish
Diffstat (limited to 'kernel')
-rw-r--r--kernel/file.h2
-rw-r--r--kernel/fs.c63
-rw-r--r--kernel/fs.h8
3 files changed, 64 insertions, 9 deletions
diff --git a/kernel/file.h b/kernel/file.h
index 1eb5107..b993cc3 100644
--- a/kernel/file.h
+++ b/kernel/file.h
@@ -33,7 +33,7 @@ struct inode {
short minor;
short nlink;
uint size;
- uint addrs[NDIRECT+1];
+ uint addrs[NDIRECT+2];
};
// map major device number to device functions.
diff --git a/kernel/fs.c b/kernel/fs.c
index 6c4079e..57b36a1 100644
--- a/kernel/fs.c
+++ b/kernel/fs.c
@@ -396,7 +396,7 @@ bmap(struct inode *ip, uint bn)
}
bn -= NDIRECT;
- if(bn < NINDIRECT){
+ if(bn < NSG_INDIRECT){
// Load indirect block, allocating if necessary.
if((addr = ip->addrs[NDIRECT]) == 0){
addr = balloc(ip->dev);
@@ -416,6 +416,38 @@ bmap(struct inode *ip, uint bn)
brelse(bp);
return addr;
}
+ bn -= NSG_INDIRECT;
+
+ if(bn < NDB_INDIRECT){
+ // Load indirect block in each level, allocating if necessary.
+ 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;
+ if((addr = a[bn/NSG_INDIRECT]) == 0){
+ addr = balloc(ip->dev);
+ if(addr){
+ a[bn/NSG_INDIRECT] = addr;
+ log_write(bp);
+ }
+ }
+ brelse(bp);
+ bp = bread(ip->dev, addr);
+ a = (uint*)bp->data;
+ if((addr = a[bn%NSG_INDIRECT]) == 0){
+ addr = balloc(ip->dev);
+ if(addr){
+ a[bn%NSG_INDIRECT] = addr;
+ log_write(bp);
+ }
+ }
+ brelse(bp);
+ return addr;
+ }
panic("bmap: out of range");
}
@@ -424,9 +456,9 @@ bmap(struct inode *ip, uint bn)
void
itrunc(struct inode *ip)
{
- int i, j;
- struct buf *bp;
- uint *a;
+ int i, j, k;
+ struct buf *bp, *l2bp;
+ uint *a, *l2a;
for(i = 0; i < NDIRECT; i++){
if(ip->addrs[i]){
@@ -438,7 +470,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 < NSG_INDIRECT; j++){
if(a[j])
bfree(ip->dev, a[j]);
}
@@ -447,6 +479,27 @@ itrunc(struct inode *ip)
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 < NSG_INDIRECT; j++){
+ if(a[j]){
+ l2bp = bread(ip->dev, a[j]);
+ l2a = (uint*)l2bp->data;
+ for(k = 0; k < NSG_INDIRECT; k++)
+ {
+ if(l2a[k]){
+ bfree(ip->dev, l2a[k]);
+ }
+ }
+ brelse(l2bp); bfree(ip->dev, a[j]);
+ }
+ }
+ brelse(bp);
+ bfree(ip->dev, ip->addrs[NDIRECT+1]);
+ ip->addrs[NDIRECT+1] = 0;
+ }
+
ip->size = 0;
iupdate(ip);
}
diff --git a/kernel/fs.h b/kernel/fs.h
index 139dcc9..9ae5ece 100644
--- a/kernel/fs.h
+++ b/kernel/fs.h
@@ -24,8 +24,10 @@ struct superblock {
#define FSMAGIC 0x10203040
-#define NDIRECT 12
-#define NINDIRECT (BSIZE / sizeof(uint))
+#define NDIRECT 11
+#define NSG_INDIRECT (BSIZE / sizeof(uint))
+#define NDB_INDIRECT (NSG_INDIRECT * NSG_INDIRECT)
+#define NINDIRECT (NSG_INDIRECT + NDB_INDIRECT)
#define MAXFILE (NDIRECT + NINDIRECT)
// On-disk inode structure
@@ -35,7 +37,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.