diff options
author | Mole Shang <[email protected]> | 2024-02-17 12:23:15 +0800 |
---|---|---|
committer | Mole Shang <[email protected]> | 2024-02-17 12:39:50 +0800 |
commit | 659b978caa5c97bbc2477d1393461c944544a1a7 (patch) | |
tree | 9c1920f3e65443f838d0f6e8af020d0903ab3fcd | |
parent | e8e0a7b4c97064eb5e9415726d7e38aaceccd3fd (diff) | |
download | xv6-labs-659b978caa5c97bbc2477d1393461c944544a1a7.tar.gz xv6-labs-659b978caa5c97bbc2477d1393461c944544a1a7.tar.bz2 xv6-labs-659b978caa5c97bbc2477d1393461c944544a1a7.zip |
lab fs/bigfile: finish
-rw-r--r-- | kernel/file.h | 2 | ||||
-rw-r--r-- | kernel/fs.c | 63 | ||||
-rw-r--r-- | kernel/fs.h | 8 |
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. |