1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| static uint bmap(struct inode *ip, uint bn) { uint addr, *a; struct buf *bp;
if(bn < NDIRECT) { if((addr = ip->addrs[bn]) == 0) ip->addrs[bn] = addr = balloc(ip->dev); return addr; } bn -= NDIRECT;
if(bn < NINDIRECT) { if((addr = ip->addrs[NDIRECT]) == 0) ip->addrs[NDIRECT] = 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; } bn -= NINDIRECT;
if(bn < NINDIRECT * NINDIRECT) { if((addr = ip->addrs[NDIRECT+1]) == 0) ip->addrs[NDIRECT+1] = addr = balloc(ip->dev); bp = bread(ip->dev, addr); a = (uint*)bp->data; uint first_idx = bn / NINDIRECT; uint second_idx = bn % NINDIRECT; if((addr = a[first_idx]) == 0) { a[first_idx] = addr = balloc(ip->dev); log_write(bp); } brelse(bp); bp = bread(ip->dev, addr); a = (uint*)bp->data; if((addr = a[second_idx]) == 0) { a[second_idx] = addr = balloc(ip->dev); log_write(bp); } brelse(bp); return addr; } panic("bmap: out of range"); return 0; }
void itrunc(struct inode *ip) { int i, j, k; struct buf *bp, *bp2; uint *a, *a2;
for(i = 0; i < NDIRECT; i++) { if(ip->addrs[i]) { bfree(ip->dev, ip->addrs[i]); ip->addrs[i] = 0; } }
if(ip->addrs[NDIRECT]) { bp = bread(ip->dev, ip->addrs[NDIRECT]); a = (uint*)bp->data; for(j = 0; j < NINDIRECT; j++) { if(a[j]) bfree(ip->dev, a[j]); } brelse(bp); bfree(ip->dev, ip->addrs[NDIRECT]); ip->addrs[NDIRECT] = 0; }
if(ip->addrs[NDIRECT+1]) { bp = bread(ip->dev, ip->addrs[NDIRECT+1]); a = (uint*)bp->data; for(j = 0; j < NINDIRECT; j++) { if(a[j]) { bp2 = bread(ip->dev, a[j]); a2 = (uint*)bp2->data; for(k = 0; k < NINDIRECT; k++) { if(a2[k]) bfree(ip->dev, a2[k]); } brelse(bp2); bfree(ip->dev, a[j]); } } brelse(bp); bfree(ip->dev, ip->addrs[NDIRECT+1]); ip->addrs[NDIRECT+1] = 0; }
ip->size = 0; iupdate(ip); }
|