if (ip->i_e2fs_size < uio->uio_offset + xfersize) {
if (uio->uio_offset + xfersize > ip->i_e2fs_size) {
ext2fs_write(v)	void *v;{	struct vop_write_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int a_ioflag;		struct ucred *a_cred;	} */ *ap = v;	struct vnode *vp;	struct uio *uio;	struct inode *ip;	struct m_ext2fs *fs;	struct buf *bp;	struct proc *p;	ufs_daddr_t lbn;	off_t osize;	int blkoffset, error, flags, ioflag, resid, xfersize;	vsize_t bytelen;	void *win;	off_t oldoff;	boolean_t rv;	ioflag = ap->a_ioflag;	uio = ap->a_uio;	vp = ap->a_vp;	ip = VTOI(vp);	error = 0;#ifdef DIAGNOSTIC	if (uio->uio_rw != UIO_WRITE)		panic("%s: mode", "ext2fs_write");#endif	switch (vp->v_type) {	case VREG:		if (ioflag & IO_APPEND)			uio->uio_offset = ip->i_e2fs_size;		if ((ip->i_e2fs_flags & EXT2_APPEND) &&			uio->uio_offset != ip->i_e2fs_size)			return (EPERM);		/* FALLTHROUGH */	case VLNK:		break;	case VDIR:		if ((ioflag & IO_SYNC) == 0)			panic("%s: nonsync dir write", "ext2fs_write");		break;	default:		panic("%s: type", "ext2fs_write");	}	fs = ip->i_e2fs;	if (uio->uio_offset < 0 ||		(u_int64_t)uio->uio_offset + uio->uio_resid >		((u_int64_t)0x80000000 * fs->e2fs_bsize - 1))		return (EFBIG);	/*	 * Maybe this should be above the vnode op call, but so long as	 * file servers have no limits, I don't think it matters.	 */	p = uio->uio_procp;	if (vp->v_type == VREG && p &&		uio->uio_offset + uio->uio_resid >		p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {		psignal(p, SIGXFSZ);		return (EFBIG);	}	resid = uio->uio_resid;	osize = ip->i_e2fs_size;	if (vp->v_type == VREG) {		while (uio->uio_resid > 0) {			oldoff = uio->uio_offset;			blkoffset = blkoff(fs, uio->uio_offset);			bytelen = MIN(fs->e2fs_bsize - blkoffset,			    uio->uio_resid);			/*			 * XXXUBC if file is mapped and this is the last block,			 * process one page at a time.			 */			error = ext2fs_balloc_range(vp, uio->uio_offset,			    bytelen, ap->a_cred, 0);			if (error) {				break;			}			win = ubc_alloc(&vp->v_uobj, uio->uio_offset,			    &bytelen, UBC_WRITE);			error = uiomove(win, bytelen, uio);			ubc_release(win, 0);			if (error) {				break;			}			/*			 * flush what we just wrote if necessary.			 * XXXUBC simplistic async flushing.			 */			if (oldoff >> 16 != uio->uio_offset >> 16) {				simple_lock(&vp->v_uobj.vmobjlock);				rv = vp->v_uobj.pgops->pgo_flush(				    &vp->v_uobj, (oldoff >> 16) << 16,				    (uio->uio_offset >> 16) << 16, PGO_CLEANIT);				simple_unlock(&vp->v_uobj.vmobjlock);			}		}		goto out;	}	flags = ioflag & IO_SYNC ? B_SYNC : 0;	for (error = 0; uio->uio_resid > 0;) {		lbn = lblkno(fs, uio->uio_offset);		blkoffset = blkoff(fs, uio->uio_offset);		xfersize = MIN(fs->e2fs_bsize - blkoffset, uio->uio_resid);		if (xfersize < fs->e2fs_bsize)			flags |= B_CLRBUF;		else			flags &= ~B_CLRBUF;		error = ext2fs_buf_alloc(ip,		    lbn, blkoffset + xfersize, ap->a_cred, &bp, flags);		if (error)			break;		if (ip->i_e2fs_size < uio->uio_offset + xfersize) {			ip->i_e2fs_size = uio->uio_offset + xfersize;		}		error = uiomove((char *)bp->b_data + blkoffset, xfersize, uio);		if (ioflag & IO_SYNC)			(void)bwrite(bp);		else if (xfersize + blkoffset == fs->e2fs_bsize) {			if (doclusterwrite)				cluster_write(bp, &ip->i_ci, ip->i_e2fs_size);			else				bawrite(bp);		} else			bdwrite(bp);		if (error || xfersize == 0)			break;	}	/*	 * If we successfully wrote any data, and we are not the superuser	 * we clear the setuid and setgid bits as a precaution against	 * tampering.	 */out:	ip->i_flag |= IN_CHANGE | IN_UPDATE;	if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0)		ip->i_e2fs_mode &= ~(ISUID | ISGID);	if (error) {		if (ioflag & IO_UNIT) {			(void)ext2fs_truncate(ip, osize,				ioflag & IO_SYNC, ap->a_cred);			uio->uio_offset -= resid - uio->uio_resid;			uio->uio_resid = resid;		}	} else if (resid > uio->uio_resid && (ioflag & IO_SYNC) == IO_SYNC)		error = ext2fs_update(ip, NULL, NULL, 1);	return (error);}