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