xref: /csrg-svn/sys/ufs/lfs/lfs_balloc.c (revision 56609)
123396Smckusick /*
251494Sbostic  * Copyright (c) 1989, 1991 Regents of the University of California.
337736Smckusick  * All rights reserved.
423396Smckusick  *
544537Sbostic  * %sccs.include.redist.c%
637736Smckusick  *
7*56609Smargo  *	@(#)lfs_balloc.c	7.39 (Berkeley) 10/22/92
823396Smckusick  */
951486Sbostic #include <sys/param.h>
1051486Sbostic #include <sys/buf.h>
1151486Sbostic #include <sys/proc.h>
1251486Sbostic #include <sys/vnode.h>
1351486Sbostic #include <sys/mount.h>
1451486Sbostic #include <sys/resourcevar.h>
1551486Sbostic #include <sys/trace.h>
167443Sroot 
1755048Smckusick #include <miscfs/specfs/specdev.h>
1855048Smckusick 
1951494Sbostic #include <ufs/ufs/quota.h>
2051494Sbostic #include <ufs/ufs/inode.h>
2151494Sbostic #include <ufs/ufs/ufsmount.h>
2247571Skarels 
2351494Sbostic #include <ufs/lfs/lfs.h>
2451494Sbostic #include <ufs/lfs/lfs_extern.h>
2551486Sbostic 
2651855Sbostic int
2752082Sbostic lfs_balloc(vp, iosize, lbn, bpp)
2852082Sbostic 	struct vnode *vp;
2952082Sbostic 	u_long iosize;
3052082Sbostic 	daddr_t lbn;
3152082Sbostic 	struct buf **bpp;
3252082Sbostic {
33*56609Smargo 	struct buf *ibp, *bp;
3452082Sbostic 	struct inode *ip;
3552082Sbostic 	struct lfs *fs;
36*56609Smargo 	struct indir indirs[NIADDR+2];
3752082Sbostic 	daddr_t daddr;
38*56609Smargo 	int bb, error, i, num;
3952082Sbostic 
4052082Sbostic 	ip = VTOI(vp);
4152082Sbostic 	fs = ip->i_lfs;
4252082Sbostic 
4352082Sbostic 	/*
4452082Sbostic 	 * Three cases: it's a block beyond the end of file, it's a block in
4552082Sbostic 	 * the file that may or may not have been assigned a disk address or
4652082Sbostic 	 * we're writing an entire block.  Note, if the daddr is unassigned,
47*56609Smargo 	 * the block might still have existed in the cache (if it was read
48*56609Smargo 	 * or written earlier).  If it did, make sure we don't count it as a
49*56609Smargo 	 * new block or zero out its contents.  If it did not, make sure
50*56609Smargo 	 * we allocate any necessary indirect blocks.
5152082Sbostic 	 */
5255942Sbostic 
5355942Sbostic 	*bpp = NULL;
54*56609Smargo 	if (error = ufs_bmaparray(vp, lbn, &daddr, &indirs[0], &num, NULL ))
5552994Sbostic 		return (error);
5652082Sbostic 
57*56609Smargo 	*bpp = bp = getblk(vp, lbn, fs->lfs_bsize);
58*56609Smargo 	bb = VFSTOUFS(vp->v_mount)->um_seqinc;
59*56609Smargo 	if (daddr == UNASSIGNED)
60*56609Smargo 		/* May need to allocate indirect blocks */
61*56609Smargo 		for (i = 1; i < num; ++i)
62*56609Smargo 			if (!indirs[i].in_exists) {
63*56609Smargo 				ibp =
64*56609Smargo 				    getblk(vp, indirs[i].in_lbn, fs->lfs_bsize);
65*56609Smargo 				if (!(ibp->b_flags & (B_DONE | B_DELWRI))) {
66*56609Smargo 					if (!ISSPACE(fs, bb, curproc->p_ucred)){
67*56609Smargo 						ibp->b_flags |= B_INVAL;
68*56609Smargo 						brelse(ibp);
69*56609Smargo 						error = ENOSPC;
70*56609Smargo 					} else {
71*56609Smargo 						ip->i_blocks += bb;
72*56609Smargo 						ip->i_lfs->lfs_bfree -= bb;
73*56609Smargo 						clrbuf(ibp);
74*56609Smargo 						error = VOP_BWRITE(ibp);
75*56609Smargo 					}
76*56609Smargo 				} else
77*56609Smargo 					panic ("Indirect block should not exist");
78*56609Smargo 			}
79*56609Smargo 	if (error) {
80*56609Smargo 		if (bp)
81*56609Smargo 			brelse(bp);
82*56609Smargo 		return(error);
83*56609Smargo 	}
84*56609Smargo 
85*56609Smargo 
86*56609Smargo 	/* Now, we may need to allocate the data block */
87*56609Smargo 	if (!(bp->b_flags & (B_CACHE | B_DONE | B_DELWRI))) {
88*56609Smargo 		if (daddr == UNASSIGNED)
89*56609Smargo 			if (!ISSPACE(fs, bb, curproc->p_ucred)) {
9056160Smargo 				bp->b_flags |= B_INVAL;
9156160Smargo 				brelse(bp);
92*56609Smargo 				return(ENOSPC);
93*56609Smargo 			} else {
94*56609Smargo 				ip->i_blocks += bb;
95*56609Smargo 				ip->i_lfs->lfs_bfree -= bb;
96*56609Smargo 				if (iosize != fs->lfs_bsize)
97*56609Smargo 					clrbuf(bp);
9856160Smargo 			}
99*56609Smargo 		else if (iosize == fs->lfs_bsize)
100*56609Smargo 			bp->b_blkno = daddr;		/* Skip the I/O */
101*56609Smargo 		else  {
102*56609Smargo 			bp->b_blkno = daddr;
103*56609Smargo 			VOP_STRATEGY(bp);
10452082Sbostic 		}
10552082Sbostic 	}
106*56609Smargo 	return (error);
10752082Sbostic }
108