summaryrefslogtreecommitdiff
path: root/sys/ufs/ffs/ffs_balloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs/ffs/ffs_balloc.c')
-rw-r--r--sys/ufs/ffs/ffs_balloc.c188
1 files changed, 55 insertions, 133 deletions
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
index 285ca5f2ca7..46daac066d7 100644
--- a/sys/ufs/ffs/ffs_balloc.c
+++ b/sys/ufs/ffs/ffs_balloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_balloc.c,v 1.4 1997/10/06 15:26:29 csapuntz Exp $ */
+/* $OpenBSD: ffs_balloc.c,v 1.5 1997/10/06 20:21:34 deraadt Exp $ */
/* $NetBSD: ffs_balloc.c,v 1.3 1996/02/09 22:22:21 christos Exp $ */
/*
@@ -41,7 +41,6 @@
#include <sys/buf.h>
#include <sys/proc.h>
#include <sys/file.h>
-#include <sys/mount.h>
#include <sys/vnode.h>
#include <vm/vm.h>
@@ -59,44 +58,27 @@
* the inode and the logical block number in a file.
*/
int
-ffs_balloc(v)
- void *v;
-{
- struct vop_balloc_args /* {
- struct vnode *a_vp;
- off_t a_startpoint;
- int a_size;
- struct ucred *a_cred;
- int a_flags;
- struct buf *a_bpp;
- } */ *ap = v;
-
- struct inode *ip;
- daddr_t lbn;
+ffs_balloc(ip, bn, size, cred, bpp, flags)
+ register struct inode *ip;
+ register daddr_t bn;
int size;
struct ucred *cred;
+ struct buf **bpp;
int flags;
- struct fs *fs;
- daddr_t nb;
+{
+ register struct fs *fs;
+ register daddr_t nb;
struct buf *bp, *nbp;
- struct vnode *vp;
+ struct vnode *vp = ITOV(ip);
struct indir indirs[NIADDR + 2];
- daddr_t newb, *bap, pref;
- int deallocated, osize, nsize, num, i, error;
- daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR+1];
+ daddr_t newb, lbn, *bap, pref;
+ int osize, nsize, num, i, error;
- vp = ap->a_vp;
- ip = VTOI(vp);
- fs = ip->i_fs;
- lbn = lblkno(fs, ap->a_startoffset);
- size = blkoff(fs, ap->a_startoffset) + ap->a_size;
- if (size > fs->fs_bsize)
- panic("ffs_balloc; blk too big");
- *ap->a_bpp = NULL;
- if (lbn < 0)
+ *bpp = NULL;
+ if (bn < 0)
return (EFBIG);
- cred = ap->a_cred;
- flags = ap->a_flags;
+ fs = ip->i_fs;
+ lbn = bn;
/*
* If the next write will extend the file into a new block,
@@ -104,7 +86,7 @@ ffs_balloc(v)
* this fragment has to be extended to be a full block.
*/
nb = lblkno(fs, ip->i_ffs_size);
- if (nb < NDADDR && nb < lbn) {
+ if (nb < NDADDR && nb < bn) {
osize = blksize(fs, ip, nb);
if (osize < fs->fs_bsize && osize > 0) {
error = ffs_realloccg(ip, nb,
@@ -112,11 +94,6 @@ ffs_balloc(v)
osize, (int)fs->fs_bsize, cred, &bp);
if (error)
return (error);
- if (DOINGSOFTDEP(vp))
- softdep_setup_allocdirect(ip, nb,
- dbtofsb(fs, bp->b_blkno), ip->i_ffs_db[nb],
- fs->fs_bsize, osize, bp);
-
ip->i_ffs_size = (nb + 1) * fs->fs_bsize;
vnode_pager_setsize(vp, (u_long)ip->i_ffs_size);
ip->i_ffs_db[nb] = dbtofsb(fs, bp->b_blkno);
@@ -130,15 +107,15 @@ ffs_balloc(v)
/*
* The first NDADDR blocks are direct blocks
*/
- if (lbn < NDADDR) {
- nb = ip->i_ffs_db[lbn];
- if (nb != 0 && ip->i_ffs_size >= (lbn + 1) * fs->fs_bsize) {
- error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
+ if (bn < NDADDR) {
+ nb = ip->i_ffs_db[bn];
+ if (nb != 0 && ip->i_ffs_size >= (bn + 1) * fs->fs_bsize) {
+ error = bread(vp, bn, fs->fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
- *ap->a_bpp = bp;
+ *bpp = bp;
return (0);
}
if (nb != 0) {
@@ -148,52 +125,43 @@ ffs_balloc(v)
osize = fragroundup(fs, blkoff(fs, ip->i_ffs_size));
nsize = fragroundup(fs, size);
if (nsize <= osize) {
- error = bread(vp, lbn, osize, NOCRED, &bp);
+ error = bread(vp, bn, osize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
} else {
- error = ffs_realloccg(ip, lbn,
- ffs_blkpref(ip, lbn, (int)lbn,
- &ip->i_ffs_db[0]),
+ error = ffs_realloccg(ip, bn,
+ ffs_blkpref(ip, bn, (int)bn, &ip->i_ffs_db[0]),
osize, nsize, cred, &bp);
if (error)
return (error);
- if (DOINGSOFTDEP(vp))
- softdep_setup_allocdirect(ip, lbn,
- dbtofsb(fs, bp->b_blkno), nb,
- nsize, osize, bp);
}
} else {
- if (ip->i_ffs_size < (lbn + 1) * fs->fs_bsize)
+ if (ip->i_ffs_size < (bn + 1) * fs->fs_bsize)
nsize = fragroundup(fs, size);
else
nsize = fs->fs_bsize;
- error = ffs_alloc(ip, lbn,
- ffs_blkpref(ip, lbn, (int)lbn, &ip->i_ffs_db[0]),
+ error = ffs_alloc(ip, bn,
+ ffs_blkpref(ip, bn, (int)bn, &ip->i_ffs_db[0]),
nsize, cred, &newb);
if (error)
return (error);
- bp = getblk(vp, lbn, nsize, 0, 0);
+ bp = getblk(vp, bn, nsize, 0, 0);
bp->b_blkno = fsbtodb(fs, newb);
if (flags & B_CLRBUF)
clrbuf(bp);
- if (DOINGSOFTDEP(vp))
- softdep_setup_allocdirect(ip, lbn, newb, 0,
- nsize, 0, bp);
-
}
- ip->i_ffs_db[lbn] = dbtofsb(fs, bp->b_blkno);
+ ip->i_ffs_db[bn] = dbtofsb(fs, bp->b_blkno);
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- *ap->a_bpp = bp;
+ *bpp = bp;
return (0);
}
/*
* Determine the number of levels of indirection.
*/
pref = 0;
- if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
+ if ((error = ufs_getlbns(vp, bn, indirs, &num)) != 0)
return(error);
#ifdef DIAGNOSTIC
if (num < 1)
@@ -204,9 +172,6 @@ ffs_balloc(v)
*/
--num;
nb = ip->i_ffs_ib[indirs[0].in_off];
-
- allocib = NULL;
- allocblk = allociblk;
if (nb == 0) {
pref = ffs_blkpref(ip, lbn, 0, (daddr_t *)0);
error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
@@ -214,26 +179,18 @@ ffs_balloc(v)
if (error)
return (error);
nb = newb;
-
- *allocblk++ = nb;
bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0);
- bp->b_blkno = fsbtodb(fs, nb);
+ bp->b_blkno = fsbtodb(fs, newb);
clrbuf(bp);
-
- if (DOINGSOFTDEP(vp)) {
- softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off,
- newb, 0, fs->fs_bsize, 0, bp);
- bdwrite(bp);
- } else {
- /*
- * Write synchronously so that indirect blocks
- * never point at garbage.
- */
- if ((error = bwrite(bp)) != 0)
- goto fail;
- }
- allocib = &ip->i_ffs_ib[indirs[0].in_off];
- *allocib = nb;
+ /*
+ * Write synchronously so that indirect blocks
+ * never point at garbage.
+ */
+ if ((error = bwrite(bp)) != 0) {
+ ffs_blkfree(ip, nb, fs->fs_bsize);
+ return (error);
+ }
+ ip->i_ffs_ib[indirs[0].in_off] = newb;
ip->i_flag |= IN_CHANGE | IN_UPDATE;
}
/*
@@ -244,7 +201,7 @@ ffs_balloc(v)
indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
- goto fail;
+ return (error);
}
bap = (daddr_t *)bp->b_data;
nb = bap[indirs[i].in_off];
@@ -261,27 +218,20 @@ ffs_balloc(v)
&newb);
if (error) {
brelse(bp);
- goto fail;
+ return (error);
}
nb = newb;
- *allocblk++ = nb;
nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0);
nbp->b_blkno = fsbtodb(fs, nb);
clrbuf(nbp);
-
- if (DOINGSOFTDEP(vp)) {
- softdep_setup_allocindir_meta(nbp, ip, bp,
- indirs[i - 1].in_off, nb);
- bdwrite(nbp);
- } else {
- /*
- * Write synchronously so that indirect blocks
- * never point at garbage.
- */
- if ((error = bwrite(nbp)) != 0) {
- brelse(bp);
- goto fail;
- }
+ /*
+ * Write synchronously so that indirect blocks
+ * never point at garbage.
+ */
+ if ((error = bwrite(nbp)) != 0) {
+ ffs_blkfree(ip, nb, fs->fs_bsize);
+ brelse(bp);
+ return (error);
}
bap[indirs[i - 1].in_off] = nb;
/*
@@ -303,17 +253,13 @@ ffs_balloc(v)
&newb);
if (error) {
brelse(bp);
- goto fail;
+ return (error);
}
nb = newb;
- *allocblk++ = nb;
nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
nbp->b_blkno = fsbtodb(fs, nb);
if (flags & B_CLRBUF)
clrbuf(nbp);
- if (DOINGSOFTDEP(vp))
- softdep_setup_allocindir_page(ip, lbn, bp,
- indirs[i].in_off, nb, 0, nbp);
bap[indirs[i].in_off] = nb;
/*
* If required, write synchronously, otherwise use
@@ -324,7 +270,7 @@ ffs_balloc(v)
} else {
bdwrite(bp);
}
- *ap->a_bpp = nbp;
+ *bpp = nbp;
return (0);
}
brelse(bp);
@@ -332,36 +278,12 @@ ffs_balloc(v)
error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
if (error) {
brelse(nbp);
- goto fail;
+ return (error);
}
} else {
nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0);
nbp->b_blkno = fsbtodb(fs, nb);
}
- *ap->a_bpp = nbp;
+ *bpp = nbp;
return (0);
-
-fail:
- /*
- * If we have failed part way through block allocation, we
- * have to deallocate any indirect blocks that we have allocated.
- */
- for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {
- ffs_blkfree(ip, *blkp, fs->fs_bsize);
- deallocated += fs->fs_bsize;
- }
- if (allocib != NULL)
- *allocib = 0;
- if (deallocated) {
-#ifdef QUOTA
- /*
- * Restore user's disk quota because allocation failed.
- */
- (void) chkdq(ip, (long)-btodb(deallocated), cred, FORCE);
-#endif
- ip->i_ffs_blocks -= btodb(deallocated);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- }
- return (error);
-
}