diff options
author | Robert Morris <[email protected]> | 2022-08-10 06:13:52 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2022-08-10 06:13:52 -0400 |
commit | 872fa88e8afd24a8f228ba431fad380d326b0f36 (patch) | |
tree | 8577fd7cfd9067a34eb6b8a2b41925cabcd0d014 /kernel | |
parent | 7d573bae2ab70f0d0bd1807f0099c00e8f9e24f2 (diff) | |
download | xv6-labs-872fa88e8afd24a8f228ba431fad380d326b0f36.tar.gz xv6-labs-872fa88e8afd24a8f228ba431fad380d326b0f36.tar.bz2 xv6-labs-872fa88e8afd24a8f228ba431fad380d326b0f36.zip |
tolerate running out of disk blocks
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fs.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/kernel/fs.c b/kernel/fs.c index 40c9bd4..247a86f 100644 --- a/kernel/fs.c +++ b/kernel/fs.c @@ -61,6 +61,7 @@ bzero(int dev, int bno) // Blocks. // Allocate a zeroed disk block. +// returns 0 if out of disk space. static uint balloc(uint dev) { @@ -82,7 +83,8 @@ balloc(uint dev) } brelse(bp); } - panic("balloc: out of blocks"); + printf("balloc: out of blocks\n"); + return 0; } // Free a disk block. @@ -109,8 +111,8 @@ bfree(int dev, uint b) // its size, the number of links referring to it, and the // list of blocks holding the file's content. // -// The inodes are laid out sequentially on disk at -// sb.startinode. Each inode has a number, indicating its +// The inodes are laid out sequentially on disk at block +// sb.inodestart. Each inode has a number, indicating its // position on the disk. // // The kernel keeps a table of in-use inodes in memory @@ -374,6 +376,7 @@ iunlockput(struct inode *ip) // Return the disk block address of the nth block in inode ip. // If there is no such block, bmap allocates one. +// returns 0 if out of disk space. static uint bmap(struct inode *ip, uint bn) { @@ -381,21 +384,32 @@ bmap(struct inode *ip, uint bn) struct buf *bp; if(bn < NDIRECT){ - if((addr = ip->addrs[bn]) == 0) - ip->addrs[bn] = addr = balloc(ip->dev); + if((addr = ip->addrs[bn]) == 0){ + addr = balloc(ip->dev); + if(addr == 0) + return 0; + ip->addrs[bn] = addr; + } return addr; } bn -= NDIRECT; if(bn < NINDIRECT){ // Load indirect block, allocating if necessary. - if((addr = ip->addrs[NDIRECT]) == 0) - ip->addrs[NDIRECT] = addr = balloc(ip->dev); + if((addr = ip->addrs[NDIRECT]) == 0){ + addr = balloc(ip->dev); + if(addr == 0) + return 0; + ip->addrs[NDIRECT] = addr; + } bp = bread(ip->dev, addr); a = (uint*)bp->data; if((addr = a[bn]) == 0){ - a[bn] = addr = balloc(ip->dev); - log_write(bp); + addr = balloc(ip->dev); + if(addr){ + a[bn] = addr; + log_write(bp); + } } brelse(bp); return addr; @@ -464,7 +478,10 @@ readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n) n = ip->size - off; for(tot=0; tot<n; tot+=m, off+=m, dst+=m){ - bp = bread(ip->dev, bmap(ip, off/BSIZE)); + uint addr = bmap(ip, off/BSIZE); + if(addr == 0) + break; + bp = bread(ip->dev, addr); m = min(n - tot, BSIZE - off%BSIZE); if(either_copyout(user_dst, dst, bp->data + (off % BSIZE), m) == -1) { brelse(bp); @@ -495,7 +512,10 @@ writei(struct inode *ip, int user_src, uint64 src, uint off, uint n) return -1; for(tot=0; tot<n; tot+=m, off+=m, src+=m){ - bp = bread(ip->dev, bmap(ip, off/BSIZE)); + uint addr = bmap(ip, off/BSIZE); + if(addr == 0) + break; + bp = bread(ip->dev, addr); m = min(n - tot, BSIZE - off%BSIZE); if(either_copyin(bp->data + (off % BSIZE), user_src, src, m) == -1) { brelse(bp); |