1 /* $OpenBSD: ffs_balloc.c,v 1.47 2024/04/13 23:44:11 jsg Exp $ */
2 /* $NetBSD: ffs_balloc.c,v 1.3 1996/02/09 22:22:21 christos Exp $ */
3
4 /*
5 * Copyright (c) 2002 Networks Associates Technology, Inc.
6 * All rights reserved.
7 *
8 * This software was developed for the FreeBSD Project by Marshall
9 * Kirk McKusick and Network Associates Laboratories, the Security
10 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
11 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
12 * research program.
13 *
14 * Copyright (c) 1982, 1986, 1989, 1993
15 * The Regents of the University of California. All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 *
41 * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93
42 */
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/buf.h>
47 #include <sys/proc.h>
48 #include <sys/mount.h>
49 #include <sys/vnode.h>
50
51 #include <ufs/ufs/quota.h>
52 #include <ufs/ufs/inode.h>
53 #include <ufs/ufs/ufsmount.h>
54 #include <ufs/ufs/ufs_extern.h>
55
56 #include <ufs/ffs/fs.h>
57 #include <ufs/ffs/ffs_extern.h>
58
59 int ffs1_balloc(struct inode *, off_t, int, struct ucred *, int, struct buf **);
60 #ifdef FFS2
61 int ffs2_balloc(struct inode *, off_t, int, struct ucred *, int, struct buf **);
62 #endif
63
64 /*
65 * Balloc defines the structure of file system storage
66 * by allocating the physical blocks on a device given
67 * the inode and the logical block number in a file.
68 */
69 int
ffs1_balloc(struct inode * ip,off_t startoffset,int size,struct ucred * cred,int flags,struct buf ** bpp)70 ffs1_balloc(struct inode *ip, off_t startoffset, int size, struct ucred *cred,
71 int flags, struct buf **bpp)
72 {
73 daddr_t lbn, nb, newb, pref;
74 struct fs *fs;
75 struct buf *bp, *nbp;
76 struct vnode *vp;
77 struct proc *p;
78 struct indir indirs[NIADDR + 2];
79 int32_t *bap;
80 int deallocated, osize, nsize, num, i, error;
81 int32_t *allocib, *blkp, *allocblk, allociblk[NIADDR+1];
82 int unwindidx = -1;
83
84 vp = ITOV(ip);
85 fs = ip->i_fs;
86 p = curproc;
87 lbn = lblkno(fs, startoffset);
88 size = blkoff(fs, startoffset) + size;
89 if (size > fs->fs_bsize)
90 panic("ffs1_balloc: blk too big");
91 if (bpp != NULL)
92 *bpp = NULL;
93 if (lbn < 0)
94 return (EFBIG);
95
96 /*
97 * If the next write will extend the file into a new block,
98 * and the file is currently composed of a fragment
99 * this fragment has to be extended to be a full block.
100 */
101 nb = lblkno(fs, ip->i_ffs1_size);
102 if (nb < NDADDR && nb < lbn) {
103 osize = blksize(fs, ip, nb);
104 if (osize < fs->fs_bsize && osize > 0) {
105 error = ffs_realloccg(ip, nb,
106 ffs1_blkpref(ip, nb, (int)nb, &ip->i_ffs1_db[0]),
107 osize, (int)fs->fs_bsize, cred, bpp, &newb);
108 if (error)
109 return (error);
110
111 ip->i_ffs1_size = lblktosize(fs, nb + 1);
112 uvm_vnp_setsize(vp, ip->i_ffs1_size);
113 ip->i_ffs1_db[nb] = newb;
114 ip->i_flag |= IN_CHANGE | IN_UPDATE;
115 if (bpp != NULL) {
116 if (flags & B_SYNC)
117 bwrite(*bpp);
118 else
119 bawrite(*bpp);
120 }
121 }
122 }
123 /*
124 * The first NDADDR blocks are direct blocks
125 */
126 if (lbn < NDADDR) {
127 nb = ip->i_ffs1_db[lbn];
128 if (nb != 0 && ip->i_ffs1_size >= lblktosize(fs, lbn + 1)) {
129 /*
130 * The block is an already-allocated direct block
131 * and the file already extends past this block,
132 * thus this must be a whole block.
133 * Just read the block (if requested).
134 */
135
136 if (bpp != NULL) {
137 error = bread(vp, lbn, fs->fs_bsize, bpp);
138 if (error) {
139 brelse(*bpp);
140 return (error);
141 }
142 }
143 return (0);
144 }
145 if (nb != 0) {
146 /*
147 * Consider need to reallocate a fragment.
148 */
149 osize = fragroundup(fs, blkoff(fs, ip->i_ffs1_size));
150 nsize = fragroundup(fs, size);
151 if (nsize <= osize) {
152 /*
153 * The existing block is already
154 * at least as big as we want.
155 * Just read the block (if requested).
156 */
157 if (bpp != NULL) {
158 error = bread(vp, lbn, fs->fs_bsize,
159 bpp);
160 if (error) {
161 brelse(*bpp);
162 return (error);
163 }
164 buf_adjcnt((*bpp), osize);
165 }
166 return (0);
167 } else {
168 /*
169 * The existing block is smaller than we
170 * want, grow it.
171 */
172 error = ffs_realloccg(ip, lbn,
173 ffs1_blkpref(ip, lbn, (int)lbn,
174 &ip->i_ffs1_db[0]),
175 osize, nsize, cred, bpp, &newb);
176 if (error)
177 return (error);
178 }
179 } else {
180 /*
181 * The block was not previously allocated,
182 * allocate a new block or fragment.
183 */
184
185 if (ip->i_ffs1_size < lblktosize(fs, lbn + 1))
186 nsize = fragroundup(fs, size);
187 else
188 nsize = fs->fs_bsize;
189 error = ffs_alloc(ip, lbn,
190 ffs1_blkpref(ip, lbn, (int)lbn, &ip->i_ffs1_db[0]),
191 nsize, cred, &newb);
192 if (error)
193 return (error);
194 if (bpp != NULL) {
195 *bpp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP);
196 if (nsize < fs->fs_bsize)
197 (*bpp)->b_bcount = nsize;
198 (*bpp)->b_blkno = fsbtodb(fs, newb);
199 if (flags & B_CLRBUF)
200 clrbuf(*bpp);
201 }
202 }
203 ip->i_ffs1_db[lbn] = newb;
204 ip->i_flag |= IN_CHANGE | IN_UPDATE;
205 return (0);
206 }
207
208 /*
209 * Determine the number of levels of indirection.
210 */
211 pref = 0;
212 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
213 return(error);
214 #ifdef DIAGNOSTIC
215 if (num < 1)
216 panic ("ffs1_balloc: ufs_bmaparray returned indirect block");
217 #endif
218 /*
219 * Fetch the first indirect block allocating if necessary.
220 */
221 --num;
222 nb = ip->i_ffs1_ib[indirs[0].in_off];
223
224 allocib = NULL;
225 allocblk = allociblk;
226 if (nb == 0) {
227 pref = ffs1_blkpref(ip, lbn, -indirs[0].in_off - 1, NULL);
228 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
229 cred, &newb);
230 if (error)
231 goto fail;
232 nb = newb;
233
234 *allocblk++ = nb;
235 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, INFSLP);
236 bp->b_blkno = fsbtodb(fs, nb);
237 clrbuf(bp);
238
239 /*
240 * Write synchronously so that indirect blocks
241 * never point at garbage.
242 */
243 if ((error = bwrite(bp)) != 0)
244 goto fail;
245 allocib = &ip->i_ffs1_ib[indirs[0].in_off];
246 *allocib = nb;
247 ip->i_flag |= IN_CHANGE | IN_UPDATE;
248 }
249
250 /*
251 * Fetch through the indirect blocks, allocating as necessary.
252 */
253 for (i = 1;;) {
254 error = bread(vp, indirs[i].in_lbn, (int)fs->fs_bsize, &bp);
255 if (error) {
256 brelse(bp);
257 goto fail;
258 }
259 bap = (int32_t *)bp->b_data;
260 nb = bap[indirs[i].in_off];
261 if (i == num)
262 break;
263 i++;
264 if (nb != 0) {
265 brelse(bp);
266 continue;
267 }
268 if (pref == 0)
269 pref = ffs1_blkpref(ip, lbn, i - num - 1, NULL);
270 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
271 &newb);
272 if (error) {
273 brelse(bp);
274 goto fail;
275 }
276 nb = newb;
277 *allocblk++ = nb;
278 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, INFSLP);
279 nbp->b_blkno = fsbtodb(fs, nb);
280 clrbuf(nbp);
281
282 /*
283 * Write synchronously so that indirect blocks
284 * never point at garbage.
285 */
286 if ((error = bwrite(nbp)) != 0) {
287 brelse(bp);
288 goto fail;
289 }
290 bap[indirs[i - 1].in_off] = nb;
291 if (allocib == NULL && unwindidx < 0)
292 unwindidx = i - 1;
293 /*
294 * If required, write synchronously, otherwise use
295 * delayed write.
296 */
297 if (flags & B_SYNC) {
298 bwrite(bp);
299 } else {
300 bdwrite(bp);
301 }
302 }
303 /*
304 * Get the data block, allocating if necessary.
305 */
306 if (nb == 0) {
307 pref = ffs1_blkpref(ip, lbn, indirs[i].in_off, &bap[0]);
308 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
309 &newb);
310 if (error) {
311 brelse(bp);
312 goto fail;
313 }
314 nb = newb;
315 *allocblk++ = nb;
316 if (bpp != NULL) {
317 nbp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP);
318 nbp->b_blkno = fsbtodb(fs, nb);
319 if (flags & B_CLRBUF)
320 clrbuf(nbp);
321 *bpp = nbp;
322 }
323 bap[indirs[i].in_off] = nb;
324 /*
325 * If required, write synchronously, otherwise use
326 * delayed write.
327 */
328 if (flags & B_SYNC) {
329 bwrite(bp);
330 } else {
331 bdwrite(bp);
332 }
333 return (0);
334 }
335 brelse(bp);
336 if (bpp != NULL) {
337 if (flags & B_CLRBUF) {
338 error = bread(vp, lbn, (int)fs->fs_bsize, &nbp);
339 if (error) {
340 brelse(nbp);
341 goto fail;
342 }
343 } else {
344 nbp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP);
345 nbp->b_blkno = fsbtodb(fs, nb);
346 }
347 *bpp = nbp;
348 }
349 return (0);
350
351 fail:
352 /*
353 * If we have failed to allocate any blocks, simply return the error.
354 * This is the usual case and avoids the need to fsync the file.
355 */
356 if (allocblk == allociblk && allocib == NULL && unwindidx == -1)
357 return (error);
358 /*
359 * If we have failed part way through block allocation, we have to
360 * deallocate any indirect blocks that we have allocated. We have to
361 * fsync the file before we start to get rid of all of its
362 * dependencies so that we do not leave them dangling. We have to sync
363 * it at the end so that the softdep code does not find any untracked
364 * changes. Although this is really slow, running out of disk space is
365 * not expected to be a common occurrence. The error return from fsync
366 * is ignored as we already have an error to return to the user.
367 */
368 VOP_FSYNC(vp, p->p_ucred, MNT_WAIT, p);
369 for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {
370 ffs_blkfree(ip, *blkp, fs->fs_bsize);
371 deallocated += fs->fs_bsize;
372 }
373 if (allocib != NULL) {
374 *allocib = 0;
375 } else if (unwindidx >= 0) {
376 int r;
377
378 r = bread(vp, indirs[unwindidx].in_lbn, (int)fs->fs_bsize, &bp);
379 if (r)
380 panic("Could not unwind indirect block, error %d", r);
381 bap = (int32_t *)bp->b_data;
382 bap[indirs[unwindidx].in_off] = 0;
383 if (flags & B_SYNC) {
384 bwrite(bp);
385 } else {
386 bdwrite(bp);
387 }
388 }
389 if (deallocated) {
390 /*
391 * Restore user's disk quota because allocation failed.
392 */
393 (void)ufs_quota_free_blocks(ip, btodb(deallocated), cred);
394
395 ip->i_ffs1_blocks -= btodb(deallocated);
396 ip->i_flag |= IN_CHANGE | IN_UPDATE;
397 }
398 VOP_FSYNC(vp, p->p_ucred, MNT_WAIT, p);
399 return (error);
400 }
401
402 #ifdef FFS2
403 int
ffs2_balloc(struct inode * ip,off_t off,int size,struct ucred * cred,int flags,struct buf ** bpp)404 ffs2_balloc(struct inode *ip, off_t off, int size, struct ucred *cred,
405 int flags, struct buf **bpp)
406 {
407 daddr_t lbn, lastlbn, nb, newb, *blkp;
408 daddr_t pref, *allocblk, allociblk[NIADDR + 1];
409 daddr_t *bap, *allocib;
410 int deallocated, osize, nsize, num, i, error, unwindidx, r;
411 struct buf *bp, *nbp;
412 struct indir indirs[NIADDR + 2];
413 struct fs *fs;
414 struct vnode *vp;
415 struct proc *p;
416
417 vp = ITOV(ip);
418 fs = ip->i_fs;
419 p = curproc;
420 unwindidx = -1;
421
422 lbn = lblkno(fs, off);
423 size = blkoff(fs, off) + size;
424
425 if (size > fs->fs_bsize)
426 panic("ffs2_balloc: block too big");
427
428 if (bpp != NULL)
429 *bpp = NULL;
430
431 if (lbn < 0)
432 return (EFBIG);
433
434 /*
435 * If the next write will extend the file into a new block, and the
436 * file is currently composed of a fragment, this fragment has to be
437 * extended to be a full block.
438 */
439 lastlbn = lblkno(fs, ip->i_ffs2_size);
440 if (lastlbn < NDADDR && lastlbn < lbn) {
441 nb = lastlbn;
442 osize = blksize(fs, ip, nb);
443 if (osize < fs->fs_bsize && osize > 0) {
444 error = ffs_realloccg(ip, nb, ffs2_blkpref(ip,
445 lastlbn, nb, &ip->i_ffs2_db[0]), osize,
446 (int) fs->fs_bsize, cred, bpp, &newb);
447 if (error)
448 return (error);
449
450 ip->i_ffs2_size = lblktosize(fs, nb + 1);
451 uvm_vnp_setsize(vp, ip->i_ffs2_size);
452 ip->i_ffs2_db[nb] = newb;
453 ip->i_flag |= IN_CHANGE | IN_UPDATE;
454
455 if (bpp) {
456 if (flags & B_SYNC)
457 bwrite(*bpp);
458 else
459 bawrite(*bpp);
460 }
461 }
462 }
463
464 /*
465 * The first NDADDR blocks are direct.
466 */
467 if (lbn < NDADDR) {
468
469 nb = ip->i_ffs2_db[lbn];
470
471 if (nb != 0 && ip->i_ffs2_size >= lblktosize(fs, lbn + 1)) {
472 /*
473 * The direct block is already allocated and the file
474 * extends past this block, thus this must be a whole
475 * block. Just read it, if requested.
476 */
477 if (bpp != NULL) {
478 error = bread(vp, lbn, fs->fs_bsize, bpp);
479 if (error) {
480 brelse(*bpp);
481 return (error);
482 }
483 }
484
485 return (0);
486 }
487
488 if (nb != 0) {
489 /*
490 * Consider the need to allocate a fragment.
491 */
492 osize = fragroundup(fs, blkoff(fs, ip->i_ffs2_size));
493 nsize = fragroundup(fs, size);
494
495 if (nsize <= osize) {
496 /*
497 * The existing block is already at least as
498 * big as we want. Just read it, if requested.
499 */
500 if (bpp != NULL) {
501 error = bread(vp, lbn, fs->fs_bsize,
502 bpp);
503 if (error) {
504 brelse(*bpp);
505 return (error);
506 }
507 buf_adjcnt((*bpp), osize);
508 }
509
510 return (0);
511 } else {
512 /*
513 * The existing block is smaller than we want,
514 * grow it.
515 */
516 error = ffs_realloccg(ip, lbn,
517 ffs2_blkpref(ip, lbn, (int) lbn,
518 &ip->i_ffs2_db[0]), osize, nsize, cred,
519 bpp, &newb);
520 if (error)
521 return (error);
522 }
523 } else {
524 /*
525 * The block was not previously allocated, allocate a
526 * new block or fragment.
527 */
528 if (ip->i_ffs2_size < lblktosize(fs, lbn + 1))
529 nsize = fragroundup(fs, size);
530 else
531 nsize = fs->fs_bsize;
532
533 error = ffs_alloc(ip, lbn, ffs2_blkpref(ip, lbn,
534 (int) lbn, &ip->i_ffs2_db[0]), nsize, cred, &newb);
535 if (error)
536 return (error);
537
538 if (bpp != NULL) {
539 bp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP);
540 if (nsize < fs->fs_bsize)
541 bp->b_bcount = nsize;
542 bp->b_blkno = fsbtodb(fs, newb);
543 if (flags & B_CLRBUF)
544 clrbuf(bp);
545 *bpp = bp;
546 }
547 }
548
549 ip->i_ffs2_db[lbn] = newb;
550 ip->i_flag |= IN_CHANGE | IN_UPDATE;
551
552 return (0);
553 }
554
555 /*
556 * Determine the number of levels of indirection.
557 */
558 pref = 0;
559 error = ufs_getlbns(vp, lbn, indirs, &num);
560 if (error)
561 return (error);
562
563 #ifdef DIAGNOSTIC
564 if (num < 1)
565 panic("ffs2_balloc: ufs_bmaparray returned indirect block");
566 #endif
567
568 /*
569 * Fetch the first indirect block allocating it necessary.
570 */
571 --num;
572 nb = ip->i_ffs2_ib[indirs[0].in_off];
573 allocib = NULL;
574 allocblk = allociblk;
575
576 if (nb == 0) {
577 pref = ffs2_blkpref(ip, lbn, -indirs[0].in_off - 1, NULL);
578 error = ffs_alloc(ip, lbn, pref, (int) fs->fs_bsize, cred,
579 &newb);
580 if (error)
581 goto fail;
582
583 nb = newb;
584 *allocblk++ = nb;
585 bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, INFSLP);
586 bp->b_blkno = fsbtodb(fs, nb);
587 clrbuf(bp);
588
589 /*
590 * Write synchronously so that indirect blocks never
591 * point at garbage.
592 */
593 error = bwrite(bp);
594 if (error)
595 goto fail;
596
597 unwindidx = 0;
598 allocib = &ip->i_ffs2_ib[indirs[0].in_off];
599 *allocib = nb;
600 ip->i_flag |= IN_CHANGE | IN_UPDATE;
601 }
602
603 /*
604 * Fetch through the indirect blocks, allocating as necessary.
605 */
606 for (i = 1;;) {
607 error = bread(vp, indirs[i].in_lbn, (int)fs->fs_bsize, &bp);
608 if (error) {
609 brelse(bp);
610 goto fail;
611 }
612
613 bap = (int64_t *) bp->b_data;
614 nb = bap[indirs[i].in_off];
615
616 if (i == num)
617 break;
618
619 i++;
620
621 if (nb != 0) {
622 brelse(bp);
623 continue;
624 }
625
626 if (pref == 0)
627 pref = ffs2_blkpref(ip, lbn, i - num - 1, NULL);
628
629 error = ffs_alloc(ip, lbn, pref, (int) fs->fs_bsize, cred,
630 &newb);
631 if (error) {
632 brelse(bp);
633 goto fail;
634 }
635
636 nb = newb;
637 *allocblk++ = nb;
638 nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, INFSLP);
639 nbp->b_blkno = fsbtodb(fs, nb);
640 clrbuf(nbp);
641
642 /*
643 * Write synchronously so that indirect blocks never
644 * point at garbage.
645 */
646 error = bwrite(nbp);
647 if (error) {
648 brelse(bp);
649 goto fail;
650 }
651
652 if (unwindidx < 0)
653 unwindidx = i - 1;
654
655 bap[indirs[i - 1].in_off] = nb;
656
657 /*
658 * If required, write synchronously, otherwise use delayed
659 * write.
660 */
661 if (flags & B_SYNC)
662 bwrite(bp);
663 else
664 bdwrite(bp);
665 }
666
667 /*
668 * Get the data block, allocating if necessary.
669 */
670 if (nb == 0) {
671 pref = ffs2_blkpref(ip, lbn, indirs[num].in_off, &bap[0]);
672
673 error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
674 &newb);
675 if (error) {
676 brelse(bp);
677 goto fail;
678 }
679
680 nb = newb;
681 *allocblk++ = nb;
682
683 if (bpp != NULL) {
684 nbp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP);
685 nbp->b_blkno = fsbtodb(fs, nb);
686 if (flags & B_CLRBUF)
687 clrbuf(nbp);
688 *bpp = nbp;
689 }
690
691 bap[indirs[num].in_off] = nb;
692
693 if (allocib == NULL && unwindidx < 0)
694 unwindidx = i - 1;
695
696 /*
697 * If required, write synchronously, otherwise use delayed
698 * write.
699 */
700 if (flags & B_SYNC)
701 bwrite(bp);
702 else
703 bdwrite(bp);
704
705 return (0);
706 }
707
708 brelse(bp);
709
710 if (bpp != NULL) {
711 if (flags & B_CLRBUF) {
712 error = bread(vp, lbn, (int)fs->fs_bsize, &nbp);
713 if (error) {
714 brelse(nbp);
715 goto fail;
716 }
717 } else {
718 nbp = getblk(vp, lbn, fs->fs_bsize, 0, INFSLP);
719 nbp->b_blkno = fsbtodb(fs, nb);
720 clrbuf(nbp);
721 }
722
723 *bpp = nbp;
724 }
725
726 return (0);
727
728 fail:
729 /*
730 * If we have failed to allocate any blocks, simply return the error.
731 * This is the usual case and avoids the need to fsync the file.
732 */
733 if (allocblk == allociblk && allocib == NULL && unwindidx == -1)
734 return (error);
735 /*
736 * If we have failed part way through block allocation, we have to
737 * deallocate any indirect blocks that we have allocated. We have to
738 * fsync the file before we start to get rid of all of its
739 * dependencies so that we do not leave them dangling. We have to sync
740 * it at the end so that the softdep code does not find any untracked
741 * changes. Although this is really slow, running out of disk space is
742 * not expected to be a common occurrence. The error return from fsync
743 * is ignored as we already have an error to return to the user.
744 */
745 VOP_FSYNC(vp, p->p_ucred, MNT_WAIT, p);
746 if (unwindidx >= 0) {
747 /*
748 * First write out any buffers we've created to resolve their
749 * softdeps. This must be done in reverse order of creation so
750 * that we resolve the dependencies in one pass.
751 * Write the cylinder group buffers for these buffers too.
752 */
753 for (i = num; i >= unwindidx; i--) {
754 if (i == 0)
755 break;
756
757 bp = getblk(vp, indirs[i].in_lbn, (int) fs->fs_bsize,
758 0, INFSLP);
759 if (bp->b_flags & B_DELWRI) {
760 nb = fsbtodb(fs, cgtod(fs, dtog(fs,
761 dbtofsb(fs, bp->b_blkno))));
762 bwrite(bp);
763 bp = getblk(ip->i_devvp, nb,
764 (int) fs->fs_cgsize, 0, INFSLP);
765 if (bp->b_flags & B_DELWRI)
766 bwrite(bp);
767 else {
768 bp->b_flags |= B_INVAL;
769 brelse(bp);
770 }
771 } else {
772 bp->b_flags |= B_INVAL;
773 brelse(bp);
774 }
775 }
776
777 /*
778 * Now that any dependencies that we created have been
779 * resolved, we can undo the partial allocation.
780 */
781 if (unwindidx == 0) {
782 *allocib = 0;
783 ip->i_flag |= IN_CHANGE | IN_UPDATE;
784 } else {
785 r = bread(vp, indirs[unwindidx].in_lbn,
786 (int)fs->fs_bsize, &bp);
787 if (r)
788 panic("ffs2_balloc: unwind failed");
789
790 bap = (int64_t *) bp->b_data;
791 bap[indirs[unwindidx].in_off] = 0;
792 bwrite(bp);
793 }
794
795 for (i = unwindidx + 1; i <= num; i++) {
796 bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0,
797 INFSLP);
798 bp->b_flags |= B_INVAL;
799 brelse(bp);
800 }
801 }
802
803 for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {
804 ffs_blkfree(ip, *blkp, fs->fs_bsize);
805 deallocated += fs->fs_bsize;
806 }
807
808 if (deallocated) {
809 /*
810 * Restore user's disk quota because allocation failed.
811 */
812 (void) ufs_quota_free_blocks(ip, btodb(deallocated), cred);
813
814 ip->i_ffs2_blocks -= btodb(deallocated);
815 ip->i_flag |= IN_CHANGE | IN_UPDATE;
816 }
817 VOP_FSYNC(vp, p->p_ucred, MNT_WAIT, p);
818 return (error);
819 }
820 #endif /* FFS2 */
821
822 /*
823 * Balloc defines the structure of file system storage by allocating the
824 * physical blocks given the inode and the logical block number in a file.
825 */
826 int
ffs_balloc(struct inode * ip,off_t off,int size,struct ucred * cred,int flags,struct buf ** bpp)827 ffs_balloc(struct inode *ip, off_t off, int size, struct ucred *cred,
828 int flags, struct buf **bpp)
829 {
830 #ifdef FFS2
831 if (ip->i_fs->fs_magic == FS_UFS2_MAGIC)
832 return (ffs2_balloc(ip, off, size, cred, flags, bpp));
833 else
834 #endif
835 return (ffs1_balloc(ip, off, size, cred, flags, bpp));
836 }
837