xref: /openbsd/sys/ufs/ffs/ffs_balloc.c (revision 3b9d585e)
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