xref: /csrg-svn/sys/ufs/lfs/lfs_balloc.c (revision 56864)
123396Smckusick /*
251494Sbostic  * Copyright (c) 1989, 1991 Regents of the University of California.
337736Smckusick  * All rights reserved.
423396Smckusick  *
544537Sbostic  * %sccs.include.redist.c%
637736Smckusick  *
7*56864Smargo  *	@(#)lfs_balloc.c	7.40 (Berkeley) 11/17/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 {
3356609Smargo 	struct buf *ibp, *bp;
3452082Sbostic 	struct inode *ip;
3552082Sbostic 	struct lfs *fs;
3656609Smargo 	struct indir indirs[NIADDR+2];
3752082Sbostic 	daddr_t daddr;
3856609Smargo 	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,
4756609Smargo 	 * the block might still have existed in the cache (if it was read
4856609Smargo 	 * or written earlier).  If it did, make sure we don't count it as a
4956609Smargo 	 * new block or zero out its contents.  If it did not, make sure
5056609Smargo 	 * we allocate any necessary indirect blocks.
5152082Sbostic 	 */
5255942Sbostic 
5355942Sbostic 	*bpp = NULL;
5456609Smargo 	if (error = ufs_bmaparray(vp, lbn, &daddr, &indirs[0], &num, NULL ))
5552994Sbostic 		return (error);
5652082Sbostic 
5756609Smargo 	*bpp = bp = getblk(vp, lbn, fs->lfs_bsize);
5856609Smargo 	bb = VFSTOUFS(vp->v_mount)->um_seqinc;
5956609Smargo 	if (daddr == UNASSIGNED)
6056609Smargo 		/* May need to allocate indirect blocks */
6156609Smargo 		for (i = 1; i < num; ++i)
6256609Smargo 			if (!indirs[i].in_exists) {
6356609Smargo 				ibp =
6456609Smargo 				    getblk(vp, indirs[i].in_lbn, fs->lfs_bsize);
6556609Smargo 				if (!(ibp->b_flags & (B_DONE | B_DELWRI))) {
6656609Smargo 					if (!ISSPACE(fs, bb, curproc->p_ucred)){
6756609Smargo 						ibp->b_flags |= B_INVAL;
6856609Smargo 						brelse(ibp);
6956609Smargo 						error = ENOSPC;
7056609Smargo 					} else {
7156609Smargo 						ip->i_blocks += bb;
7256609Smargo 						ip->i_lfs->lfs_bfree -= bb;
7356609Smargo 						clrbuf(ibp);
7456609Smargo 						error = VOP_BWRITE(ibp);
7556609Smargo 					}
7656609Smargo 				} else
7756609Smargo 					panic ("Indirect block should not exist");
7856609Smargo 			}
7956609Smargo 	if (error) {
8056609Smargo 		if (bp)
8156609Smargo 			brelse(bp);
8256609Smargo 		return(error);
8356609Smargo 	}
8456609Smargo 
8556609Smargo 
8656609Smargo 	/* Now, we may need to allocate the data block */
8756609Smargo 	if (!(bp->b_flags & (B_CACHE | B_DONE | B_DELWRI))) {
8856609Smargo 		if (daddr == UNASSIGNED)
8956609Smargo 			if (!ISSPACE(fs, bb, curproc->p_ucred)) {
9056160Smargo 				bp->b_flags |= B_INVAL;
9156160Smargo 				brelse(bp);
9256609Smargo 				return(ENOSPC);
9356609Smargo 			} else {
9456609Smargo 				ip->i_blocks += bb;
9556609Smargo 				ip->i_lfs->lfs_bfree -= bb;
9656609Smargo 				if (iosize != fs->lfs_bsize)
9756609Smargo 					clrbuf(bp);
9856160Smargo 			}
9956609Smargo 		else if (iosize == fs->lfs_bsize)
10056609Smargo 			bp->b_blkno = daddr;		/* Skip the I/O */
10156609Smargo 		else  {
10256609Smargo 			bp->b_blkno = daddr;
103*56864Smargo 			bp->b_flags != B_READ;
10456609Smargo 			VOP_STRATEGY(bp);
105*56864Smargo 			return(biowait(bp));
10652082Sbostic 		}
10752082Sbostic 	}
10856609Smargo 	return (error);
10952082Sbostic }
110