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.
This commit is contained in:
Sanchayan Maity 2015-04-13 23:07:31 +05:30
parent 83a632b1b2
commit b28eba04a8
3 changed files with 46 additions and 6 deletions

2
file.h
View File

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

44
fs.c
View File

@ -356,18 +356,25 @@ iunlockput(struct inode *ip)
static uint
bmap(struct inode *ip, uint bn)
{
uint addr, *a;
uint addr, *a, i;
struct buf *bp;
// We use 10 direct, two indirect and one double indirect pointer
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)
ip->addrs[bn] = addr = balloc(ip->dev);
return addr;
}
// The block number does not fall in the first 10 direct blocks
// Substract the number from the passed block number
bn -= NDIRECT;
if(bn < NINDIRECT){
// Load indirect block, allocating if necessary.
// This is the first indirect block range
if((addr = ip->addrs[NDIRECT]) == 0)
ip->addrs[NDIRECT] = addr = balloc(ip->dev);
bp = bread(ip->dev, addr);
@ -378,6 +385,39 @@ bmap(struct inode *ip, uint bn)
}
brelse(bp);
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");
@ -401,7 +441,7 @@ itrunc(struct inode *ip)
ip->addrs[i] = 0;
}
}
if(ip->addrs[NDIRECT]){
bp = bread(ip->dev, ip->addrs[NDIRECT]);
a = (uint*)bp->data;

6
fs.h
View File

@ -19,9 +19,9 @@ struct superblock {
uint nlog; // Number of log blocks
};
#define NDIRECT 12
#define NDIRECT 10
#define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT)
#define MAXFILE (NDIRECT + 2 * NINDIRECT + NINDIRECT * NINDIRECT)
// On-disk inode structure
struct dinode {
@ -30,7 +30,7 @@ struct dinode {
short minor; // Minor device number (T_DEV 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+3]; // Data block addresses
};
// Inodes per block.