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:
parent
83a632b1b2
commit
b28eba04a8
3 changed files with 46 additions and 6 deletions
2
file.h
2
file.h
|
@ -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
44
fs.c
|
@ -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
6
fs.h
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue