ffs_balloc.c revision 1.33.2.3 1 /* $NetBSD: ffs_balloc.c,v 1.33.2.3 2004/09/18 14:56:52 skrll Exp $ */
2
3 /*
4 * Copyright (c) 2002 Networks Associates Technology, Inc.
5 * All rights reserved.
6 *
7 * This software was developed for the FreeBSD Project by Marshall
8 * Kirk McKusick and Network Associates Laboratories, the Security
9 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
10 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
11 * research program
12 *
13 * Copyright (c) 1982, 1986, 1989, 1993
14 * The Regents of the University of California. All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95
41 */
42
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: ffs_balloc.c,v 1.33.2.3 2004/09/18 14:56:52 skrll Exp $");
45
46 #if defined(_KERNEL_OPT)
47 #include "opt_quota.h"
48 #endif
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/buf.h>
53 #include <sys/file.h>
54 #include <sys/mount.h>
55 #include <sys/vnode.h>
56 #include <sys/mount.h>
57
58 #include <ufs/ufs/quota.h>
59 #include <ufs/ufs/ufsmount.h>
60 #include <ufs/ufs/inode.h>
61 #include <ufs/ufs/ufs_extern.h>
62 #include <ufs/ufs/ufs_bswap.h>
63
64 #include <ufs/ffs/fs.h>
65 #include <ufs/ffs/ffs_extern.h>
66
67 #include <uvm/uvm.h>
68
69 static int ffs_balloc_ufs1(void *);
70 static int ffs_balloc_ufs2(void *);
71
72 /*
73 * Balloc defines the structure of file system storage
74 * by allocating the physical blocks on a device given
75 * the inode and the logical block number in a file.
76 */
77
78 int
79 ffs_balloc(v)
80 void *v;
81 {
82 struct vop_balloc_args *ap = v;
83
84 if (VTOI(ap->a_vp)->i_fs->fs_magic == FS_UFS2_MAGIC)
85 return ffs_balloc_ufs2(v);
86 else
87 return ffs_balloc_ufs1(v);
88 }
89
90 static int
91 ffs_balloc_ufs1(v)
92 void *v;
93 {
94 struct vop_balloc_args /* {
95 struct vnode *a_vp;
96 off_t a_startoffset;
97 int a_size;
98 struct ucred *a_cred;
99 int a_flags;
100 struct buf **a_bpp;
101 } */ *ap = v;
102 daddr_t lbn, lastlbn;
103 int size;
104 struct ucred *cred;
105 int flags;
106 int32_t nb;
107 struct buf *bp, *nbp;
108 struct vnode *vp = ap->a_vp;
109 struct inode *ip = VTOI(vp);
110 struct fs *fs = ip->i_fs;
111 struct indir indirs[NIADDR + 2];
112 daddr_t newb, pref;
113 int32_t *bap; /* XXX ondisk32 */
114 int deallocated, osize, nsize, num, i, error;
115 int32_t *blkp, *allocblk, allociblk[NIADDR + 1];
116 int32_t *allocib;
117 int unwindidx = -1;
118 struct buf **bpp = ap->a_bpp;
119 #ifdef FFS_EI
120 const int needswap = UFS_FSNEEDSWAP(fs);
121 #endif
122 UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist);
123
124 lbn = lblkno(fs, ap->a_startoffset);
125 size = blkoff(fs, ap->a_startoffset) + ap->a_size;
126 if (size > fs->fs_bsize)
127 panic("ffs_balloc: blk too big");
128 if (bpp != NULL) {
129 *bpp = NULL;
130 }
131 UVMHIST_LOG(ubchist, "vp %p lbn 0x%x size 0x%x", vp, lbn, size,0);
132
133 KASSERT(size <= fs->fs_bsize);
134 if (lbn < 0)
135 return (EFBIG);
136 cred = ap->a_cred;
137 flags = ap->a_flags;
138
139 /*
140 * If the next write will extend the file into a new block,
141 * and the file is currently composed of a fragment
142 * this fragment has to be extended to be a full block.
143 */
144
145 lastlbn = lblkno(fs, ip->i_size);
146 if (lastlbn < NDADDR && lastlbn < lbn) {
147 nb = lastlbn;
148 osize = blksize(fs, ip, nb);
149 if (osize < fs->fs_bsize && osize > 0) {
150 error = ffs_realloccg(ip, nb,
151 ffs_blkpref_ufs1(ip, lastlbn, nb,
152 &ip->i_ffs1_db[0]),
153 osize, (int)fs->fs_bsize, cred, bpp, &newb);
154 if (error)
155 return (error);
156 if (DOINGSOFTDEP(vp))
157 softdep_setup_allocdirect(ip, nb, newb,
158 ufs_rw32(ip->i_ffs1_db[nb], needswap),
159 fs->fs_bsize, osize, bpp ? *bpp : NULL);
160 ip->i_size = lblktosize(fs, nb + 1);
161 ip->i_ffs1_size = ip->i_size;
162 uvm_vnp_setsize(vp, ip->i_ffs1_size);
163 ip->i_ffs1_db[nb] = ufs_rw32((int32_t)newb, needswap);
164 ip->i_flag |= IN_CHANGE | IN_UPDATE;
165 if (bpp) {
166 if (flags & B_SYNC)
167 bwrite(*bpp);
168 else
169 bawrite(*bpp);
170 }
171 }
172 }
173
174 /*
175 * The first NDADDR blocks are direct blocks
176 */
177
178 if (lbn < NDADDR) {
179 nb = ufs_rw32(ip->i_ffs1_db[lbn], needswap);
180 if (nb != 0 && ip->i_size >= lblktosize(fs, lbn + 1)) {
181
182 /*
183 * The block is an already-allocated direct block
184 * and the file already extends past this block,
185 * thus this must be a whole block.
186 * Just read the block (if requested).
187 */
188
189 if (bpp != NULL) {
190 error = bread(vp, lbn, fs->fs_bsize, NOCRED,
191 bpp);
192 if (error) {
193 brelse(*bpp);
194 return (error);
195 }
196 }
197 return (0);
198 }
199 if (nb != 0) {
200
201 /*
202 * Consider need to reallocate a fragment.
203 */
204
205 osize = fragroundup(fs, blkoff(fs, ip->i_size));
206 nsize = fragroundup(fs, size);
207 if (nsize <= osize) {
208
209 /*
210 * The existing block is already
211 * at least as big as we want.
212 * Just read the block (if requested).
213 */
214
215 if (bpp != NULL) {
216 error = bread(vp, lbn, osize, NOCRED,
217 bpp);
218 if (error) {
219 brelse(*bpp);
220 return (error);
221 }
222 }
223 return 0;
224 } else {
225
226 /*
227 * The existing block is smaller than we want,
228 * grow it.
229 */
230
231 error = ffs_realloccg(ip, lbn,
232 ffs_blkpref_ufs1(ip, lbn, (int)lbn,
233 &ip->i_ffs1_db[0]), osize, nsize, cred,
234 bpp, &newb);
235 if (error)
236 return (error);
237 if (DOINGSOFTDEP(vp))
238 softdep_setup_allocdirect(ip, lbn,
239 newb, nb, nsize, osize,
240 bpp ? *bpp : NULL);
241 }
242 } else {
243
244 /*
245 * the block was not previously allocated,
246 * allocate a new block or fragment.
247 */
248
249 if (ip->i_size < lblktosize(fs, lbn + 1))
250 nsize = fragroundup(fs, size);
251 else
252 nsize = fs->fs_bsize;
253 error = ffs_alloc(ip, lbn,
254 ffs_blkpref_ufs1(ip, lbn, (int)lbn,
255 &ip->i_ffs1_db[0]),
256 nsize, cred, &newb);
257 if (error)
258 return (error);
259 if (bpp != NULL) {
260 bp = getblk(vp, lbn, nsize, 0, 0);
261 bp->b_blkno = fsbtodb(fs, newb);
262 if (flags & B_CLRBUF)
263 clrbuf(bp);
264 *bpp = bp;
265 }
266 if (DOINGSOFTDEP(vp)) {
267 softdep_setup_allocdirect(ip, lbn, newb, 0,
268 nsize, 0, bpp ? *bpp : NULL);
269 }
270 }
271 ip->i_ffs1_db[lbn] = ufs_rw32((int32_t)newb, needswap);
272 ip->i_flag |= IN_CHANGE | IN_UPDATE;
273 return (0);
274 }
275
276 /*
277 * Determine the number of levels of indirection.
278 */
279
280 pref = 0;
281 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
282 return (error);
283
284 /*
285 * Fetch the first indirect block allocating if necessary.
286 */
287
288 --num;
289 nb = ufs_rw32(ip->i_ffs1_ib[indirs[0].in_off], needswap);
290 allocib = NULL;
291 allocblk = allociblk;
292 if (nb == 0) {
293 pref = ffs_blkpref_ufs1(ip, lbn, 0, (int32_t *)0);
294 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
295 &newb);
296 if (error)
297 goto fail;
298 nb = newb;
299 *allocblk++ = nb;
300 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0);
301 bp->b_blkno = fsbtodb(fs, nb);
302 clrbuf(bp);
303 if (DOINGSOFTDEP(vp)) {
304 softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off,
305 newb, 0, fs->fs_bsize, 0, bp);
306 bdwrite(bp);
307 } else {
308
309 /*
310 * Write synchronously so that indirect blocks
311 * never point at garbage.
312 */
313
314 if ((error = bwrite(bp)) != 0)
315 goto fail;
316 }
317 unwindidx = 0;
318 allocib = &ip->i_ffs1_ib[indirs[0].in_off];
319 *allocib = ufs_rw32(nb, needswap);
320 ip->i_flag |= IN_CHANGE | IN_UPDATE;
321 }
322
323 /*
324 * Fetch through the indirect blocks, allocating as necessary.
325 */
326
327 for (i = 1;;) {
328 error = bread(vp,
329 indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
330 if (error) {
331 brelse(bp);
332 goto fail;
333 }
334 bap = (int32_t *)bp->b_data; /* XXX ondisk32 */
335 nb = ufs_rw32(bap[indirs[i].in_off], needswap);
336 if (i == num)
337 break;
338 i++;
339 if (nb != 0) {
340 brelse(bp);
341 continue;
342 }
343 if (pref == 0)
344 pref = ffs_blkpref_ufs1(ip, lbn, 0, (int32_t *)0);
345 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
346 &newb);
347 if (error) {
348 brelse(bp);
349 goto fail;
350 }
351 nb = newb;
352 *allocblk++ = nb;
353 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0);
354 nbp->b_blkno = fsbtodb(fs, nb);
355 clrbuf(nbp);
356 if (DOINGSOFTDEP(vp)) {
357 softdep_setup_allocindir_meta(nbp, ip, bp,
358 indirs[i - 1].in_off, nb);
359 bdwrite(nbp);
360 } else {
361
362 /*
363 * Write synchronously so that indirect blocks
364 * never point at garbage.
365 */
366
367 if ((error = bwrite(nbp)) != 0) {
368 brelse(bp);
369 goto fail;
370 }
371 }
372 if (unwindidx < 0)
373 unwindidx = i - 1;
374 bap[indirs[i - 1].in_off] = ufs_rw32(nb, needswap);
375
376 /*
377 * If required, write synchronously, otherwise use
378 * delayed write.
379 */
380
381 if (flags & B_SYNC) {
382 bwrite(bp);
383 } else {
384 bdwrite(bp);
385 }
386 }
387
388 if (flags & B_METAONLY) {
389 *bpp = bp;
390 return (0);
391 }
392
393 /*
394 * Get the data block, allocating if necessary.
395 */
396
397 if (nb == 0) {
398 pref = ffs_blkpref_ufs1(ip, lbn, indirs[num].in_off, &bap[0]);
399 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
400 &newb);
401 if (error) {
402 brelse(bp);
403 goto fail;
404 }
405 nb = newb;
406 *allocblk++ = nb;
407 if (bpp != NULL) {
408 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
409 nbp->b_blkno = fsbtodb(fs, nb);
410 if (flags & B_CLRBUF)
411 clrbuf(nbp);
412 *bpp = nbp;
413 }
414 if (DOINGSOFTDEP(vp))
415 softdep_setup_allocindir_page(ip, lbn, bp,
416 indirs[num].in_off, nb, 0, bpp ? *bpp : NULL);
417 bap[indirs[num].in_off] = ufs_rw32(nb, needswap);
418 if (allocib == NULL && unwindidx < 0) {
419 unwindidx = i - 1;
420 }
421
422 /*
423 * If required, write synchronously, otherwise use
424 * delayed write.
425 */
426
427 if (flags & B_SYNC) {
428 bwrite(bp);
429 } else {
430 bdwrite(bp);
431 }
432 return (0);
433 }
434 brelse(bp);
435 if (bpp != NULL) {
436 if (flags & B_CLRBUF) {
437 error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
438 if (error) {
439 brelse(nbp);
440 goto fail;
441 }
442 } else {
443 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
444 nbp->b_blkno = fsbtodb(fs, nb);
445 clrbuf(nbp);
446 }
447 *bpp = nbp;
448 }
449 return (0);
450
451 fail:
452 /*
453 * If we have failed part way through block allocation, we
454 * have to deallocate any indirect blocks that we have allocated.
455 */
456
457 if (unwindidx >= 0) {
458
459 /*
460 * First write out any buffers we've created to resolve their
461 * softdeps. This must be done in reverse order of creation
462 * so that we resolve the dependencies in one pass.
463 * Write the cylinder group buffers for these buffers too.
464 */
465
466 for (i = num; i >= unwindidx; i--) {
467 if (i == 0) {
468 break;
469 }
470 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0,
471 0);
472 if (bp->b_flags & B_DELWRI) {
473 nb = fsbtodb(fs, cgtod(fs, dtog(fs,
474 dbtofsb(fs, bp->b_blkno))));
475 bwrite(bp);
476 bp = getblk(ip->i_devvp, nb, (int)fs->fs_cgsize,
477 0, 0);
478 if (bp->b_flags & B_DELWRI) {
479 bwrite(bp);
480 } else {
481 bp->b_flags |= B_INVAL;
482 brelse(bp);
483 }
484 } else {
485 bp->b_flags |= B_INVAL;
486 brelse(bp);
487 }
488 }
489 if (DOINGSOFTDEP(vp) && unwindidx == 0) {
490 ip->i_flag |= IN_CHANGE | IN_UPDATE;
491 VOP_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
492 }
493
494 /*
495 * Now that any dependencies that we created have been
496 * resolved, we can undo the partial allocation.
497 */
498
499 if (unwindidx == 0) {
500 *allocib = 0;
501 ip->i_flag |= IN_CHANGE | IN_UPDATE;
502 if (DOINGSOFTDEP(vp))
503 VOP_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
504 } else {
505 int r;
506
507 r = bread(vp, indirs[unwindidx].in_lbn,
508 (int)fs->fs_bsize, NOCRED, &bp);
509 if (r) {
510 panic("Could not unwind indirect block, error %d", r);
511 brelse(bp);
512 } else {
513 bap = (int32_t *)bp->b_data; /* XXX ondisk32 */
514 bap[indirs[unwindidx].in_off] = 0;
515 bwrite(bp);
516 }
517 }
518 for (i = unwindidx + 1; i <= num; i++) {
519 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0,
520 0);
521 bp->b_flags |= B_INVAL;
522 brelse(bp);
523 }
524 }
525 for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {
526 ffs_blkfree(fs, ip->i_devvp, *blkp, fs->fs_bsize, ip->i_number);
527 deallocated += fs->fs_bsize;
528 }
529 if (deallocated) {
530 #ifdef QUOTA
531 /*
532 * Restore user's disk quota because allocation failed.
533 */
534 (void)chkdq(ip, -btodb(deallocated), cred, FORCE);
535 #endif
536 ip->i_ffs1_blocks -= btodb(deallocated);
537 ip->i_flag |= IN_CHANGE | IN_UPDATE;
538 }
539 return (error);
540 }
541
542 static int
543 ffs_balloc_ufs2(v)
544 void *v;
545 {
546 struct vop_balloc_args /* {
547 struct vnode *a_vp;
548 off_t a_startoffset;
549 int a_size;
550 struct ucred *a_cred;
551 int a_flags;
552 struct buf **a_bpp;
553 } */ *ap = v;
554 daddr_t lbn, lastlbn;
555 int size;
556 struct ucred *cred;
557 int flags;
558 struct buf *bp, *nbp;
559 struct vnode *vp = ap->a_vp;
560 struct inode *ip = VTOI(vp);
561 struct fs *fs = ip->i_fs;
562 struct indir indirs[NIADDR + 2];
563 daddr_t newb, pref, nb;
564 int64_t *bap;
565 int deallocated, osize, nsize, num, i, error;
566 daddr_t *blkp, *allocblk, allociblk[NIADDR + 1];
567 int64_t *allocib;
568 int unwindidx = -1;
569 struct buf **bpp = ap->a_bpp;
570 #ifdef FFS_EI
571 const int needswap = UFS_FSNEEDSWAP(fs);
572 #endif
573 UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist);
574
575 lbn = lblkno(fs, ap->a_startoffset);
576 size = blkoff(fs, ap->a_startoffset) + ap->a_size;
577 if (size > fs->fs_bsize)
578 panic("ffs_balloc: blk too big");
579 if (bpp != NULL) {
580 *bpp = NULL;
581 }
582 UVMHIST_LOG(ubchist, "vp %p lbn 0x%x size 0x%x", vp, lbn, size,0);
583
584 KASSERT(size <= fs->fs_bsize);
585 if (lbn < 0)
586 return (EFBIG);
587 cred = ap->a_cred;
588 flags = ap->a_flags;
589
590 #ifdef notyet
591 /*
592 * Check for allocating external data.
593 */
594 if (flags & IO_EXT) {
595 if (lbn >= NXADDR)
596 return (EFBIG);
597 /*
598 * If the next write will extend the data into a new block,
599 * and the data is currently composed of a fragment
600 * this fragment has to be extended to be a full block.
601 */
602 lastlbn = lblkno(fs, dp->di_extsize);
603 if (lastlbn < lbn) {
604 nb = lastlbn;
605 osize = sblksize(fs, dp->di_extsize, nb);
606 if (osize < fs->fs_bsize && osize > 0) {
607 error = ffs_realloccg(ip, -1 - nb,
608 dp->di_extb[nb],
609 ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
610 &dp->di_extb[0]), osize,
611 (int)fs->fs_bsize, cred, &bp);
612 if (error)
613 return (error);
614 if (DOINGSOFTDEP(vp))
615 softdep_setup_allocext(ip, nb,
616 dbtofsb(fs, bp->b_blkno),
617 dp->di_extb[nb],
618 fs->fs_bsize, osize, bp);
619 dp->di_extsize = smalllblktosize(fs, nb + 1);
620 dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno);
621 bp->b_xflags |= BX_ALTDATA;
622 ip->i_flag |= IN_CHANGE | IN_UPDATE;
623 if (flags & IO_SYNC)
624 bwrite(bp);
625 else
626 bawrite(bp);
627 }
628 }
629 /*
630 * All blocks are direct blocks
631 */
632 if (flags & BA_METAONLY)
633 panic("ffs_balloc_ufs2: BA_METAONLY for ext block");
634 nb = dp->di_extb[lbn];
635 if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) {
636 error = bread(vp, -1 - lbn, fs->fs_bsize, NOCRED, &bp);
637 if (error) {
638 brelse(bp);
639 return (error);
640 }
641 bp->b_blkno = fsbtodb(fs, nb);
642 bp->b_xflags |= BX_ALTDATA;
643 *bpp = bp;
644 return (0);
645 }
646 if (nb != 0) {
647 /*
648 * Consider need to reallocate a fragment.
649 */
650 osize = fragroundup(fs, blkoff(fs, dp->di_extsize));
651 nsize = fragroundup(fs, size);
652 if (nsize <= osize) {
653 error = bread(vp, -1 - lbn, osize, NOCRED, &bp);
654 if (error) {
655 brelse(bp);
656 return (error);
657 }
658 bp->b_blkno = fsbtodb(fs, nb);
659 bp->b_xflags |= BX_ALTDATA;
660 } else {
661 error = ffs_realloccg(ip, -1 - lbn,
662 dp->di_extb[lbn],
663 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
664 &dp->di_extb[0]), osize, nsize, cred, &bp);
665 if (error)
666 return (error);
667 bp->b_xflags |= BX_ALTDATA;
668 if (DOINGSOFTDEP(vp))
669 softdep_setup_allocext(ip, lbn,
670 dbtofsb(fs, bp->b_blkno), nb,
671 nsize, osize, bp);
672 }
673 } else {
674 if (dp->di_extsize < smalllblktosize(fs, lbn + 1))
675 nsize = fragroundup(fs, size);
676 else
677 nsize = fs->fs_bsize;
678 error = ffs_alloc(ip, lbn,
679 ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]),
680 nsize, cred, &newb);
681 if (error)
682 return (error);
683 bp = getblk(vp, -1 - lbn, nsize, 0, 0);
684 bp->b_blkno = fsbtodb(fs, newb);
685 bp->b_xflags |= BX_ALTDATA;
686 if (flags & BA_CLRBUF)
687 vfs_bio_clrbuf(bp);
688 if (DOINGSOFTDEP(vp))
689 softdep_setup_allocext(ip, lbn, newb, 0,
690 nsize, 0, bp);
691 }
692 dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
693 ip->i_flag |= IN_CHANGE | IN_UPDATE;
694 *bpp = bp;
695 return (0);
696 }
697 #endif
698 /*
699 * If the next write will extend the file into a new block,
700 * and the file is currently composed of a fragment
701 * this fragment has to be extended to be a full block.
702 */
703
704 lastlbn = lblkno(fs, ip->i_size);
705 if (lastlbn < NDADDR && lastlbn < lbn) {
706 nb = lastlbn;
707 osize = blksize(fs, ip, nb);
708 if (osize < fs->fs_bsize && osize > 0) {
709 error = ffs_realloccg(ip, nb,
710 ffs_blkpref_ufs2(ip, lastlbn, nb,
711 &ip->i_ffs2_db[0]),
712 osize, (int)fs->fs_bsize, cred, bpp, &newb);
713 if (error)
714 return (error);
715 if (DOINGSOFTDEP(vp))
716 softdep_setup_allocdirect(ip, nb, newb,
717 ufs_rw64(ip->i_ffs2_db[nb], needswap),
718 fs->fs_bsize, osize, bpp ? *bpp : NULL);
719 ip->i_size = lblktosize(fs, nb + 1);
720 ip->i_ffs2_size = ip->i_size;
721 uvm_vnp_setsize(vp, ip->i_size);
722 ip->i_ffs2_db[nb] = ufs_rw64(newb, needswap);
723 ip->i_flag |= IN_CHANGE | IN_UPDATE;
724 if (bpp) {
725 if (flags & B_SYNC)
726 bwrite(*bpp);
727 else
728 bawrite(*bpp);
729 }
730 }
731 }
732
733 /*
734 * The first NDADDR blocks are direct blocks
735 */
736
737 if (lbn < NDADDR) {
738 nb = ufs_rw64(ip->i_ffs2_db[lbn], needswap);
739 if (nb != 0 && ip->i_size >= lblktosize(fs, lbn + 1)) {
740
741 /*
742 * The block is an already-allocated direct block
743 * and the file already extends past this block,
744 * thus this must be a whole block.
745 * Just read the block (if requested).
746 */
747
748 if (bpp != NULL) {
749 error = bread(vp, lbn, fs->fs_bsize, NOCRED,
750 bpp);
751 if (error) {
752 brelse(*bpp);
753 return (error);
754 }
755 }
756 return (0);
757 }
758 if (nb != 0) {
759
760 /*
761 * Consider need to reallocate a fragment.
762 */
763
764 osize = fragroundup(fs, blkoff(fs, ip->i_size));
765 nsize = fragroundup(fs, size);
766 if (nsize <= osize) {
767
768 /*
769 * The existing block is already
770 * at least as big as we want.
771 * Just read the block (if requested).
772 */
773
774 if (bpp != NULL) {
775 error = bread(vp, lbn, osize, NOCRED,
776 bpp);
777 if (error) {
778 brelse(*bpp);
779 return (error);
780 }
781 }
782 return 0;
783 } else {
784
785 /*
786 * The existing block is smaller than we want,
787 * grow it.
788 */
789
790 error = ffs_realloccg(ip, lbn,
791 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
792 &ip->i_ffs2_db[0]), osize, nsize, cred,
793 bpp, &newb);
794 if (error)
795 return (error);
796 if (DOINGSOFTDEP(vp))
797 softdep_setup_allocdirect(ip, lbn,
798 newb, nb, nsize, osize,
799 bpp ? *bpp : NULL);
800 }
801 } else {
802
803 /*
804 * the block was not previously allocated,
805 * allocate a new block or fragment.
806 */
807
808 if (ip->i_size < lblktosize(fs, lbn + 1))
809 nsize = fragroundup(fs, size);
810 else
811 nsize = fs->fs_bsize;
812 error = ffs_alloc(ip, lbn,
813 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
814 &ip->i_ffs2_db[0]), nsize, cred, &newb);
815 if (error)
816 return (error);
817 if (bpp != NULL) {
818 bp = getblk(vp, lbn, nsize, 0, 0);
819 bp->b_blkno = fsbtodb(fs, newb);
820 if (flags & B_CLRBUF)
821 clrbuf(bp);
822 *bpp = bp;
823 }
824 if (DOINGSOFTDEP(vp)) {
825 softdep_setup_allocdirect(ip, lbn, newb, 0,
826 nsize, 0, bpp ? *bpp : NULL);
827 }
828 }
829 ip->i_ffs2_db[lbn] = ufs_rw64(newb, needswap);
830 ip->i_flag |= IN_CHANGE | IN_UPDATE;
831 return (0);
832 }
833
834 /*
835 * Determine the number of levels of indirection.
836 */
837
838 pref = 0;
839 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
840 return (error);
841
842 /*
843 * Fetch the first indirect block allocating if necessary.
844 */
845
846 --num;
847 nb = ufs_rw64(ip->i_ffs2_ib[indirs[0].in_off], needswap);
848 allocib = NULL;
849 allocblk = allociblk;
850 if (nb == 0) {
851 pref = ffs_blkpref_ufs2(ip, lbn, 0, (int64_t *)0);
852 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
853 &newb);
854 if (error)
855 goto fail;
856 nb = newb;
857 *allocblk++ = nb;
858 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0);
859 bp->b_blkno = fsbtodb(fs, nb);
860 clrbuf(bp);
861 if (DOINGSOFTDEP(vp)) {
862 softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off,
863 newb, 0, fs->fs_bsize, 0, bp);
864 bdwrite(bp);
865 } else {
866
867 /*
868 * Write synchronously so that indirect blocks
869 * never point at garbage.
870 */
871
872 if ((error = bwrite(bp)) != 0)
873 goto fail;
874 }
875 unwindidx = 0;
876 allocib = &ip->i_ffs2_ib[indirs[0].in_off];
877 *allocib = ufs_rw64(nb, needswap);
878 ip->i_flag |= IN_CHANGE | IN_UPDATE;
879 }
880
881 /*
882 * Fetch through the indirect blocks, allocating as necessary.
883 */
884
885 for (i = 1;;) {
886 error = bread(vp,
887 indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
888 if (error) {
889 brelse(bp);
890 goto fail;
891 }
892 bap = (int64_t *)bp->b_data;
893 nb = ufs_rw64(bap[indirs[i].in_off], needswap);
894 if (i == num)
895 break;
896 i++;
897 if (nb != 0) {
898 brelse(bp);
899 continue;
900 }
901 if (pref == 0)
902 pref = ffs_blkpref_ufs2(ip, lbn, 0, (int64_t *)0);
903 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
904 &newb);
905 if (error) {
906 brelse(bp);
907 goto fail;
908 }
909 nb = newb;
910 *allocblk++ = nb;
911 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0);
912 nbp->b_blkno = fsbtodb(fs, nb);
913 clrbuf(nbp);
914 if (DOINGSOFTDEP(vp)) {
915 softdep_setup_allocindir_meta(nbp, ip, bp,
916 indirs[i - 1].in_off, nb);
917 bdwrite(nbp);
918 } else {
919
920 /*
921 * Write synchronously so that indirect blocks
922 * never point at garbage.
923 */
924
925 if ((error = bwrite(nbp)) != 0) {
926 brelse(bp);
927 goto fail;
928 }
929 }
930 if (unwindidx < 0)
931 unwindidx = i - 1;
932 bap[indirs[i - 1].in_off] = ufs_rw64(nb, needswap);
933
934 /*
935 * If required, write synchronously, otherwise use
936 * delayed write.
937 */
938
939 if (flags & B_SYNC) {
940 bwrite(bp);
941 } else {
942 bdwrite(bp);
943 }
944 }
945
946 if (flags & B_METAONLY) {
947 *bpp = bp;
948 return (0);
949 }
950
951 /*
952 * Get the data block, allocating if necessary.
953 */
954
955 if (nb == 0) {
956 pref = ffs_blkpref_ufs2(ip, lbn, indirs[num].in_off, &bap[0]);
957 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
958 &newb);
959 if (error) {
960 brelse(bp);
961 goto fail;
962 }
963 nb = newb;
964 *allocblk++ = nb;
965 if (bpp != NULL) {
966 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
967 nbp->b_blkno = fsbtodb(fs, nb);
968 if (flags & B_CLRBUF)
969 clrbuf(nbp);
970 *bpp = nbp;
971 }
972 if (DOINGSOFTDEP(vp))
973 softdep_setup_allocindir_page(ip, lbn, bp,
974 indirs[num].in_off, nb, 0, bpp ? *bpp : NULL);
975 bap[indirs[num].in_off] = ufs_rw64(nb, needswap);
976 if (allocib == NULL && unwindidx < 0) {
977 unwindidx = i - 1;
978 }
979
980 /*
981 * If required, write synchronously, otherwise use
982 * delayed write.
983 */
984
985 if (flags & B_SYNC) {
986 bwrite(bp);
987 } else {
988 bdwrite(bp);
989 }
990 return (0);
991 }
992 brelse(bp);
993 if (bpp != NULL) {
994 if (flags & B_CLRBUF) {
995 error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
996 if (error) {
997 brelse(nbp);
998 goto fail;
999 }
1000 } else {
1001 nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
1002 nbp->b_blkno = fsbtodb(fs, nb);
1003 clrbuf(nbp);
1004 }
1005 *bpp = nbp;
1006 }
1007 return (0);
1008
1009 fail:
1010 /*
1011 * If we have failed part way through block allocation, we
1012 * have to deallocate any indirect blocks that we have allocated.
1013 */
1014
1015 if (unwindidx >= 0) {
1016
1017 /*
1018 * First write out any buffers we've created to resolve their
1019 * softdeps. This must be done in reverse order of creation
1020 * so that we resolve the dependencies in one pass.
1021 * Write the cylinder group buffers for these buffers too.
1022 */
1023
1024 for (i = num; i >= unwindidx; i--) {
1025 if (i == 0) {
1026 break;
1027 }
1028 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0,
1029 0);
1030 if (bp->b_flags & B_DELWRI) {
1031 nb = fsbtodb(fs, cgtod(fs, dtog(fs,
1032 dbtofsb(fs, bp->b_blkno))));
1033 bwrite(bp);
1034 bp = getblk(ip->i_devvp, nb, (int)fs->fs_cgsize,
1035 0, 0);
1036 if (bp->b_flags & B_DELWRI) {
1037 bwrite(bp);
1038 } else {
1039 bp->b_flags |= B_INVAL;
1040 brelse(bp);
1041 }
1042 } else {
1043 bp->b_flags |= B_INVAL;
1044 brelse(bp);
1045 }
1046 }
1047 if (DOINGSOFTDEP(vp) && unwindidx == 0) {
1048 ip->i_flag |= IN_CHANGE | IN_UPDATE;
1049 VOP_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
1050 }
1051
1052 /*
1053 * Now that any dependencies that we created have been
1054 * resolved, we can undo the partial allocation.
1055 */
1056
1057 if (unwindidx == 0) {
1058 *allocib = 0;
1059 ip->i_flag |= IN_CHANGE | IN_UPDATE;
1060 if (DOINGSOFTDEP(vp))
1061 VOP_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
1062 } else {
1063 int r;
1064
1065 r = bread(vp, indirs[unwindidx].in_lbn,
1066 (int)fs->fs_bsize, NOCRED, &bp);
1067 if (r) {
1068 panic("Could not unwind indirect block, error %d", r);
1069 brelse(bp);
1070 } else {
1071 bap = (int64_t *)bp->b_data;
1072 bap[indirs[unwindidx].in_off] = 0;
1073 bwrite(bp);
1074 }
1075 }
1076 for (i = unwindidx + 1; i <= num; i++) {
1077 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0,
1078 0);
1079 bp->b_flags |= B_INVAL;
1080 brelse(bp);
1081 }
1082 }
1083 for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {
1084 ffs_blkfree(fs, ip->i_devvp, *blkp, fs->fs_bsize, ip->i_number);
1085 deallocated += fs->fs_bsize;
1086 }
1087 if (deallocated) {
1088 #ifdef QUOTA
1089 /*
1090 * Restore user's disk quota because allocation failed.
1091 */
1092 (void)chkdq(ip, -btodb(deallocated), cred, FORCE);
1093 #endif
1094 ip->i_ffs2_blocks -= btodb(deallocated);
1095 ip->i_flag |= IN_CHANGE | IN_UPDATE;
1096 }
1097 return (error);
1098 }
1099