Deleted Added
full compact
ffs_balloc.c (98658) ffs_balloc.c (100344)
1/*
2 * Copyright (c) 2002 Networks Associates Technology, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by Marshall
6 * Kirk McKusick and Network Associates Laboratories, the Security
7 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
8 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS

--- 29 unchanged lines hidden (view full) ---

38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 *
45 * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95
1/*
2 * Copyright (c) 2002 Networks Associates Technology, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by Marshall
6 * Kirk McKusick and Network Associates Laboratories, the Security
7 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
8 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS

--- 29 unchanged lines hidden (view full) ---

38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 *
45 * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95
46 * $FreeBSD: head/sys/ufs/ffs/ffs_balloc.c 98658 2002-06-23 06:12:22Z dillon $
46 * $FreeBSD: head/sys/ufs/ffs/ffs_balloc.c 100344 2002-07-19 07:29:39Z mckusick $
47 */
48
49#include <sys/param.h>
50#include <sys/systm.h>
51#include <sys/bio.h>
52#include <sys/buf.h>
53#include <sys/lock.h>
54#include <sys/mount.h>

--- 13 unchanged lines hidden (view full) ---

68 * This is the allocation strategy for UFS1. Below is
69 * the allocation strategy for UFS2.
70 */
71int
72ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
73 struct ucred *cred, int flags, struct buf **bpp)
74{
75 struct inode *ip;
47 */
48
49#include <sys/param.h>
50#include <sys/systm.h>
51#include <sys/bio.h>
52#include <sys/buf.h>
53#include <sys/lock.h>
54#include <sys/mount.h>

--- 13 unchanged lines hidden (view full) ---

68 * This is the allocation strategy for UFS1. Below is
69 * the allocation strategy for UFS2.
70 */
71int
72ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
73 struct ucred *cred, int flags, struct buf **bpp)
74{
75 struct inode *ip;
76 struct ufs1_dinode *dp;
76 ufs_lbn_t lbn, lastlbn;
77 struct fs *fs;
78 ufs1_daddr_t nb;
79 struct buf *bp, *nbp;
80 struct indir indirs[NIADDR + 2];
81 int deallocated, osize, nsize, num, i, error;
82 ufs2_daddr_t newb;
83 ufs1_daddr_t *bap, pref;
84 ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
85 int unwindidx = -1;
86 struct thread *td = curthread; /* XXX */
87
88 ip = VTOI(vp);
77 ufs_lbn_t lbn, lastlbn;
78 struct fs *fs;
79 ufs1_daddr_t nb;
80 struct buf *bp, *nbp;
81 struct indir indirs[NIADDR + 2];
82 int deallocated, osize, nsize, num, i, error;
83 ufs2_daddr_t newb;
84 ufs1_daddr_t *bap, pref;
85 ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
86 int unwindidx = -1;
87 struct thread *td = curthread; /* XXX */
88
89 ip = VTOI(vp);
90 dp = ip->i_din1;
89 fs = ip->i_fs;
90 lbn = lblkno(fs, startoffset);
91 size = blkoff(fs, startoffset) + size;
92 if (size > fs->fs_bsize)
93 panic("ffs_balloc_ufs1: blk too big");
94 *bpp = NULL;
91 fs = ip->i_fs;
92 lbn = lblkno(fs, startoffset);
93 size = blkoff(fs, startoffset) + size;
94 if (size > fs->fs_bsize)
95 panic("ffs_balloc_ufs1: blk too big");
96 *bpp = NULL;
97 if (flags & IO_EXT)
98 return (EOPNOTSUPP);
95 if (lbn < 0)
96 return (EFBIG);
97
98 /*
99 * If the next write will extend the file into a new block,
100 * and the file is currently composed of a fragment
101 * this fragment has to be extended to be a full block.
102 */
103 lastlbn = lblkno(fs, ip->i_size);
104 if (lastlbn < NDADDR && lastlbn < lbn) {
105 nb = lastlbn;
106 osize = blksize(fs, ip, nb);
107 if (osize < fs->fs_bsize && osize > 0) {
99 if (lbn < 0)
100 return (EFBIG);
101
102 /*
103 * If the next write will extend the file into a new block,
104 * and the file is currently composed of a fragment
105 * this fragment has to be extended to be a full block.
106 */
107 lastlbn = lblkno(fs, ip->i_size);
108 if (lastlbn < NDADDR && lastlbn < lbn) {
109 nb = lastlbn;
110 osize = blksize(fs, ip, nb);
111 if (osize < fs->fs_bsize && osize > 0) {
108 error = ffs_realloccg(ip, nb,
109 ffs_blkpref_ufs1(ip, lastlbn, (int)nb,
110 &ip->i_din1->di_db[0]),
111 osize, (int)fs->fs_bsize, cred, &bp);
112 error = ffs_realloccg(ip, nb, dp->di_db[nb],
113 ffs_blkpref_ufs1(ip, lastlbn, (int)nb,
114 &dp->di_db[0]), osize, (int)fs->fs_bsize, cred, &bp);
112 if (error)
113 return (error);
114 if (DOINGSOFTDEP(vp))
115 softdep_setup_allocdirect(ip, nb,
115 if (error)
116 return (error);
117 if (DOINGSOFTDEP(vp))
118 softdep_setup_allocdirect(ip, nb,
116 dbtofsb(fs, bp->b_blkno),
117 ip->i_din1->di_db[nb],
119 dbtofsb(fs, bp->b_blkno), dp->di_db[nb],
118 fs->fs_bsize, osize, bp);
119 ip->i_size = smalllblktosize(fs, nb + 1);
120 fs->fs_bsize, osize, bp);
121 ip->i_size = smalllblktosize(fs, nb + 1);
120 ip->i_din1->di_size = ip->i_size;
121 ip->i_din1->di_db[nb] = dbtofsb(fs, bp->b_blkno);
122 dp->di_size = ip->i_size;
123 dp->di_db[nb] = dbtofsb(fs, bp->b_blkno);
122 ip->i_flag |= IN_CHANGE | IN_UPDATE;
124 ip->i_flag |= IN_CHANGE | IN_UPDATE;
123 if (flags & BA_SYNC)
125 if (flags & IO_SYNC)
124 bwrite(bp);
125 else
126 bawrite(bp);
127 }
128 }
129 /*
130 * The first NDADDR blocks are direct blocks
131 */
132 if (lbn < NDADDR) {
133 if (flags & BA_METAONLY)
134 panic("ffs_balloc_ufs1: BA_METAONLY for direct block");
126 bwrite(bp);
127 else
128 bawrite(bp);
129 }
130 }
131 /*
132 * The first NDADDR blocks are direct blocks
133 */
134 if (lbn < NDADDR) {
135 if (flags & BA_METAONLY)
136 panic("ffs_balloc_ufs1: BA_METAONLY for direct block");
135 nb = ip->i_din1->di_db[lbn];
137 nb = dp->di_db[lbn];
136 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) {
137 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
138 if (error) {
139 brelse(bp);
140 return (error);
141 }
142 bp->b_blkno = fsbtodb(fs, nb);
143 *bpp = bp;

--- 8 unchanged lines hidden (view full) ---

152 if (nsize <= osize) {
153 error = bread(vp, lbn, osize, NOCRED, &bp);
154 if (error) {
155 brelse(bp);
156 return (error);
157 }
158 bp->b_blkno = fsbtodb(fs, nb);
159 } else {
138 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) {
139 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
140 if (error) {
141 brelse(bp);
142 return (error);
143 }
144 bp->b_blkno = fsbtodb(fs, nb);
145 *bpp = bp;

--- 8 unchanged lines hidden (view full) ---

154 if (nsize <= osize) {
155 error = bread(vp, lbn, osize, NOCRED, &bp);
156 if (error) {
157 brelse(bp);
158 return (error);
159 }
160 bp->b_blkno = fsbtodb(fs, nb);
161 } else {
160 error = ffs_realloccg(ip, lbn,
162 error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
161 ffs_blkpref_ufs1(ip, lbn, (int)lbn,
163 ffs_blkpref_ufs1(ip, lbn, (int)lbn,
162 &ip->i_din1->di_db[0]),
163 osize, nsize, cred, &bp);
164 &dp->di_db[0]), osize, nsize, cred, &bp);
164 if (error)
165 return (error);
166 if (DOINGSOFTDEP(vp))
167 softdep_setup_allocdirect(ip, lbn,
168 dbtofsb(fs, bp->b_blkno), nb,
169 nsize, osize, bp);
170 }
171 } else {
172 if (ip->i_size < smalllblktosize(fs, lbn + 1))
173 nsize = fragroundup(fs, size);
174 else
175 nsize = fs->fs_bsize;
176 error = ffs_alloc(ip, lbn,
165 if (error)
166 return (error);
167 if (DOINGSOFTDEP(vp))
168 softdep_setup_allocdirect(ip, lbn,
169 dbtofsb(fs, bp->b_blkno), nb,
170 nsize, osize, bp);
171 }
172 } else {
173 if (ip->i_size < smalllblktosize(fs, lbn + 1))
174 nsize = fragroundup(fs, size);
175 else
176 nsize = fs->fs_bsize;
177 error = ffs_alloc(ip, lbn,
177 ffs_blkpref_ufs1(ip, lbn, (int)lbn,
178 &ip->i_din1->di_db[0]),
178 ffs_blkpref_ufs1(ip, lbn, (int)lbn, &dp->di_db[0]),
179 nsize, cred, &newb);
180 if (error)
181 return (error);
182 bp = getblk(vp, lbn, nsize, 0, 0);
183 bp->b_blkno = fsbtodb(fs, newb);
184 if (flags & BA_CLRBUF)
185 vfs_bio_clrbuf(bp);
186 if (DOINGSOFTDEP(vp))
187 softdep_setup_allocdirect(ip, lbn, newb, 0,
188 nsize, 0, bp);
189 }
179 nsize, cred, &newb);
180 if (error)
181 return (error);
182 bp = getblk(vp, lbn, nsize, 0, 0);
183 bp->b_blkno = fsbtodb(fs, newb);
184 if (flags & BA_CLRBUF)
185 vfs_bio_clrbuf(bp);
186 if (DOINGSOFTDEP(vp))
187 softdep_setup_allocdirect(ip, lbn, newb, 0,
188 nsize, 0, bp);
189 }
190 ip->i_din1->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
190 dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
191 ip->i_flag |= IN_CHANGE | IN_UPDATE;
192 *bpp = bp;
193 return (0);
194 }
195 /*
196 * Determine the number of levels of indirection.
197 */
198 pref = 0;
199 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
200 return(error);
201#ifdef DIAGNOSTIC
202 if (num < 1)
203 panic ("ffs_balloc_ufs1: ufs_getlbns returned indirect block");
204#endif
205 /*
206 * Fetch the first indirect block allocating if necessary.
207 */
208 --num;
191 ip->i_flag |= IN_CHANGE | IN_UPDATE;
192 *bpp = bp;
193 return (0);
194 }
195 /*
196 * Determine the number of levels of indirection.
197 */
198 pref = 0;
199 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
200 return(error);
201#ifdef DIAGNOSTIC
202 if (num < 1)
203 panic ("ffs_balloc_ufs1: ufs_getlbns returned indirect block");
204#endif
205 /*
206 * Fetch the first indirect block allocating if necessary.
207 */
208 --num;
209 nb = ip->i_din1->di_ib[indirs[0].in_off];
209 nb = dp->di_ib[indirs[0].in_off];
210 allocib = NULL;
211 allocblk = allociblk;
212 if (nb == 0) {
213 pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
214 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
215 cred, &newb)) != 0)
216 return (error);
217 nb = newb;

--- 10 unchanged lines hidden (view full) ---

228 * Write synchronously so that indirect blocks
229 * never point at garbage.
230 */
231 if (DOINGASYNC(vp))
232 bdwrite(bp);
233 else if ((error = bwrite(bp)) != 0)
234 goto fail;
235 }
210 allocib = NULL;
211 allocblk = allociblk;
212 if (nb == 0) {
213 pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
214 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
215 cred, &newb)) != 0)
216 return (error);
217 nb = newb;

--- 10 unchanged lines hidden (view full) ---

228 * Write synchronously so that indirect blocks
229 * never point at garbage.
230 */
231 if (DOINGASYNC(vp))
232 bdwrite(bp);
233 else if ((error = bwrite(bp)) != 0)
234 goto fail;
235 }
236 allocib = &ip->i_din1->di_ib[indirs[0].in_off];
236 allocib = &dp->di_ib[indirs[0].in_off];
237 *allocib = nb;
238 ip->i_flag |= IN_CHANGE | IN_UPDATE;
239 }
240 /*
241 * Fetch through the indirect blocks, allocating as necessary.
242 */
243 for (i = 1;;) {
244 error = bread(vp,

--- 39 unchanged lines hidden (view full) ---

284 }
285 bap[indirs[i - 1].in_off] = nb;
286 if (allocib == NULL && unwindidx < 0)
287 unwindidx = i - 1;
288 /*
289 * If required, write synchronously, otherwise use
290 * delayed write.
291 */
237 *allocib = nb;
238 ip->i_flag |= IN_CHANGE | IN_UPDATE;
239 }
240 /*
241 * Fetch through the indirect blocks, allocating as necessary.
242 */
243 for (i = 1;;) {
244 error = bread(vp,

--- 39 unchanged lines hidden (view full) ---

284 }
285 bap[indirs[i - 1].in_off] = nb;
286 if (allocib == NULL && unwindidx < 0)
287 unwindidx = i - 1;
288 /*
289 * If required, write synchronously, otherwise use
290 * delayed write.
291 */
292 if (flags & BA_SYNC) {
292 if (flags & IO_SYNC) {
293 bwrite(bp);
294 } else {
295 if (bp->b_bufsize == fs->fs_bsize)
296 bp->b_flags |= B_CLUSTEROK;
297 bdwrite(bp);
298 }
299 }
300 /*

--- 23 unchanged lines hidden (view full) ---

324 if (DOINGSOFTDEP(vp))
325 softdep_setup_allocindir_page(ip, lbn, bp,
326 indirs[i].in_off, nb, 0, nbp);
327 bap[indirs[i].in_off] = nb;
328 /*
329 * If required, write synchronously, otherwise use
330 * delayed write.
331 */
293 bwrite(bp);
294 } else {
295 if (bp->b_bufsize == fs->fs_bsize)
296 bp->b_flags |= B_CLUSTEROK;
297 bdwrite(bp);
298 }
299 }
300 /*

--- 23 unchanged lines hidden (view full) ---

324 if (DOINGSOFTDEP(vp))
325 softdep_setup_allocindir_page(ip, lbn, bp,
326 indirs[i].in_off, nb, 0, nbp);
327 bap[indirs[i].in_off] = nb;
328 /*
329 * If required, write synchronously, otherwise use
330 * delayed write.
331 */
332 if (flags & BA_SYNC) {
332 if (flags & IO_SYNC) {
333 bwrite(bp);
334 } else {
335 if (bp->b_bufsize == fs->fs_bsize)
336 bp->b_flags |= B_CLUSTEROK;
337 bdwrite(bp);
338 }
339 *bpp = nbp;
340 return (0);

--- 36 unchanged lines hidden (view full) ---

377 r = bread(vp, indirs[unwindidx].in_lbn,
378 (int)fs->fs_bsize, NOCRED, &bp);
379 if (r) {
380 panic("Could not unwind indirect block, error %d", r);
381 brelse(bp);
382 } else {
383 bap = (ufs1_daddr_t *)bp->b_data;
384 bap[indirs[unwindidx].in_off] = 0;
333 bwrite(bp);
334 } else {
335 if (bp->b_bufsize == fs->fs_bsize)
336 bp->b_flags |= B_CLUSTEROK;
337 bdwrite(bp);
338 }
339 *bpp = nbp;
340 return (0);

--- 36 unchanged lines hidden (view full) ---

377 r = bread(vp, indirs[unwindidx].in_lbn,
378 (int)fs->fs_bsize, NOCRED, &bp);
379 if (r) {
380 panic("Could not unwind indirect block, error %d", r);
381 brelse(bp);
382 } else {
383 bap = (ufs1_daddr_t *)bp->b_data;
384 bap[indirs[unwindidx].in_off] = 0;
385 if (flags & BA_SYNC) {
385 if (flags & IO_SYNC) {
386 bwrite(bp);
387 } else {
388 if (bp->b_bufsize == fs->fs_bsize)
389 bp->b_flags |= B_CLUSTEROK;
390 bdwrite(bp);
391 }
392 }
393 }
394 if (deallocated) {
395#ifdef QUOTA
396 /*
397 * Restore user's disk quota because allocation failed.
398 */
399 (void) chkdq(ip, -btodb(deallocated), cred, FORCE);
400#endif
386 bwrite(bp);
387 } else {
388 if (bp->b_bufsize == fs->fs_bsize)
389 bp->b_flags |= B_CLUSTEROK;
390 bdwrite(bp);
391 }
392 }
393 }
394 if (deallocated) {
395#ifdef QUOTA
396 /*
397 * Restore user's disk quota because allocation failed.
398 */
399 (void) chkdq(ip, -btodb(deallocated), cred, FORCE);
400#endif
401 ip->i_din1->di_blocks -= btodb(deallocated);
401 dp->di_blocks -= btodb(deallocated);
402 ip->i_flag |= IN_CHANGE | IN_UPDATE;
403 }
404 (void) VOP_FSYNC(vp, cred, MNT_WAIT, td);
405 return (error);
406}
407
408/*
409 * Balloc defines the structure of file system storage
410 * by allocating the physical blocks on a device given
411 * the inode and the logical block number in a file.
412 * This is the allocation strategy for UFS2. Above is
413 * the allocation strategy for UFS1.
414 */
415int
416ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
417 struct ucred *cred, int flags, struct buf **bpp)
418{
419 struct inode *ip;
402 ip->i_flag |= IN_CHANGE | IN_UPDATE;
403 }
404 (void) VOP_FSYNC(vp, cred, MNT_WAIT, td);
405 return (error);
406}
407
408/*
409 * Balloc defines the structure of file system storage
410 * by allocating the physical blocks on a device given
411 * the inode and the logical block number in a file.
412 * This is the allocation strategy for UFS2. Above is
413 * the allocation strategy for UFS1.
414 */
415int
416ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
417 struct ucred *cred, int flags, struct buf **bpp)
418{
419 struct inode *ip;
420 struct ufs2_dinode *dp;
420 ufs_lbn_t lbn, lastlbn;
421 struct fs *fs;
422 struct buf *bp, *nbp;
423 struct indir indirs[NIADDR + 2];
424 ufs2_daddr_t nb, newb, *bap, pref;
425 ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
426 int deallocated, osize, nsize, num, i, error;
427 int unwindidx = -1;
428 struct thread *td = curthread; /* XXX */
429
430 ip = VTOI(vp);
421 ufs_lbn_t lbn, lastlbn;
422 struct fs *fs;
423 struct buf *bp, *nbp;
424 struct indir indirs[NIADDR + 2];
425 ufs2_daddr_t nb, newb, *bap, pref;
426 ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
427 int deallocated, osize, nsize, num, i, error;
428 int unwindidx = -1;
429 struct thread *td = curthread; /* XXX */
430
431 ip = VTOI(vp);
432 dp = ip->i_din2;
431 fs = ip->i_fs;
432 lbn = lblkno(fs, startoffset);
433 size = blkoff(fs, startoffset) + size;
434 if (size > fs->fs_bsize)
435 panic("ffs_balloc_ufs2: blk too big");
436 *bpp = NULL;
437 if (lbn < 0)
438 return (EFBIG);
439
440 /*
433 fs = ip->i_fs;
434 lbn = lblkno(fs, startoffset);
435 size = blkoff(fs, startoffset) + size;
436 if (size > fs->fs_bsize)
437 panic("ffs_balloc_ufs2: blk too big");
438 *bpp = NULL;
439 if (lbn < 0)
440 return (EFBIG);
441
442 /*
443 * Check for allocating external data.
444 */
445 if (flags & IO_EXT) {
446 if (lbn >= NXADDR)
447 return (EFBIG);
448 /*
449 * If the next write will extend the data into a new block,
450 * and the data is currently composed of a fragment
451 * this fragment has to be extended to be a full block.
452 */
453 lastlbn = lblkno(fs, dp->di_extsize);
454 if (lastlbn < lbn) {
455 nb = lastlbn;
456 osize = sblksize(fs, dp->di_extsize, nb);
457 if (osize < fs->fs_bsize && osize > 0) {
458 error = ffs_realloccg(ip, -1 - nb,
459 dp->di_extb[nb],
460 ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
461 &dp->di_extb[0]), osize,
462 (int)fs->fs_bsize, cred, &bp);
463 if (error)
464 return (error);
465 if (DOINGSOFTDEP(vp))
466 softdep_setup_allocext(ip, nb,
467 dbtofsb(fs, bp->b_blkno),
468 dp->di_extb[nb],
469 fs->fs_bsize, osize, bp);
470 dp->di_extsize = smalllblktosize(fs, nb + 1);
471 dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno);
472 bp->b_xflags |= BX_ALTDATA;
473 ip->i_flag |= IN_CHANGE | IN_UPDATE;
474 if (flags & IO_SYNC)
475 bwrite(bp);
476 else
477 bawrite(bp);
478 }
479 }
480 /*
481 * All blocks are direct blocks
482 */
483 if (flags & BA_METAONLY)
484 panic("ffs_balloc_ufs2: BA_METAONLY for ext block");
485 nb = dp->di_extb[lbn];
486 if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) {
487 error = bread(vp, -1 - lbn, fs->fs_bsize, NOCRED, &bp);
488 if (error) {
489 brelse(bp);
490 return (error);
491 }
492 bp->b_blkno = fsbtodb(fs, nb);
493 bp->b_xflags |= BX_ALTDATA;
494 *bpp = bp;
495 return (0);
496 }
497 if (nb != 0) {
498 /*
499 * Consider need to reallocate a fragment.
500 */
501 osize = fragroundup(fs, blkoff(fs, dp->di_extsize));
502 nsize = fragroundup(fs, size);
503 if (nsize <= osize) {
504 error = bread(vp, -1 - lbn, osize, NOCRED, &bp);
505 if (error) {
506 brelse(bp);
507 return (error);
508 }
509 bp->b_blkno = fsbtodb(fs, nb);
510 bp->b_xflags |= BX_ALTDATA;
511 } else {
512 error = ffs_realloccg(ip, -1 - lbn,
513 dp->di_extb[lbn],
514 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
515 &dp->di_extb[0]), osize, nsize, cred, &bp);
516 if (error)
517 return (error);
518 bp->b_xflags |= BX_ALTDATA;
519 if (DOINGSOFTDEP(vp))
520 softdep_setup_allocext(ip, lbn,
521 dbtofsb(fs, bp->b_blkno), nb,
522 nsize, osize, bp);
523 }
524 } else {
525 if (dp->di_extsize < smalllblktosize(fs, lbn + 1))
526 nsize = fragroundup(fs, size);
527 else
528 nsize = fs->fs_bsize;
529 error = ffs_alloc(ip, lbn,
530 ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]),
531 nsize, cred, &newb);
532 if (error)
533 return (error);
534 bp = getblk(vp, -1 - lbn, nsize, 0, 0);
535 bp->b_blkno = fsbtodb(fs, newb);
536 bp->b_xflags |= BX_ALTDATA;
537 if (flags & BA_CLRBUF)
538 vfs_bio_clrbuf(bp);
539 if (DOINGSOFTDEP(vp))
540 softdep_setup_allocext(ip, lbn, newb, 0,
541 nsize, 0, bp);
542 }
543 dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
544 ip->i_flag |= IN_CHANGE | IN_UPDATE;
545 *bpp = bp;
546 return (0);
547 }
548 /*
441 * If the next write will extend the file into a new block,
442 * and the file is currently composed of a fragment
443 * this fragment has to be extended to be a full block.
444 */
445 lastlbn = lblkno(fs, ip->i_size);
446 if (lastlbn < NDADDR && lastlbn < lbn) {
447 nb = lastlbn;
448 osize = blksize(fs, ip, nb);
449 if (osize < fs->fs_bsize && osize > 0) {
549 * If the next write will extend the file into a new block,
550 * and the file is currently composed of a fragment
551 * this fragment has to be extended to be a full block.
552 */
553 lastlbn = lblkno(fs, ip->i_size);
554 if (lastlbn < NDADDR && lastlbn < lbn) {
555 nb = lastlbn;
556 osize = blksize(fs, ip, nb);
557 if (osize < fs->fs_bsize && osize > 0) {
450 error = ffs_realloccg(ip, nb,
558 error = ffs_realloccg(ip, nb, dp->di_db[nb],
451 ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
559 ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
452 &ip->i_din2->di_db[0]),
453 osize, (int)fs->fs_bsize, cred, &bp);
560 &dp->di_db[0]), osize, (int)fs->fs_bsize,
561 cred, &bp);
454 if (error)
455 return (error);
456 if (DOINGSOFTDEP(vp))
457 softdep_setup_allocdirect(ip, nb,
458 dbtofsb(fs, bp->b_blkno),
562 if (error)
563 return (error);
564 if (DOINGSOFTDEP(vp))
565 softdep_setup_allocdirect(ip, nb,
566 dbtofsb(fs, bp->b_blkno),
459 ip->i_din2->di_db[nb],
567 dp->di_db[nb],
460 fs->fs_bsize, osize, bp);
461 ip->i_size = smalllblktosize(fs, nb + 1);
568 fs->fs_bsize, osize, bp);
569 ip->i_size = smalllblktosize(fs, nb + 1);
462 ip->i_din2->di_size = ip->i_size;
463 ip->i_din2->di_db[nb] = dbtofsb(fs, bp->b_blkno);
570 dp->di_size = ip->i_size;
571 dp->di_db[nb] = dbtofsb(fs, bp->b_blkno);
464 ip->i_flag |= IN_CHANGE | IN_UPDATE;
572 ip->i_flag |= IN_CHANGE | IN_UPDATE;
465 if (flags & BA_SYNC)
573 if (flags & IO_SYNC)
466 bwrite(bp);
467 else
468 bawrite(bp);
469 }
470 }
471 /*
472 * The first NDADDR blocks are direct blocks
473 */
474 if (lbn < NDADDR) {
475 if (flags & BA_METAONLY)
476 panic("ffs_balloc_ufs2: BA_METAONLY for direct block");
574 bwrite(bp);
575 else
576 bawrite(bp);
577 }
578 }
579 /*
580 * The first NDADDR blocks are direct blocks
581 */
582 if (lbn < NDADDR) {
583 if (flags & BA_METAONLY)
584 panic("ffs_balloc_ufs2: BA_METAONLY for direct block");
477 nb = ip->i_din2->di_db[lbn];
585 nb = dp->di_db[lbn];
478 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) {
479 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
480 if (error) {
481 brelse(bp);
482 return (error);
483 }
484 bp->b_blkno = fsbtodb(fs, nb);
485 *bpp = bp;

--- 8 unchanged lines hidden (view full) ---

494 if (nsize <= osize) {
495 error = bread(vp, lbn, osize, NOCRED, &bp);
496 if (error) {
497 brelse(bp);
498 return (error);
499 }
500 bp->b_blkno = fsbtodb(fs, nb);
501 } else {
586 if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) {
587 error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
588 if (error) {
589 brelse(bp);
590 return (error);
591 }
592 bp->b_blkno = fsbtodb(fs, nb);
593 *bpp = bp;

--- 8 unchanged lines hidden (view full) ---

602 if (nsize <= osize) {
603 error = bread(vp, lbn, osize, NOCRED, &bp);
604 if (error) {
605 brelse(bp);
606 return (error);
607 }
608 bp->b_blkno = fsbtodb(fs, nb);
609 } else {
502 error = ffs_realloccg(ip, lbn,
610 error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
503 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
611 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
504 &ip->i_din2->di_db[0]),
505 osize, nsize, cred, &bp);
612 &dp->di_db[0]), osize, nsize, cred, &bp);
506 if (error)
507 return (error);
508 if (DOINGSOFTDEP(vp))
509 softdep_setup_allocdirect(ip, lbn,
510 dbtofsb(fs, bp->b_blkno), nb,
511 nsize, osize, bp);
512 }
513 } else {
514 if (ip->i_size < smalllblktosize(fs, lbn + 1))
515 nsize = fragroundup(fs, size);
516 else
517 nsize = fs->fs_bsize;
518 error = ffs_alloc(ip, lbn,
519 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
613 if (error)
614 return (error);
615 if (DOINGSOFTDEP(vp))
616 softdep_setup_allocdirect(ip, lbn,
617 dbtofsb(fs, bp->b_blkno), nb,
618 nsize, osize, bp);
619 }
620 } else {
621 if (ip->i_size < smalllblktosize(fs, lbn + 1))
622 nsize = fragroundup(fs, size);
623 else
624 nsize = fs->fs_bsize;
625 error = ffs_alloc(ip, lbn,
626 ffs_blkpref_ufs2(ip, lbn, (int)lbn,
520 &ip->i_din2->di_db[0]),
521 nsize, cred, &newb);
627 &dp->di_db[0]), nsize, cred, &newb);
522 if (error)
523 return (error);
524 bp = getblk(vp, lbn, nsize, 0, 0);
525 bp->b_blkno = fsbtodb(fs, newb);
526 if (flags & BA_CLRBUF)
527 vfs_bio_clrbuf(bp);
528 if (DOINGSOFTDEP(vp))
529 softdep_setup_allocdirect(ip, lbn, newb, 0,
530 nsize, 0, bp);
531 }
628 if (error)
629 return (error);
630 bp = getblk(vp, lbn, nsize, 0, 0);
631 bp->b_blkno = fsbtodb(fs, newb);
632 if (flags & BA_CLRBUF)
633 vfs_bio_clrbuf(bp);
634 if (DOINGSOFTDEP(vp))
635 softdep_setup_allocdirect(ip, lbn, newb, 0,
636 nsize, 0, bp);
637 }
532 ip->i_din2->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
638 dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
533 ip->i_flag |= IN_CHANGE | IN_UPDATE;
534 *bpp = bp;
535 return (0);
536 }
537 /*
538 * Determine the number of levels of indirection.
539 */
540 pref = 0;
541 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
542 return(error);
543#ifdef DIAGNOSTIC
544 if (num < 1)
545 panic ("ffs_balloc_ufs2: ufs_getlbns returned indirect block");
546#endif
547 /*
548 * Fetch the first indirect block allocating if necessary.
549 */
550 --num;
639 ip->i_flag |= IN_CHANGE | IN_UPDATE;
640 *bpp = bp;
641 return (0);
642 }
643 /*
644 * Determine the number of levels of indirection.
645 */
646 pref = 0;
647 if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
648 return(error);
649#ifdef DIAGNOSTIC
650 if (num < 1)
651 panic ("ffs_balloc_ufs2: ufs_getlbns returned indirect block");
652#endif
653 /*
654 * Fetch the first indirect block allocating if necessary.
655 */
656 --num;
551 nb = ip->i_din2->di_ib[indirs[0].in_off];
657 nb = dp->di_ib[indirs[0].in_off];
552 allocib = NULL;
553 allocblk = allociblk;
554 if (nb == 0) {
555 pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
556 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
557 cred, &newb)) != 0)
558 return (error);
559 nb = newb;

--- 10 unchanged lines hidden (view full) ---

570 * Write synchronously so that indirect blocks
571 * never point at garbage.
572 */
573 if (DOINGASYNC(vp))
574 bdwrite(bp);
575 else if ((error = bwrite(bp)) != 0)
576 goto fail;
577 }
658 allocib = NULL;
659 allocblk = allociblk;
660 if (nb == 0) {
661 pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
662 if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
663 cred, &newb)) != 0)
664 return (error);
665 nb = newb;

--- 10 unchanged lines hidden (view full) ---

676 * Write synchronously so that indirect blocks
677 * never point at garbage.
678 */
679 if (DOINGASYNC(vp))
680 bdwrite(bp);
681 else if ((error = bwrite(bp)) != 0)
682 goto fail;
683 }
578 allocib = &ip->i_din2->di_ib[indirs[0].in_off];
684 allocib = &dp->di_ib[indirs[0].in_off];
579 *allocib = nb;
580 ip->i_flag |= IN_CHANGE | IN_UPDATE;
581 }
582 /*
583 * Fetch through the indirect blocks, allocating as necessary.
584 */
585 for (i = 1;;) {
586 error = bread(vp,

--- 39 unchanged lines hidden (view full) ---

626 }
627 bap[indirs[i - 1].in_off] = nb;
628 if (allocib == NULL && unwindidx < 0)
629 unwindidx = i - 1;
630 /*
631 * If required, write synchronously, otherwise use
632 * delayed write.
633 */
685 *allocib = nb;
686 ip->i_flag |= IN_CHANGE | IN_UPDATE;
687 }
688 /*
689 * Fetch through the indirect blocks, allocating as necessary.
690 */
691 for (i = 1;;) {
692 error = bread(vp,

--- 39 unchanged lines hidden (view full) ---

732 }
733 bap[indirs[i - 1].in_off] = nb;
734 if (allocib == NULL && unwindidx < 0)
735 unwindidx = i - 1;
736 /*
737 * If required, write synchronously, otherwise use
738 * delayed write.
739 */
634 if (flags & BA_SYNC) {
740 if (flags & IO_SYNC) {
635 bwrite(bp);
636 } else {
637 if (bp->b_bufsize == fs->fs_bsize)
638 bp->b_flags |= B_CLUSTEROK;
639 bdwrite(bp);
640 }
641 }
642 /*

--- 23 unchanged lines hidden (view full) ---

666 if (DOINGSOFTDEP(vp))
667 softdep_setup_allocindir_page(ip, lbn, bp,
668 indirs[i].in_off, nb, 0, nbp);
669 bap[indirs[i].in_off] = nb;
670 /*
671 * If required, write synchronously, otherwise use
672 * delayed write.
673 */
741 bwrite(bp);
742 } else {
743 if (bp->b_bufsize == fs->fs_bsize)
744 bp->b_flags |= B_CLUSTEROK;
745 bdwrite(bp);
746 }
747 }
748 /*

--- 23 unchanged lines hidden (view full) ---

772 if (DOINGSOFTDEP(vp))
773 softdep_setup_allocindir_page(ip, lbn, bp,
774 indirs[i].in_off, nb, 0, nbp);
775 bap[indirs[i].in_off] = nb;
776 /*
777 * If required, write synchronously, otherwise use
778 * delayed write.
779 */
674 if (flags & BA_SYNC) {
780 if (flags & IO_SYNC) {
675 bwrite(bp);
676 } else {
677 if (bp->b_bufsize == fs->fs_bsize)
678 bp->b_flags |= B_CLUSTEROK;
679 bdwrite(bp);
680 }
681 *bpp = nbp;
682 return (0);

--- 36 unchanged lines hidden (view full) ---

719 r = bread(vp, indirs[unwindidx].in_lbn,
720 (int)fs->fs_bsize, NOCRED, &bp);
721 if (r) {
722 panic("Could not unwind indirect block, error %d", r);
723 brelse(bp);
724 } else {
725 bap = (ufs2_daddr_t *)bp->b_data;
726 bap[indirs[unwindidx].in_off] = 0;
781 bwrite(bp);
782 } else {
783 if (bp->b_bufsize == fs->fs_bsize)
784 bp->b_flags |= B_CLUSTEROK;
785 bdwrite(bp);
786 }
787 *bpp = nbp;
788 return (0);

--- 36 unchanged lines hidden (view full) ---

825 r = bread(vp, indirs[unwindidx].in_lbn,
826 (int)fs->fs_bsize, NOCRED, &bp);
827 if (r) {
828 panic("Could not unwind indirect block, error %d", r);
829 brelse(bp);
830 } else {
831 bap = (ufs2_daddr_t *)bp->b_data;
832 bap[indirs[unwindidx].in_off] = 0;
727 if (flags & BA_SYNC) {
833 if (flags & IO_SYNC) {
728 bwrite(bp);
729 } else {
730 if (bp->b_bufsize == fs->fs_bsize)
731 bp->b_flags |= B_CLUSTEROK;
732 bdwrite(bp);
733 }
734 }
735 }
736 if (deallocated) {
737#ifdef QUOTA
738 /*
739 * Restore user's disk quota because allocation failed.
740 */
741 (void) chkdq(ip, -btodb(deallocated), cred, FORCE);
742#endif
834 bwrite(bp);
835 } else {
836 if (bp->b_bufsize == fs->fs_bsize)
837 bp->b_flags |= B_CLUSTEROK;
838 bdwrite(bp);
839 }
840 }
841 }
842 if (deallocated) {
843#ifdef QUOTA
844 /*
845 * Restore user's disk quota because allocation failed.
846 */
847 (void) chkdq(ip, -btodb(deallocated), cred, FORCE);
848#endif
743 ip->i_din2->di_blocks -= btodb(deallocated);
849 dp->di_blocks -= btodb(deallocated);
744 ip->i_flag |= IN_CHANGE | IN_UPDATE;
745 }
746 (void) VOP_FSYNC(vp, cred, MNT_WAIT, td);
747 return (error);
748}
850 ip->i_flag |= IN_CHANGE | IN_UPDATE;
851 }
852 (void) VOP_FSYNC(vp, cred, MNT_WAIT, td);
853 return (error);
854}