Compare commits

..

1 commit

Author SHA1 Message Date
b28eba04a8 Incrase file size to around 8MB
Use 10 direct block numbers, 2 indirect block numbers and one double
indirect block number to increase the maximum file size to around 8MB.

Using this scheme, we can address a total of blocks
10 + 2 * 128 + 128 * 128 = 16650 blocks or just over 8MB.
2015-04-13 23:07:31 +05:30
3 changed files with 46 additions and 6 deletions

2
file.h
View file

@ -21,7 +21,7 @@ struct inode {
short minor; short minor;
short nlink; short nlink;
uint size; uint size;
uint addrs[NDIRECT+1]; uint addrs[NDIRECT+3];
}; };
#define I_BUSY 0x1 #define I_BUSY 0x1
#define I_VALID 0x2 #define I_VALID 0x2

44
fs.c
View file

@ -356,18 +356,25 @@ iunlockput(struct inode *ip)
static uint static uint
bmap(struct inode *ip, uint bn) bmap(struct inode *ip, uint bn)
{ {
uint addr, *a; uint addr, *a, i;
struct buf *bp; struct buf *bp;
// We use 10 direct, two indirect and one double indirect pointer
if(bn < NDIRECT){ if(bn < NDIRECT){
// If block number is less than direct pointers available
// allocate a disk block if not allocated/available
// then return the address of the block
if((addr = ip->addrs[bn]) == 0) if((addr = ip->addrs[bn]) == 0)
ip->addrs[bn] = addr = balloc(ip->dev); ip->addrs[bn] = addr = balloc(ip->dev);
return addr; return addr;
} }
// The block number does not fall in the first 10 direct blocks
// Substract the number from the passed block number
bn -= NDIRECT; bn -= NDIRECT;
if(bn < NINDIRECT){ if(bn < NINDIRECT){
// Load indirect block, allocating if necessary. // Load indirect block, allocating if necessary.
// This is the first indirect block range
if((addr = ip->addrs[NDIRECT]) == 0) if((addr = ip->addrs[NDIRECT]) == 0)
ip->addrs[NDIRECT] = addr = balloc(ip->dev); ip->addrs[NDIRECT] = addr = balloc(ip->dev);
bp = bread(ip->dev, addr); bp = bread(ip->dev, addr);
@ -378,6 +385,39 @@ bmap(struct inode *ip, uint bn)
} }
brelse(bp); brelse(bp);
return addr; return addr;
} else if(bn < NINDIRECT * 2){
bn -= NINDIRECT;
// Load indirect block, allocating if necessary.
// This is the second indirect block range
if((addr = ip->addrs[NDIRECT+1]) == 0)
ip->addrs[NDIRECT+1] = addr = balloc(ip->dev);
bp = bread(ip->dev, addr);
a = (uint*)bp->data;
if((addr = a[bn]) == 0){
a[bn] = addr = balloc(ip->dev);
log_write(bp);
}
brelse(bp);
return addr;
} else {
// We are now in the double indirect block range
bn -= NINDIRECT * 2;
// Load indirect block, allocating if necessary.
if((addr = ip->addrs[NDIRECT+2]) == 0)
ip->addrs[NDIRECT+2] = addr = balloc(ip->dev);
bp = bread(ip->dev, addr);
a = (uint*)bp->data;
// This last double indirect block should contain addresses to
// other blocks and not data. Fig 6.4 of xv6 booklet
for (i = 0; i < BSIZE/4; i++){
if((addr = a[i]) == 0){
a[bn] = addr = balloc(ip->dev);
log_write(bp);
break;
}
}
brelse(bp);
return addr;
} }
panic("bmap: out of range"); panic("bmap: out of range");
@ -401,7 +441,7 @@ itrunc(struct inode *ip)
ip->addrs[i] = 0; ip->addrs[i] = 0;
} }
} }
if(ip->addrs[NDIRECT]){ if(ip->addrs[NDIRECT]){
bp = bread(ip->dev, ip->addrs[NDIRECT]); bp = bread(ip->dev, ip->addrs[NDIRECT]);
a = (uint*)bp->data; a = (uint*)bp->data;

6
fs.h
View file

@ -19,9 +19,9 @@ struct superblock {
uint nlog; // Number of log blocks uint nlog; // Number of log blocks
}; };
#define NDIRECT 12 #define NDIRECT 10
#define NINDIRECT (BSIZE / sizeof(uint)) #define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT) #define MAXFILE (NDIRECT + 2 * NINDIRECT + NINDIRECT * NINDIRECT)
// On-disk inode structure // On-disk inode structure
struct dinode { struct dinode {
@ -30,7 +30,7 @@ struct dinode {
short minor; // Minor device number (T_DEV only) short minor; // Minor device number (T_DEV only)
short nlink; // Number of links to inode in file system short nlink; // Number of links to inode in file system
uint size; // Size of file (bytes) uint size; // Size of file (bytes)
uint addrs[NDIRECT+1]; // Data block addresses uint addrs[NDIRECT+3]; // Data block addresses
}; };
// Inodes per block. // Inodes per block.