}
-#define FOP_READ(F, B, C) (F)->f_op->read(F, B, (size_t)(C), &(F)->f_pos)
-#define FOP_WRITE(F, B, C) (F)->f_op->write(F, B, (size_t)(C), &(F)->f_pos)
-
/* osi_rdwr
* seek, then read or write to an open inode. addrp points to data in
* kernel space.
osi_rdwr(struct osi_file *osifile, uio_t * uiop, int rw)
{
struct file *filp = osifile->filp;
- KERNEL_SPACE_DECL;
+ mm_segment_t old_fs = {0};
int code = 0;
struct iovec *iov;
- afs_size_t count;
+ size_t count;
unsigned long savelim;
+ loff_t pos;
savelim = current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur;
current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
- if (uiop->uio_seg == AFS_UIOSYS)
- TO_USER_SPACE();
+ if (uiop->uio_seg == AFS_UIOSYS) {
+ /* Switch into user space */
+ old_fs = get_fs();
+ set_fs(get_ds());
+ }
/* seek to the desired position. Return -1 on error. */
- if (filp->f_op->llseek) {
- if (filp->f_op->llseek(filp, (loff_t) uiop->uio_offset, 0) != uiop->uio_offset) {
- code = -1;
- goto out;
- }
- } else
- filp->f_pos = uiop->uio_offset;
+ if (vfs_llseek(filp, (loff_t) uiop->uio_offset, 0) != uiop->uio_offset) {
+ code = -1;
+ goto out;
+ }
while (code == 0 && uiop->uio_resid > 0 && uiop->uio_iovcnt > 0) {
iov = uiop->uio_iov;
continue;
}
+ pos = filp->f_pos;
if (rw == UIO_READ)
- code = FOP_READ(filp, iov->iov_base, count);
+ code = filp->f_op->read(filp, iov->iov_base, count, &pos);
else
- code = FOP_WRITE(filp, iov->iov_base, count);
+ code = filp->f_op->write(filp, iov->iov_base, count, &pos);
+ filp->f_pos = pos;
if (code < 0) {
code = -code;
}
out:
- if (uiop->uio_seg == AFS_UIOSYS)
- TO_KERNEL_SPACE();
+ if (uiop->uio_seg == AFS_UIOSYS) {
+ /* Switch back into kernel space */
+ set_fs(old_fs);
+ }
current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = savelim;