Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/ufs/ffs/ffs_balloc.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/ufs/ffs/ffs_balloc.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.48 retrieving revision 1.48.12.2 diff -u -p -r1.48 -r1.48.12.2 --- src/sys/ufs/ffs/ffs_balloc.c 2008/01/02 11:49:09 1.48 +++ src/sys/ufs/ffs/ffs_balloc.c 2008/09/18 04:37:05 1.48.12.2 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_balloc.c,v 1.48 2008/01/02 11:49:09 ad Exp $ */ +/* $NetBSD: ffs_balloc.c,v 1.48.12.2 2008/09/18 04:37:05 wrstuden Exp $ */ /* * Copyright (c) 2002 Networks Associates Technology, Inc. @@ -41,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ffs_balloc.c,v 1.48 2008/01/02 11:49:09 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_balloc.c,v 1.48.12.2 2008/09/18 04:37:05 wrstuden Exp $"); #if defined(_KERNEL_OPT) #include "opt_quota.h" @@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: ffs_balloc.c #include #include #include +#include #include #include @@ -81,11 +82,17 @@ int ffs_balloc(struct vnode *vp, off_t off, int size, kauth_cred_t cred, int flags, struct buf **bpp) { + int error; if (VTOI(vp)->i_fs->fs_magic == FS_UFS2_MAGIC) - return ffs_balloc_ufs2(vp, off, size, cred, flags, bpp); + error = ffs_balloc_ufs2(vp, off, size, cred, flags, bpp); else - return ffs_balloc_ufs1(vp, off, size, cred, flags, bpp); + error = ffs_balloc_ufs1(vp, off, size, cred, flags, bpp); + + if (error == 0 && bpp != NULL && (error = fscow_run(*bpp, false)) != 0) + brelse(*bpp, 0); + + return error; } static int @@ -134,7 +141,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t if (osize < fs->fs_bsize && osize > 0) { mutex_enter(&ump->um_lock); error = ffs_realloccg(ip, nb, - ffs_blkpref_ufs1(ip, lastlbn, nb, + ffs_blkpref_ufs1(ip, lastlbn, nb, flags, &ip->i_ffs1_db[0]), osize, (int)fs->fs_bsize, cred, bpp, &newb); if (error) @@ -174,7 +181,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t if (bpp != NULL) { error = bread(vp, lbn, fs->fs_bsize, NOCRED, - bpp); + B_MODIFY, bpp); if (error) { brelse(*bpp, 0); return (error); @@ -200,7 +207,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t if (bpp != NULL) { error = bread(vp, lbn, osize, NOCRED, - bpp); + B_MODIFY, bpp); if (error) { brelse(*bpp, 0); return (error); @@ -215,9 +222,9 @@ ffs_balloc_ufs1(struct vnode *vp, off_t */ mutex_enter(&ump->um_lock); error = ffs_realloccg(ip, lbn, - ffs_blkpref_ufs1(ip, lbn, (int)lbn, - &ip->i_ffs1_db[0]), osize, nsize, cred, - bpp, &newb); + ffs_blkpref_ufs1(ip, lbn, (int)lbn, flags, + &ip->i_ffs1_db[0]), + osize, nsize, cred, bpp, &newb); if (error) return (error); if (DOINGSOFTDEP(vp)) @@ -238,17 +245,16 @@ ffs_balloc_ufs1(struct vnode *vp, off_t nsize = fs->fs_bsize; mutex_enter(&ump->um_lock); error = ffs_alloc(ip, lbn, - ffs_blkpref_ufs1(ip, lbn, (int)lbn, + ffs_blkpref_ufs1(ip, lbn, (int)lbn, flags, &ip->i_ffs1_db[0]), - nsize, cred, &newb); + nsize, flags, cred, &newb); if (error) return (error); if (bpp != NULL) { - bp = getblk(vp, lbn, nsize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); - if (flags & B_CLRBUF) - clrbuf(bp); - *bpp = bp; + error = ffs_getblk(vp, lbn, fsbtodb(fs, newb), + nsize, (flags & B_CLRBUF) != 0, bpp); + if (error) + return error; } if (DOINGSOFTDEP(vp)) { softdep_setup_allocdirect(ip, lbn, newb, 0, @@ -278,16 +284,17 @@ ffs_balloc_ufs1(struct vnode *vp, off_t allocblk = allociblk; if (nb == 0) { mutex_enter(&ump->um_lock); - pref = ffs_blkpref_ufs1(ip, lbn, 0, (int32_t *)0); - error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, - &newb); + pref = ffs_blkpref_ufs1(ip, lbn, 0, flags | B_METAONLY, NULL); + error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, + flags | B_METAONLY, cred, &newb); if (error) goto fail; nb = newb; *allocblk++ = nb; - bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0); - bp->b_blkno = fsbtodb(fs, nb); - clrbuf(bp); + error = ffs_getblk(vp, indirs[1].in_lbn, fsbtodb(fs, nb), + fs->fs_bsize, true, &bp); + if (error) + goto fail; if (DOINGSOFTDEP(vp)) { softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, newb, 0, fs->fs_bsize, 0, bp); @@ -314,7 +321,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t for (i = 1;;) { error = bread(vp, - indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp); + indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, 0, &bp); if (error) { brelse(bp, 0); goto fail; @@ -328,20 +335,28 @@ ffs_balloc_ufs1(struct vnode *vp, off_t brelse(bp, 0); continue; } + if (fscow_run(bp, true) != 0) { + brelse(bp, 0); + goto fail; + } mutex_enter(&ump->um_lock); if (pref == 0) - pref = ffs_blkpref_ufs1(ip, lbn, 0, (int32_t *)0); - error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, - &newb); + pref = ffs_blkpref_ufs1(ip, lbn, 0, flags | B_METAONLY, + NULL); + error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, + flags | B_METAONLY, cred, &newb); if (error) { brelse(bp, 0); goto fail; } nb = newb; *allocblk++ = nb; - nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - clrbuf(nbp); + error = ffs_getblk(vp, indirs[i].in_lbn, fsbtodb(fs, nb), + fs->fs_bsize, true, &nbp); + if (error) { + brelse(bp, 0); + goto fail; + } if (DOINGSOFTDEP(vp)) { softdep_setup_allocindir_meta(nbp, ip, bp, indirs[i - 1].in_off, nb); @@ -385,9 +400,14 @@ ffs_balloc_ufs1(struct vnode *vp, off_t */ if (nb == 0) { + if (fscow_run(bp, true) != 0) { + brelse(bp, 0); + goto fail; + } mutex_enter(&ump->um_lock); - pref = ffs_blkpref_ufs1(ip, lbn, indirs[num].in_off, &bap[0]); - error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, + pref = ffs_blkpref_ufs1(ip, lbn, indirs[num].in_off, flags, + &bap[0]); + error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, flags, cred, &newb); if (error) { brelse(bp, 0); @@ -396,11 +416,12 @@ ffs_balloc_ufs1(struct vnode *vp, off_t nb = newb; *allocblk++ = nb; if (bpp != NULL) { - nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - if (flags & B_CLRBUF) - clrbuf(nbp); - *bpp = nbp; + error = ffs_getblk(vp, lbn, fsbtodb(fs, nb), + fs->fs_bsize, (flags & B_CLRBUF) != 0, bpp); + if (error) { + brelse(bp, 0); + goto fail; + } } if (DOINGSOFTDEP(vp)) softdep_setup_allocindir_page(ip, lbn, bp, @@ -425,15 +446,17 @@ ffs_balloc_ufs1(struct vnode *vp, off_t brelse(bp, 0); if (bpp != NULL) { if (flags & B_CLRBUF) { - error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp); + error = bread(vp, lbn, (int)fs->fs_bsize, + NOCRED, B_MODIFY, &nbp); if (error) { brelse(nbp, 0); goto fail; } } else { - nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - clrbuf(nbp); + error = ffs_getblk(vp, lbn, fsbtodb(fs, nb), + fs->fs_bsize, true, &nbp); + if (error) + goto fail; } *bpp = nbp; } @@ -458,14 +481,16 @@ fail: if (i == 0) { break; } - bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, - 0); + if (ffs_getblk(vp, indirs[i].in_lbn, FFS_NOBLK, + fs->fs_bsize, false, &bp) != 0) + continue; if (bp->b_oflags & BO_DELWRI) { nb = fsbtodb(fs, cgtod(fs, dtog(fs, dbtofsb(fs, bp->b_blkno)))); bwrite(bp); - bp = getblk(ip->i_devvp, nb, (int)fs->fs_cgsize, - 0, 0); + if (ffs_getblk(ip->i_devvp, nb, FFS_NOBLK, + fs->fs_cgsize, false, &bp) != 0) + continue; if (bp->b_oflags & BO_DELWRI) { bwrite(bp); } else { @@ -501,7 +526,7 @@ fail: int r; r = bread(vp, indirs[unwindidx].in_lbn, - (int)fs->fs_bsize, NOCRED, &bp); + (int)fs->fs_bsize, NOCRED, 0, &bp); if (r) { panic("Could not unwind indirect block, error %d", r); brelse(bp, 0); @@ -512,9 +537,9 @@ fail: } } for (i = unwindidx + 1; i <= num; i++) { - bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, - 0); - brelse(bp, BC_INVAL); + if (ffs_getblk(vp, indirs[i].in_lbn, FFS_NOBLK, + fs->fs_bsize, false, &bp) == 0) + brelse(bp, BC_INVAL); } } for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) { @@ -596,7 +621,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t error = ffs_realloccg(ip, -1 - nb, dp->di_extb[nb], ffs_blkpref_ufs2(ip, lastlbn, (int)nb, - &dp->di_extb[0]), osize, + flags, &dp->di_extb[0]), + osize, (int)fs->fs_bsize, cred, &bp); if (error) return (error); @@ -622,7 +648,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t panic("ffs_balloc_ufs2: BA_METAONLY for ext block"); nb = dp->di_extb[lbn]; if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) { - error = bread(vp, -1 - lbn, fs->fs_bsize, NOCRED, &bp); + error = bread(vp, -1 - lbn, fs->fs_bsize, + NOCRED, 0, &bp); if (error) { brelse(bp, 0); return (error); @@ -641,7 +668,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t osize = fragroundup(fs, blkoff(fs, dp->di_extsize)); nsize = fragroundup(fs, size); if (nsize <= osize) { - error = bread(vp, -1 - lbn, osize, NOCRED, &bp); + error = bread(vp, -1 - lbn, osize, + NOCRED, 0, &bp); if (error) { brelse(bp, 0); return (error); @@ -654,8 +682,9 @@ ffs_balloc_ufs2(struct vnode *vp, off_t mutex_enter(&ump->um_lock); error = ffs_realloccg(ip, -1 - lbn, dp->di_extb[lbn], - ffs_blkpref_ufs2(ip, lbn, (int)lbn, - &dp->di_extb[0]), osize, nsize, cred, &bp); + ffs_blkpref_ufs2(ip, lbn, (int)lbn, flags, + &dp->di_extb[0]), + osize, nsize, cred, &bp); if (error) return (error); bp->b_xflags |= BX_ALTDATA; @@ -671,15 +700,16 @@ ffs_balloc_ufs2(struct vnode *vp, off_t nsize = fs->fs_bsize; mutex_enter(&ump->um_lock); error = ffs_alloc(ip, lbn, - ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]), - nsize, cred, &newb); + ffs_blkpref_ufs2(ip, lbn, (int)lbn, flags, + &dp->di_extb[0]), + nsize, flags, cred, &newb); if (error) return (error); - bp = getblk(vp, -1 - lbn, nsize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); + error = ffs_getblk(vp, -1 - lbn, fsbtodb(fs, newb), + nsize, (flags & BA_CLRBUF) != 0, &bp); + if (error) + return error; bp->b_xflags |= BX_ALTDATA; - if (flags & BA_CLRBUF) - vfs_bio_clrbuf(bp); if (DOINGSOFTDEP(vp)) softdep_setup_allocext(ip, lbn, newb, 0, nsize, 0, bp); @@ -703,7 +733,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t if (osize < fs->fs_bsize && osize > 0) { mutex_enter(&ump->um_lock); error = ffs_realloccg(ip, nb, - ffs_blkpref_ufs2(ip, lastlbn, nb, + ffs_blkpref_ufs2(ip, lastlbn, nb, flags, &ip->i_ffs2_db[0]), osize, (int)fs->fs_bsize, cred, bpp, &newb); if (error) @@ -743,7 +773,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t if (bpp != NULL) { error = bread(vp, lbn, fs->fs_bsize, NOCRED, - bpp); + B_MODIFY, bpp); if (error) { brelse(*bpp, 0); return (error); @@ -769,7 +799,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t if (bpp != NULL) { error = bread(vp, lbn, osize, NOCRED, - bpp); + B_MODIFY, bpp); if (error) { brelse(*bpp, 0); return (error); @@ -784,9 +814,9 @@ ffs_balloc_ufs2(struct vnode *vp, off_t */ mutex_enter(&ump->um_lock); error = ffs_realloccg(ip, lbn, - ffs_blkpref_ufs2(ip, lbn, (int)lbn, - &ip->i_ffs2_db[0]), osize, nsize, cred, - bpp, &newb); + ffs_blkpref_ufs2(ip, lbn, (int)lbn, flags, + &ip->i_ffs2_db[0]), + osize, nsize, cred, bpp, &newb); if (error) return (error); if (DOINGSOFTDEP(vp)) @@ -807,16 +837,16 @@ ffs_balloc_ufs2(struct vnode *vp, off_t nsize = fs->fs_bsize; mutex_enter(&ump->um_lock); error = ffs_alloc(ip, lbn, - ffs_blkpref_ufs2(ip, lbn, (int)lbn, - &ip->i_ffs2_db[0]), nsize, cred, &newb); + ffs_blkpref_ufs2(ip, lbn, (int)lbn, flags, + &ip->i_ffs2_db[0]), + nsize, flags, cred, &newb); if (error) return (error); if (bpp != NULL) { - bp = getblk(vp, lbn, nsize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); - if (flags & B_CLRBUF) - clrbuf(bp); - *bpp = bp; + error = ffs_getblk(vp, lbn, fsbtodb(fs, newb), + nsize, (flags & B_CLRBUF) != 0, bpp); + if (error) + return error; } if (DOINGSOFTDEP(vp)) { softdep_setup_allocdirect(ip, lbn, newb, 0, @@ -846,16 +876,17 @@ ffs_balloc_ufs2(struct vnode *vp, off_t allocblk = allociblk; if (nb == 0) { mutex_enter(&ump->um_lock); - pref = ffs_blkpref_ufs2(ip, lbn, 0, (int64_t *)0); - error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, - &newb); + pref = ffs_blkpref_ufs2(ip, lbn, 0, flags | B_METAONLY, NULL); + error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, + flags | B_METAONLY, cred, &newb); if (error) goto fail; nb = newb; *allocblk++ = nb; - bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0); - bp->b_blkno = fsbtodb(fs, nb); - clrbuf(bp); + error = ffs_getblk(vp, indirs[1].in_lbn, fsbtodb(fs, nb), + fs->fs_bsize, true, &bp); + if (error) + goto fail; if (DOINGSOFTDEP(vp)) { softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, newb, 0, fs->fs_bsize, 0, bp); @@ -882,7 +913,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t for (i = 1;;) { error = bread(vp, - indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp); + indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, 0, &bp); if (error) { brelse(bp, 0); goto fail; @@ -896,20 +927,28 @@ ffs_balloc_ufs2(struct vnode *vp, off_t brelse(bp, 0); continue; } + if (fscow_run(bp, true) != 0) { + brelse(bp, 0); + goto fail; + } mutex_enter(&ump->um_lock); if (pref == 0) - pref = ffs_blkpref_ufs2(ip, lbn, 0, (int64_t *)0); - error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, - &newb); + pref = ffs_blkpref_ufs2(ip, lbn, 0, flags | B_METAONLY, + NULL); + error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, + flags | B_METAONLY, cred, &newb); if (error) { brelse(bp, 0); goto fail; } nb = newb; *allocblk++ = nb; - nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - clrbuf(nbp); + error = ffs_getblk(vp, indirs[i].in_lbn, fsbtodb(fs, nb), + fs->fs_bsize, true, &nbp); + if (error) { + brelse(bp, 0); + goto fail; + } if (DOINGSOFTDEP(vp)) { softdep_setup_allocindir_meta(nbp, ip, bp, indirs[i - 1].in_off, nb); @@ -953,9 +992,14 @@ ffs_balloc_ufs2(struct vnode *vp, off_t */ if (nb == 0) { + if (fscow_run(bp, true) != 0) { + brelse(bp, 0); + goto fail; + } mutex_enter(&ump->um_lock); - pref = ffs_blkpref_ufs2(ip, lbn, indirs[num].in_off, &bap[0]); - error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, + pref = ffs_blkpref_ufs2(ip, lbn, indirs[num].in_off, flags, + &bap[0]); + error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, flags, cred, &newb); if (error) { brelse(bp, 0); @@ -964,11 +1008,12 @@ ffs_balloc_ufs2(struct vnode *vp, off_t nb = newb; *allocblk++ = nb; if (bpp != NULL) { - nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - if (flags & B_CLRBUF) - clrbuf(nbp); - *bpp = nbp; + error = ffs_getblk(vp, lbn, fsbtodb(fs, nb), + fs->fs_bsize, (flags & B_CLRBUF) != 0, bpp); + if (error) { + brelse(bp, 0); + goto fail; + } } if (DOINGSOFTDEP(vp)) softdep_setup_allocindir_page(ip, lbn, bp, @@ -993,15 +1038,17 @@ ffs_balloc_ufs2(struct vnode *vp, off_t brelse(bp, 0); if (bpp != NULL) { if (flags & B_CLRBUF) { - error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp); + error = bread(vp, lbn, (int)fs->fs_bsize, + NOCRED, B_MODIFY, &nbp); if (error) { brelse(nbp, 0); goto fail; } } else { - nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - clrbuf(nbp); + error = ffs_getblk(vp, lbn, fsbtodb(fs, nb), + fs->fs_bsize, true, &nbp); + if (error) + goto fail; } *bpp = nbp; } @@ -1026,14 +1073,16 @@ fail: if (i == 0) { break; } - bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, - 0); + if (ffs_getblk(vp, indirs[i].in_lbn, FFS_NOBLK, + fs->fs_bsize, false, &bp) != 0) + continue; if (bp->b_oflags & BO_DELWRI) { nb = fsbtodb(fs, cgtod(fs, dtog(fs, dbtofsb(fs, bp->b_blkno)))); bwrite(bp); - bp = getblk(ip->i_devvp, nb, (int)fs->fs_cgsize, - 0, 0); + if (ffs_getblk(ip->i_devvp, nb, FFS_NOBLK, + fs->fs_cgsize, false, &bp) != 0) + continue; if (bp->b_oflags & BO_DELWRI) { bwrite(bp); } else { @@ -1069,7 +1118,7 @@ fail: int r; r = bread(vp, indirs[unwindidx].in_lbn, - (int)fs->fs_bsize, NOCRED, &bp); + (int)fs->fs_bsize, NOCRED, 0, &bp); if (r) { panic("Could not unwind indirect block, error %d", r); brelse(bp, 0); @@ -1080,9 +1129,9 @@ fail: } } for (i = unwindidx + 1; i <= num; i++) { - bp = getblk(vp, indirs[i].in_lbn, (int)fs->fs_bsize, 0, - 0); - brelse(bp, BC_INVAL); + if (ffs_getblk(vp, indirs[i].in_lbn, FFS_NOBLK, + fs->fs_bsize, false, &bp) == 0) + brelse(bp, BC_INVAL); } } for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {