1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)lfs_balloc.c 7.13 (Berkeley) 05/08/91 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "buf.h" 13 #include "proc.h" 14 #include "file.h" 15 #include "vnode.h" 16 17 #include "quota.h" 18 #include "inode.h" 19 #include "fs.h" 20 21 /* 22 * Bmap converts a the logical block number of a file 23 * to its physical block number on the disk. The conversion 24 * is done by using the logical block number to index into 25 * the array of block pointers described by the dinode. 26 */ 27 bmap(ip, bn, bnp) 28 register struct inode *ip; 29 register daddr_t bn; 30 daddr_t *bnp; 31 { 32 register struct fs *fs; 33 register daddr_t nb; 34 struct buf *bp; 35 daddr_t *bap; 36 int i, j, sh; 37 int error; 38 39 if (bn < 0) 40 return (EFBIG); 41 fs = ip->i_fs; 42 43 /* 44 * The first NDADDR blocks are direct blocks 45 */ 46 if (bn < NDADDR) { 47 nb = ip->i_db[bn]; 48 if (nb == 0) { 49 *bnp = (daddr_t)-1; 50 return (0); 51 } 52 *bnp = fsbtodb(fs, nb); 53 return (0); 54 } 55 /* 56 * Determine the number of levels of indirection. 57 */ 58 sh = 1; 59 bn -= NDADDR; 60 for (j = NIADDR; j > 0; j--) { 61 sh *= NINDIR(fs); 62 if (bn < sh) 63 break; 64 bn -= sh; 65 } 66 if (j == 0) 67 return (EFBIG); 68 /* 69 * Fetch through the indirect blocks. 70 */ 71 nb = ip->i_ib[NIADDR - j]; 72 if (nb == 0) { 73 *bnp = (daddr_t)-1; 74 return (0); 75 } 76 for (; j <= NIADDR; j++) { 77 if (error = bread(ip->i_devvp, fsbtodb(fs, nb), 78 (int)fs->fs_bsize, NOCRED, &bp)) { 79 brelse(bp); 80 return (error); 81 } 82 bap = bp->b_un.b_daddr; 83 sh /= NINDIR(fs); 84 i = (bn / sh) % NINDIR(fs); 85 nb = bap[i]; 86 if (nb == 0) { 87 *bnp = (daddr_t)-1; 88 brelse(bp); 89 return (0); 90 } 91 brelse(bp); 92 } 93 *bnp = fsbtodb(fs, nb); 94 return (0); 95 } 96 97 /* 98 * Balloc defines the structure of file system storage 99 * by allocating the physical blocks on a device given 100 * the inode and the logical block number in a file. 101 */ 102 balloc(ip, bn, size, bpp, flags) 103 register struct inode *ip; 104 register daddr_t bn; 105 int size; 106 struct buf **bpp; 107 int flags; 108 { 109 register struct fs *fs; 110 register daddr_t nb; 111 struct buf *bp, *nbp; 112 struct vnode *vp = ITOV(ip); 113 int osize, nsize, i, j, sh, error; 114 daddr_t newb, lbn, *bap, pref, blkpref(); 115 116 *bpp = (struct buf *)0; 117 if (bn < 0) 118 return (EFBIG); 119 fs = ip->i_fs; 120 121 /* 122 * If the next write will extend the file into a new block, 123 * and the file is currently composed of a fragment 124 * this fragment has to be extended to be a full block. 125 */ 126 nb = lblkno(fs, ip->i_size); 127 if (nb < NDADDR && nb < bn) { 128 osize = blksize(fs, ip, nb); 129 if (osize < fs->fs_bsize && osize > 0) { 130 error = realloccg(ip, nb, 131 blkpref(ip, nb, (int)nb, &ip->i_db[0]), 132 osize, (int)fs->fs_bsize, &bp); 133 if (error) 134 return (error); 135 ip->i_size = (nb + 1) * fs->fs_bsize; 136 vnode_pager_setsize(ITOV(ip), (u_long)ip->i_size); 137 ip->i_db[nb] = dbtofsb(fs, bp->b_blkno); 138 ip->i_flag |= IUPD|ICHG; 139 if (flags & B_SYNC) 140 bwrite(bp); 141 else 142 bawrite(bp); 143 } 144 } 145 /* 146 * The first NDADDR blocks are direct blocks 147 */ 148 if (bn < NDADDR) { 149 nb = ip->i_db[bn]; 150 if (nb != 0 && ip->i_size >= (bn + 1) * fs->fs_bsize) { 151 error = bread(vp, bn, fs->fs_bsize, NOCRED, &bp); 152 if (error) { 153 brelse(bp); 154 return (error); 155 } 156 *bpp = bp; 157 return (0); 158 } 159 if (nb != 0) { 160 /* 161 * Consider need to reallocate a fragment. 162 */ 163 osize = fragroundup(fs, blkoff(fs, ip->i_size)); 164 nsize = fragroundup(fs, size); 165 if (nsize <= osize) { 166 error = bread(vp, bn, osize, NOCRED, &bp); 167 if (error) { 168 brelse(bp); 169 return (error); 170 } 171 } else { 172 error = realloccg(ip, bn, 173 blkpref(ip, bn, (int)bn, &ip->i_db[0]), 174 osize, nsize, &bp); 175 if (error) 176 return (error); 177 } 178 } else { 179 if (ip->i_size < (bn + 1) * fs->fs_bsize) 180 nsize = fragroundup(fs, size); 181 else 182 nsize = fs->fs_bsize; 183 error = alloc(ip, bn, 184 blkpref(ip, bn, (int)bn, &ip->i_db[0]), 185 nsize, &newb); 186 if (error) 187 return (error); 188 bp = getblk(vp, bn, nsize); 189 bp->b_blkno = fsbtodb(fs, newb); 190 if (flags & B_CLRBUF) 191 clrbuf(bp); 192 } 193 ip->i_db[bn] = dbtofsb(fs, bp->b_blkno); 194 ip->i_flag |= IUPD|ICHG; 195 *bpp = bp; 196 return (0); 197 } 198 /* 199 * Determine the number of levels of indirection. 200 */ 201 pref = 0; 202 sh = 1; 203 lbn = bn; 204 bn -= NDADDR; 205 for (j = NIADDR; j > 0; j--) { 206 sh *= NINDIR(fs); 207 if (bn < sh) 208 break; 209 bn -= sh; 210 } 211 if (j == 0) 212 return (EFBIG); 213 /* 214 * Fetch the first indirect block allocating if necessary. 215 */ 216 nb = ip->i_ib[NIADDR - j]; 217 if (nb == 0) { 218 pref = blkpref(ip, lbn, 0, (daddr_t *)0); 219 if (error = alloc(ip, lbn, pref, (int)fs->fs_bsize, &newb)) 220 return (error); 221 nb = newb; 222 bp = getblk(ip->i_devvp, fsbtodb(fs, nb), fs->fs_bsize); 223 clrbuf(bp); 224 /* 225 * Write synchronously so that indirect blocks 226 * never point at garbage. 227 */ 228 if (error = bwrite(bp)) { 229 blkfree(ip, nb, fs->fs_bsize); 230 return (error); 231 } 232 ip->i_ib[NIADDR - j] = nb; 233 ip->i_flag |= IUPD|ICHG; 234 } 235 /* 236 * Fetch through the indirect blocks, allocating as necessary. 237 */ 238 for (; ; j++) { 239 error = bread(ip->i_devvp, fsbtodb(fs, nb), 240 (int)fs->fs_bsize, NOCRED, &bp); 241 if (error) { 242 brelse(bp); 243 return (error); 244 } 245 bap = bp->b_un.b_daddr; 246 sh /= NINDIR(fs); 247 i = (bn / sh) % NINDIR(fs); 248 nb = bap[i]; 249 if (j == NIADDR) 250 break; 251 if (nb != 0) { 252 brelse(bp); 253 continue; 254 } 255 if (pref == 0) 256 pref = blkpref(ip, lbn, 0, (daddr_t *)0); 257 if (error = alloc(ip, lbn, pref, (int)fs->fs_bsize, &newb)) { 258 brelse(bp); 259 return (error); 260 } 261 nb = newb; 262 nbp = getblk(ip->i_devvp, fsbtodb(fs, nb), fs->fs_bsize); 263 clrbuf(nbp); 264 /* 265 * Write synchronously so that indirect blocks 266 * never point at garbage. 267 */ 268 if (error = bwrite(nbp)) { 269 blkfree(ip, nb, fs->fs_bsize); 270 brelse(bp); 271 return (error); 272 } 273 bap[i] = nb; 274 /* 275 * If required, write synchronously, otherwise use 276 * delayed write. If this is the first instance of 277 * the delayed write, reassociate the buffer with the 278 * file so it will be written if the file is sync'ed. 279 */ 280 if (flags & B_SYNC) { 281 bwrite(bp); 282 } else if (bp->b_flags & B_DELWRI) { 283 bdwrite(bp); 284 } else { 285 bdwrite(bp); 286 reassignbuf(bp, vp); 287 } 288 } 289 /* 290 * Get the data block, allocating if necessary. 291 */ 292 if (nb == 0) { 293 pref = blkpref(ip, lbn, i, &bap[0]); 294 if (error = alloc(ip, lbn, pref, (int)fs->fs_bsize, &newb)) { 295 brelse(bp); 296 return (error); 297 } 298 nb = newb; 299 nbp = getblk(vp, lbn, fs->fs_bsize); 300 nbp->b_blkno = fsbtodb(fs, nb); 301 if (flags & B_CLRBUF) 302 clrbuf(nbp); 303 bap[i] = nb; 304 /* 305 * If required, write synchronously, otherwise use 306 * delayed write. If this is the first instance of 307 * the delayed write, reassociate the buffer with the 308 * file so it will be written if the file is sync'ed. 309 */ 310 if (flags & B_SYNC) { 311 bwrite(bp); 312 } else if (bp->b_flags & B_DELWRI) { 313 bdwrite(bp); 314 } else { 315 bdwrite(bp); 316 reassignbuf(bp, vp); 317 } 318 *bpp = nbp; 319 return (0); 320 } 321 brelse(bp); 322 if (flags & B_CLRBUF) { 323 error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp); 324 if (error) { 325 brelse(nbp); 326 return (error); 327 } 328 } else { 329 nbp = getblk(vp, lbn, fs->fs_bsize); 330 nbp->b_blkno = fsbtodb(fs, nb); 331 } 332 *bpp = nbp; 333 return (0); 334 } 335