+ if (uio->uio_offset < 0)
+ return (EINVAL);
+ if (uio->uio_resid == 0)
+ return (0);
+ /*
+ * Maybe this should be above the vnode op call, but so long as
+ * file servers have no limits, i don't think it matters
+ */
+ if (vp->v_type == VREG &&
+ uio->uio_offset + uio->uio_resid >
+ u.u_rlimit[RLIMIT_FSIZE].rlim_cur) {
+ psignal(u.u_procp, SIGXFSZ);
+ return (EFBIG);
+ }
+ resid = uio->uio_resid;
+ osize = ip->i_size;
+ fs = ip->i_fs;
+ flags = 0;
+ if (ioflag & IO_SYNC)
+ flags = B_SYNC;
+ do {
+ lbn = lblkno(fs, uio->uio_offset);
+ on = blkoff(fs, uio->uio_offset);
+ n = MIN((unsigned)(fs->fs_bsize - on), uio->uio_resid);
+ if (n < fs->fs_bsize)
+ flags |= B_CLRBUF;
+ else
+ flags &= ~B_CLRBUF;
+ if (error = balloc(ip, lbn, (int)(on + n), &bp, flags))
+ break;
+ bn = bp->b_blkno;
+ if (uio->uio_offset + n > ip->i_size)
+ ip->i_size = uio->uio_offset + n;
+ size = blksize(fs, ip, lbn);
+ count = howmany(size, CLBYTES);
+ for (i = 0; i < count; i++)
+ munhash(ip->i_devvp, bn + i * CLBYTES / DEV_BSIZE);
+ n = MIN(n, size - bp->b_resid);
+ error = uiomove(bp->b_un.b_addr + on, n, uio);
+ if (ioflag & IO_SYNC)
+ (void) bwrite(bp);
+ else if (n + on == fs->fs_bsize) {
+ bp->b_flags |= B_AGE;
+ bawrite(bp);
+ } else
+ bdwrite(bp);
+ ip->i_flag |= IUPD|ICHG;
+ if (cred->cr_uid != 0)
+ ip->i_mode &= ~(ISUID|ISGID);
+ } while (error == 0 && uio->uio_resid > 0 && n != 0);
+ if (error && (ioflag & IO_UNIT)) {
+ (void) itrunc(ip, osize, ioflag & IO_SYNC);
+ uio->uio_offset -= resid - uio->uio_resid;
+ uio->uio_resid = resid;
+ }
+ return (error);
+}
+
+/* ARGSUSED */
+ufs_ioctl(vp, com, data, fflag, cred)
+ struct vnode *vp;
+ int com;
+ caddr_t data;
+ int fflag;
+ struct ucred *cred;
+{
+
+ return (ENOTTY);
+}
+
+/* ARGSUSED */
+ufs_select(vp, which, cred)
+ struct vnode *vp;
+ int which;
+ struct ucred *cred;
+{
+
+ return (1); /* XXX */
+}
+
+/*
+ * Mmap a file
+ *
+ * NB Currently unsupported.
+ */
+/* ARGSUSED */
+ufs_mmap(vp, fflags, cred)
+ struct vnode *vp;
+ int fflags;
+ struct ucred *cred;
+{
+
+ return (EINVAL);