- if (type != IFBLK) {
- dev = ip->i_dev;
- fs = ip->i_fs;
- bsize = fs->fs_bsize;
- } else
- bsize = BLKDEV_IOSIZE;
- do {
- lbn = u.u_offset / bsize;
- on = u.u_offset % bsize;
- n = MIN((unsigned)(bsize - on), u.u_count);
- if (type != IFBLK) {
- diff = ip->i_size - u.u_offset;
- if (diff <= 0)
- return;
- if (diff < n)
- n = diff;
- bn = fsbtodb(fs, bmap(ip, lbn, B_READ));
- if (u.u_error)
- return;
- size = blksize(fs, ip, lbn);
- } else {
- size = bsize;
- bn = lbn * (BLKDEV_IOSIZE/DEV_BSIZE);
- rablock = bn + (BLKDEV_IOSIZE/DEV_BSIZE);
- rasize = bsize;
- }
- if ((long)bn<0) {
- bp = geteblk(size);
- clrbuf(bp);
- } else if (ip->i_lastr + 1 == lbn)
- bp = breada(dev, bn, size, rablock, rasize);
- else
- bp = bread(dev, bn, size);
- ip->i_lastr = lbn;
- n = MIN(n, size - bp->b_resid);
- if (n != 0) {
-#ifdef UNFAST
- iomove(bp->b_un.b_addr + on, n, B_READ);
-#else
- if (u.u_segflg != 1) {
- if (copyout(bp->b_un.b_addr+on, u.u_base, n)) {
- u.u_error = EFAULT;
- goto bad;
- }
- } else
- bcopy(bp->b_un.b_addr + on, u.u_base, n);
- u.u_base += n;
- u.u_offset += n;
- u.u_count -= n;
-bad:
- ;
-#endif
- }
- if (n + on == bsize || u.u_offset == ip->i_size)
- bp->b_flags |= B_AGE;
- brelse(bp);
- } while (u.u_error == 0 && u.u_count != 0 && n != 0);
+ u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, data);
+ /*
+ * Copy any data to user, size was
+ * already set and checked above.
+ */
+ if (u.u_error == 0 && (com&IOC_OUT) && size)
+ u.u_error = copyout(data, uap->cmarg, (u_int)size);