- register struct a {
- char *fname;
- time_t *tptr;
- } *uap;
- register struct inode *ip;
- time_t tv[2];
- struct timeval tv0, tv1;
-
- uap = (struct a *)u.u_ap;
- if ((ip = owner(1)) == NULL)
- return;
- u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv));
- if (u.u_error == 0) {
- ip->i_flag |= IACC|IUPD|ICHG;
- tv0.tv_sec = tv[0]; tv0.tv_usec = 0;
- tv1.tv_sec = tv[1]; tv1.tv_usec = 0;
- iupdat(ip, &tv0, &tv1, 0);
+ register struct inode *ip = VTOI(vp);
+ register struct fs *fs;
+ struct buf *bp;
+ daddr_t lbn, bn, rablock;
+ int size, rasize, diff, error = 0;
+ long n, on, type;
+
+ if (uio->uio_rw != UIO_READ)
+ panic("ufs_read mode");
+ type = ip->i_mode & IFMT;
+ if (type != IFDIR && type != IFREG && type != IFLNK)
+ panic("ufs_read type");
+ if (uio->uio_resid == 0)
+ return (0);
+ if (uio->uio_offset < 0)
+ return (EINVAL);
+ ip->i_flag |= IACC;
+ fs = ip->i_fs;
+ do {
+ lbn = lblkno(fs, uio->uio_offset);
+ on = blkoff(fs, uio->uio_offset);
+ n = MIN((unsigned)(fs->fs_bsize - on), uio->uio_resid);
+ diff = ip->i_size - uio->uio_offset;
+ if (diff <= 0)
+ return (0);
+ if (diff < n)
+ n = diff;
+ if (error = bmap(ip, lbn, &bn, &rablock, &rasize))
+ return (error);
+ size = blksize(fs, ip, lbn);
+ if ((long)bn < 0) {
+ bp = geteblk(size);
+ clrbuf(bp);
+ } else if (ip->i_lastr + 1 == lbn)
+ error = breada(ip->i_devvp, bn, size, rablock, rasize,
+ NOCRED, &bp);
+ else
+ error = bread(ip->i_devvp, bn, size, NOCRED, &bp);
+ ip->i_lastr = lbn;
+ n = MIN(n, size - bp->b_resid);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
+ error = uiomove(bp->b_un.b_addr + on, (int)n, uio);
+ if (n + on == fs->fs_bsize || uio->uio_offset == ip->i_size)
+ bp->b_flags |= B_AGE;
+ brelse(bp);
+ } while (error == 0 && uio->uio_resid > 0 && n != 0);
+ return (error);
+}
+
+/*
+ * Vnode op for writing.
+ */
+ufs_write(vp, uio, ioflag, cred)
+ register struct vnode *vp;
+ struct uio *uio;
+ int ioflag;
+ struct ucred *cred;
+{
+ register struct inode *ip = VTOI(vp);
+ register struct fs *fs;
+ struct buf *bp;
+ daddr_t lbn, bn;
+ u_long osize;
+ int i, n, on, flags;
+ int count, size, resid, error = 0;
+
+ if (uio->uio_rw != UIO_WRITE)
+ panic("ufs_write mode");
+ switch (vp->v_type) {
+ case VREG:
+ if (ioflag & IO_APPEND)
+ uio->uio_offset = ip->i_size;
+ /* fall through */
+ case VLNK:
+ break;
+
+ case VDIR:
+ if ((ioflag & IO_SYNC) == 0)
+ panic("ufs_write nonsync dir write");
+ break;
+
+ default:
+ panic("ufs_write type");