From b28eba04a807b8366a1d58701b1b1de713e18930 Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Mon, 13 Apr 2015 23:07:31 +0530 Subject: [PATCH] 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. --- file.h | 2 +- fs.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- fs.h | 6 +++--- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/file.h b/file.h index c02f76c..0595ab7 100644 --- a/file.h +++ b/file.h @@ -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 diff --git a/fs.c b/fs.c index 9d6dfd1..054e4fc 100644 --- a/fs.c +++ b/fs.c @@ -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; diff --git a/fs.h b/fs.h index f191d43..970d829 100644 --- a/fs.h +++ b/fs.h @@ -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.