[BACK]Return to ffs_balloc.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / ufs / ffs

Annotation of src/sys/ufs/ffs/ffs_balloc.c, Revision 1.23.2.4

1.23.2.4! nathanw     1: /*     $NetBSD: ffs_balloc.c,v 1.23.2.3 2001/08/24 00:13:16 nathanw Exp $      */
1.2       cgd         2:
1.1       mycroft     3: /*
                      4:  * Copyright (c) 1982, 1986, 1989, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by the University of
                     18:  *     California, Berkeley and its contributors.
                     19:  * 4. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  *
1.8       fvdl       35:  *     @(#)ffs_balloc.c        8.8 (Berkeley) 6/16/95
1.1       mycroft    36:  */
1.7       mrg        37:
1.23.2.2  nathanw    38: #if defined(_KERNEL_OPT)
1.10      scottr     39: #include "opt_quota.h"
1.11      scottr     40: #endif
1.1       mycroft    41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/buf.h>
1.23.2.1  nathanw    45: #include <sys/lwp.h>
1.1       mycroft    46: #include <sys/proc.h>
                     47: #include <sys/file.h>
1.15      fvdl       48: #include <sys/mount.h>
1.1       mycroft    49: #include <sys/vnode.h>
1.9       bouyer     50: #include <sys/mount.h>
1.6       mrg        51:
1.1       mycroft    52: #include <ufs/ufs/quota.h>
1.9       bouyer     53: #include <ufs/ufs/ufsmount.h>
1.1       mycroft    54: #include <ufs/ufs/inode.h>
                     55: #include <ufs/ufs/ufs_extern.h>
1.9       bouyer     56: #include <ufs/ufs/ufs_bswap.h>
1.1       mycroft    57:
                     58: #include <ufs/ffs/fs.h>
                     59: #include <ufs/ffs/ffs_extern.h>
                     60:
1.23      chs        61: #include <uvm/uvm.h>
                     62:
1.1       mycroft    63: /*
                     64:  * Balloc defines the structure of file system storage
                     65:  * by allocating the physical blocks on a device given
                     66:  * the inode and the logical block number in a file.
                     67:  */
1.3       christos   68: int
1.15      fvdl       69: ffs_balloc(v)
                     70:        void *v;
                     71: {
                     72:        struct vop_balloc_args /* {
                     73:                struct vnode *a_vp;
1.23.2.3  nathanw    74:                off_t a_startoffset;
1.15      fvdl       75:                int a_size;
                     76:                struct ucred *a_cred;
                     77:                int a_flags;
1.23      chs        78:                struct buf **a_bpp;
1.15      fvdl       79:        } */ *ap = v;
                     80:        ufs_daddr_t lbn;
1.1       mycroft    81:        int size;
                     82:        struct ucred *cred;
                     83:        int flags;
1.15      fvdl       84:        ufs_daddr_t nb;
1.1       mycroft    85:        struct buf *bp, *nbp;
1.15      fvdl       86:        struct vnode *vp = ap->a_vp;
                     87:        struct inode *ip = VTOI(vp);
                     88:        struct fs *fs = ip->i_fs;
1.1       mycroft    89:        struct indir indirs[NIADDR + 2];
1.8       fvdl       90:        ufs_daddr_t newb, *bap, pref;
                     91:        int deallocated, osize, nsize, num, i, error;
                     92:        ufs_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
1.17      fvdl       93:        int unwindidx = -1;
1.23      chs        94:        struct buf **bpp = ap->a_bpp;
1.15      fvdl       95: #ifdef FFS_EI
                     96:        const int needswap = UFS_FSNEEDSWAP(fs);
                     97: #endif
1.23      chs        98:        UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist);
1.1       mycroft    99:
1.15      fvdl      100:        lbn = lblkno(fs, ap->a_startoffset);
                    101:        size = blkoff(fs, ap->a_startoffset) + ap->a_size;
                    102:        if (size > fs->fs_bsize)
                    103:                panic("ffs_balloc: blk too big");
1.23      chs       104:        if (bpp != NULL) {
                    105:                *bpp = NULL;
                    106:        }
                    107:        UVMHIST_LOG(ubchist, "vp %p lbn 0x%x size 0x%x", vp, lbn, size,0);
                    108:
                    109:        KASSERT(size <= fs->fs_bsize);
1.8       fvdl      110:        if (lbn < 0)
1.1       mycroft   111:                return (EFBIG);
1.15      fvdl      112:        cred = ap->a_cred;
                    113:        flags = ap->a_flags;
1.1       mycroft   114:
                    115:        /*
                    116:         * If the next write will extend the file into a new block,
                    117:         * and the file is currently composed of a fragment
                    118:         * this fragment has to be extended to be a full block.
                    119:         */
1.23      chs       120:
1.4       bouyer    121:        nb = lblkno(fs, ip->i_ffs_size);
1.8       fvdl      122:        if (nb < NDADDR && nb < lbn) {
1.1       mycroft   123:                osize = blksize(fs, ip, nb);
                    124:                if (osize < fs->fs_bsize && osize > 0) {
                    125:                        error = ffs_realloccg(ip, nb,
1.4       bouyer    126:                                ffs_blkpref(ip, nb, (int)nb, &ip->i_ffs_db[0]),
1.23      chs       127:                                osize, (int)fs->fs_bsize, cred, bpp, &newb);
1.1       mycroft   128:                        if (error)
                    129:                                return (error);
1.15      fvdl      130:                        if (DOINGSOFTDEP(vp))
1.23      chs       131:                                softdep_setup_allocdirect(ip, nb, newb,
1.15      fvdl      132:                                    ufs_rw32(ip->i_ffs_db[nb], needswap),
1.23      chs       133:                                    fs->fs_bsize, osize, bpp ? *bpp : NULL);
                    134:                        ip->i_ffs_size = lblktosize(fs, nb + 1);
1.6       mrg       135:                        uvm_vnp_setsize(vp, ip->i_ffs_size);
1.23      chs       136:                        ip->i_ffs_db[nb] = ufs_rw32(newb, needswap);
1.1       mycroft   137:                        ip->i_flag |= IN_CHANGE | IN_UPDATE;
1.23      chs       138:                        if (bpp) {
                    139:                                if (flags & B_SYNC)
                    140:                                        bwrite(*bpp);
                    141:                                else
                    142:                                        bawrite(*bpp);
                    143:                        }
1.1       mycroft   144:                }
                    145:        }
1.23      chs       146:
1.1       mycroft   147:        /*
                    148:         * The first NDADDR blocks are direct blocks
                    149:         */
1.23      chs       150:
1.8       fvdl      151:        if (lbn < NDADDR) {
1.15      fvdl      152:                nb = ufs_rw32(ip->i_ffs_db[lbn], needswap);
1.23      chs       153:                if (nb != 0 && ip->i_ffs_size >= lblktosize(fs, lbn + 1)) {
                    154:
                    155:                        /*
                    156:                         * The block is an already-allocated direct block
                    157:                         * and the file already extends past this block,
                    158:                         * thus this must be a whole block.
                    159:                         * Just read the block (if requested).
                    160:                         */
                    161:
                    162:                        if (bpp != NULL) {
                    163:                                error = bread(vp, lbn, fs->fs_bsize, NOCRED,
                    164:                                              bpp);
                    165:                                if (error) {
                    166:                                        brelse(*bpp);
                    167:                                        return (error);
                    168:                                }
1.1       mycroft   169:                        }
                    170:                        return (0);
                    171:                }
                    172:                if (nb != 0) {
1.23      chs       173:
1.1       mycroft   174:                        /*
                    175:                         * Consider need to reallocate a fragment.
                    176:                         */
1.23      chs       177:
1.4       bouyer    178:                        osize = fragroundup(fs, blkoff(fs, ip->i_ffs_size));
1.1       mycroft   179:                        nsize = fragroundup(fs, size);
                    180:                        if (nsize <= osize) {
1.23      chs       181:
                    182:                                /*
                    183:                                 * The existing block is already
                    184:                                 * at least as big as we want.
                    185:                                 * Just read the block (if requested).
                    186:                                 */
                    187:
                    188:                                if (bpp != NULL) {
                    189:                                        error = bread(vp, lbn, osize, NOCRED,
                    190:                                                      bpp);
                    191:                                        if (error) {
                    192:                                                brelse(*bpp);
                    193:                                                return (error);
                    194:                                        }
1.1       mycroft   195:                                }
1.23      chs       196:                                return 0;
1.1       mycroft   197:                        } else {
1.23      chs       198:
                    199:                                /*
                    200:                                 * The existing block is smaller than we want,
                    201:                                 * grow it.
                    202:                                 */
                    203:
1.8       fvdl      204:                                error = ffs_realloccg(ip, lbn,
                    205:                                    ffs_blkpref(ip, lbn, (int)lbn,
                    206:                                        &ip->i_ffs_db[0]), osize, nsize, cred,
1.23      chs       207:                                        bpp, &newb);
1.1       mycroft   208:                                if (error)
                    209:                                        return (error);
1.15      fvdl      210:                                if (DOINGSOFTDEP(vp))
                    211:                                        softdep_setup_allocdirect(ip, lbn,
1.23      chs       212:                                            newb, nb, nsize, osize,
                    213:                                            bpp ? *bpp : NULL);
1.1       mycroft   214:                        }
                    215:                } else {
1.23      chs       216:
                    217:                        /*
                    218:                         * the block was not previously allocated,
                    219:                         * allocate a new block or fragment.
                    220:                         */
                    221:
                    222:                        if (ip->i_ffs_size < lblktosize(fs, lbn + 1))
1.1       mycroft   223:                                nsize = fragroundup(fs, size);
                    224:                        else
                    225:                                nsize = fs->fs_bsize;
1.8       fvdl      226:                        error = ffs_alloc(ip, lbn,
                    227:                            ffs_blkpref(ip, lbn, (int)lbn, &ip->i_ffs_db[0]),
                    228:                                nsize, cred, &newb);
1.1       mycroft   229:                        if (error)
                    230:                                return (error);
1.23      chs       231:                        if (bpp != NULL) {
                    232:                                bp = getblk(vp, lbn, nsize, 0, 0);
                    233:                                bp->b_blkno = fsbtodb(fs, newb);
                    234:                                if (flags & B_CLRBUF)
                    235:                                        clrbuf(bp);
                    236:                                *bpp = bp;
                    237:                        }
                    238:                        if (DOINGSOFTDEP(vp)) {
1.15      fvdl      239:                                softdep_setup_allocdirect(ip, lbn, newb, 0,
1.23      chs       240:                                    nsize, 0, bpp ? *bpp : NULL);
                    241:                        }
1.1       mycroft   242:                }
1.23      chs       243:                ip->i_ffs_db[lbn] = ufs_rw32(newb, needswap);
1.1       mycroft   244:                ip->i_flag |= IN_CHANGE | IN_UPDATE;
                    245:                return (0);
                    246:        }
                    247:        /*
                    248:         * Determine the number of levels of indirection.
                    249:         */
                    250:        pref = 0;
1.8       fvdl      251:        if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
1.1       mycroft   252:                return(error);
1.23      chs       253:
1.1       mycroft   254: #ifdef DIAGNOSTIC
                    255:        if (num < 1)
                    256:                panic ("ffs_balloc: ufs_bmaparray returned indirect block\n");
                    257: #endif
                    258:        /*
                    259:         * Fetch the first indirect block allocating if necessary.
                    260:         */
                    261:        --num;
1.15      fvdl      262:        nb = ufs_rw32(ip->i_ffs_ib[indirs[0].in_off], needswap);
1.8       fvdl      263:        allocib = NULL;
                    264:        allocblk = allociblk;
1.1       mycroft   265:        if (nb == 0) {
1.8       fvdl      266:                pref = ffs_blkpref(ip, lbn, 0, (ufs_daddr_t *)0);
1.18      mycroft   267:                error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
                    268:                    &newb);
1.3       christos  269:                if (error)
1.1       mycroft   270:                        return (error);
                    271:                nb = newb;
1.8       fvdl      272:                *allocblk++ = nb;
1.1       mycroft   273:                bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0);
1.8       fvdl      274:                bp->b_blkno = fsbtodb(fs, nb);
1.1       mycroft   275:                clrbuf(bp);
1.15      fvdl      276:                if (DOINGSOFTDEP(vp)) {
                    277:                        softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off,
                    278:                            newb, 0, fs->fs_bsize, 0, bp);
                    279:                        bdwrite(bp);
                    280:                } else {
                    281:                        /*
                    282:                         * Write synchronously so that indirect blocks
                    283:                         * never point at garbage.
                    284:                         */
                    285:                        if ((error = bwrite(bp)) != 0)
                    286:                                goto fail;
                    287:                }
1.18      mycroft   288:                unwindidx = 0;
1.8       fvdl      289:                allocib = &ip->i_ffs_ib[indirs[0].in_off];
1.15      fvdl      290:                *allocib = ufs_rw32(nb, needswap);
1.1       mycroft   291:                ip->i_flag |= IN_CHANGE | IN_UPDATE;
                    292:        }
                    293:        /*
                    294:         * Fetch through the indirect blocks, allocating as necessary.
                    295:         */
                    296:        for (i = 1;;) {
                    297:                error = bread(vp,
                    298:                    indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
                    299:                if (error) {
                    300:                        brelse(bp);
1.8       fvdl      301:                        goto fail;
1.1       mycroft   302:                }
1.8       fvdl      303:                bap = (ufs_daddr_t *)bp->b_data;
1.15      fvdl      304:                nb = ufs_rw32(bap[indirs[i].in_off], needswap);
1.1       mycroft   305:                if (i == num)
                    306:                        break;
1.18      mycroft   307:                i++;
1.1       mycroft   308:                if (nb != 0) {
                    309:                        brelse(bp);
                    310:                        continue;
                    311:                }
                    312:                if (pref == 0)
1.8       fvdl      313:                        pref = ffs_blkpref(ip, lbn, 0, (ufs_daddr_t *)0);
1.3       christos  314:                error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
1.18      mycroft   315:                    &newb);
1.3       christos  316:                if (error) {
1.1       mycroft   317:                        brelse(bp);
1.8       fvdl      318:                        goto fail;
1.1       mycroft   319:                }
                    320:                nb = newb;
1.8       fvdl      321:                *allocblk++ = nb;
1.1       mycroft   322:                nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0);
                    323:                nbp->b_blkno = fsbtodb(fs, nb);
                    324:                clrbuf(nbp);
1.15      fvdl      325:                if (DOINGSOFTDEP(vp)) {
                    326:                        softdep_setup_allocindir_meta(nbp, ip, bp,
                    327:                            indirs[i - 1].in_off, nb);
                    328:                        bdwrite(nbp);
                    329:                } else {
                    330:                        /*
                    331:                         * Write synchronously so that indirect blocks
                    332:                         * never point at garbage.
                    333:                         */
                    334:                        if ((error = bwrite(nbp)) != 0) {
                    335:                                brelse(bp);
                    336:                                goto fail;
                    337:                        }
1.1       mycroft   338:                }
1.18      mycroft   339:                if (unwindidx < 0)
                    340:                        unwindidx = i - 1;
1.15      fvdl      341:                bap[indirs[i - 1].in_off] = ufs_rw32(nb, needswap);
1.1       mycroft   342:                /*
                    343:                 * If required, write synchronously, otherwise use
                    344:                 * delayed write.
                    345:                 */
                    346:                if (flags & B_SYNC) {
                    347:                        bwrite(bp);
                    348:                } else {
                    349:                        bdwrite(bp);
                    350:                }
                    351:        }
                    352:        /*
                    353:         * Get the data block, allocating if necessary.
                    354:         */
                    355:        if (nb == 0) {
1.19      mycroft   356:                pref = ffs_blkpref(ip, lbn, indirs[num].in_off, &bap[0]);
1.3       christos  357:                error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
1.18      mycroft   358:                    &newb);
1.3       christos  359:                if (error) {
1.1       mycroft   360:                        brelse(bp);
1.8       fvdl      361:                        goto fail;
1.1       mycroft   362:                }
                    363:                nb = newb;
1.8       fvdl      364:                *allocblk++ = nb;
1.23      chs       365:                if (bpp != NULL) {
                    366:                        nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
                    367:                        nbp->b_blkno = fsbtodb(fs, nb);
                    368:                        if (flags & B_CLRBUF)
                    369:                                clrbuf(nbp);
                    370:                        *bpp = nbp;
                    371:                }
1.15      fvdl      372:                if (DOINGSOFTDEP(vp))
                    373:                        softdep_setup_allocindir_page(ip, lbn, bp,
1.23      chs       374:                            indirs[num].in_off, nb, 0, bpp ? *bpp : NULL);
1.19      mycroft   375:                bap[indirs[num].in_off] = ufs_rw32(nb, needswap);
1.23      chs       376:                if (allocib == NULL && unwindidx < 0) {
                    377:                        unwindidx = i - 1;
                    378:                }
1.1       mycroft   379:                /*
                    380:                 * If required, write synchronously, otherwise use
                    381:                 * delayed write.
                    382:                 */
                    383:                if (flags & B_SYNC) {
                    384:                        bwrite(bp);
                    385:                } else {
                    386:                        bdwrite(bp);
                    387:                }
                    388:                return (0);
                    389:        }
                    390:        brelse(bp);
1.23      chs       391:        if (bpp != NULL) {
                    392:                if (flags & B_CLRBUF) {
                    393:                        error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
                    394:                        if (error) {
                    395:                                brelse(nbp);
                    396:                                goto fail;
                    397:                        }
                    398:                } else {
                    399:                        nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
                    400:                        nbp->b_blkno = fsbtodb(fs, nb);
                    401:                        clrbuf(nbp);
1.1       mycroft   402:                }
1.23      chs       403:                *bpp = nbp;
1.1       mycroft   404:        }
                    405:        return (0);
1.8       fvdl      406: fail:
                    407:        /*
                    408:         * If we have failed part way through block allocation, we
                    409:         * have to deallocate any indirect blocks that we have allocated.
1.16      fvdl      410:         * We have to fsync the file before we start to get rid of all
                    411:         * of its dependencies so that we do not leave them dangling.
                    412:         * We have to sync it at the end so that the soft updates code
                    413:         * does not find any untracked changes. Although this is really
                    414:         * slow, running out of disk space is not expected to be a common
                    415:         * occurence. The error return from fsync is ignored as we already
                    416:         * have an error to return to the user.
1.8       fvdl      417:         */
1.23.2.1  nathanw   418:        (void) VOP_FSYNC(vp, cred, FSYNC_WAIT, 0, 0, curproc->l_proc);
1.8       fvdl      419:        for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {
                    420:                ffs_blkfree(ip, *blkp, fs->fs_bsize);
                    421:                deallocated += fs->fs_bsize;
                    422:        }
1.18      mycroft   423:        if (unwindidx >= 0) {
                    424:                if (unwindidx == 0) {
                    425:                        *allocib = 0;
1.17      fvdl      426:                } else {
1.18      mycroft   427:                        int r;
                    428:
                    429:                        r = bread(vp, indirs[unwindidx].in_lbn,
                    430:                            (int)fs->fs_bsize, NOCRED, &bp);
                    431:                        if (r) {
                    432:                                panic("Could not unwind indirect block, error %d", r);
                    433:                                brelse(bp);
                    434:                        } else {
                    435:                                bap = (ufs_daddr_t *)bp->b_data;
                    436:                                bap[indirs[unwindidx].in_off] = 0;
                    437:                                if (flags & B_SYNC)
                    438:                                        bwrite(bp);
                    439:                                else
                    440:                                        bdwrite(bp);
                    441:                        }
1.17      fvdl      442:                }
1.19      mycroft   443:                for (i = unwindidx + 1; i <= num; i++) {
                    444:                        bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0,
                    445:                            0);
                    446:                        bp->b_flags |= B_INVAL;
                    447:                        brelse(bp);
                    448:                }
1.17      fvdl      449:        }
1.8       fvdl      450:        if (deallocated) {
                    451: #ifdef QUOTA
                    452:                /*
                    453:                 * Restore user's disk quota because allocation failed.
                    454:                 */
                    455:                (void)chkdq(ip, (long)-btodb(deallocated), cred, FORCE);
                    456: #endif
                    457:                ip->i_ffs_blocks -= btodb(deallocated);
1.13      mycroft   458:                ip->i_flag |= IN_CHANGE | IN_UPDATE;
1.8       fvdl      459:        }
1.23.2.1  nathanw   460:        (void) VOP_FSYNC(vp, cred, FSYNC_WAIT, 0, 0, curproc->l_proc);
1.8       fvdl      461:        return (error);
1.23      chs       462: }
                    463:
                    464:
                    465: int
1.23.2.4! nathanw   466: ffs_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags,
        !           467:     struct ucred *cred)
1.23      chs       468: {
                    469:        struct inode *ip = VTOI(vp);
                    470:        struct fs *fs = ip->i_fs;
                    471:        int error, delta, bshift, bsize;
1.23.2.4! nathanw   472:        UVMHIST_FUNC("ffs_gop_alloc"); UVMHIST_CALLED(ubchist);
1.23      chs       473:
                    474:        error = 0;
                    475:        bshift = fs->fs_bshift;
                    476:        bsize = 1 << bshift;
                    477:
                    478:        delta = off & (bsize - 1);
                    479:        off -= delta;
                    480:        len += delta;
                    481:
                    482:        while (len > 0) {
1.23.2.4! nathanw   483:                bsize = MIN(bsize, len);
1.23      chs       484:
1.23.2.4! nathanw   485:                error = VOP_BALLOC(vp, off, bsize, cred, flags, NULL);
1.23      chs       486:                if (error) {
                    487:                        goto out;
                    488:                }
                    489:
                    490:                /*
                    491:                 * increase file size now, VOP_BALLOC() requires that
                    492:                 * EOF be up-to-date before each call.
                    493:                 */
                    494:
                    495:                if (ip->i_ffs_size < off + bsize) {
1.23.2.4! nathanw   496:                        UVMHIST_LOG(ubchist, "vp %p old 0x%x new 0x%x",
        !           497:                            vp, ip->i_ffs_size, off + bsize, 0);
1.23      chs       498:                        ip->i_ffs_size = off + bsize;
                    499:                }
                    500:
                    501:                off += bsize;
                    502:                len -= bsize;
                    503:        }
                    504:
                    505: out:
                    506:        return error;
1.1       mycroft   507: }

CVSweb <webmaster@jp.NetBSD.org>