Linux: Don't hide memory management
[openafs.git] / src / afs / LINUX / osi_file.c
index f5e21d5..33c9667 100644 (file)
@@ -363,9 +363,6 @@ osi_InitCacheInfo(char *aname)
 }
 
 
-#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.
@@ -374,26 +371,27 @@ int
 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;
@@ -404,10 +402,12 @@ osi_rdwr(struct osi_file *osifile, uio_t * uiop, int rw)
            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;
@@ -430,8 +430,10 @@ osi_rdwr(struct osi_file *osifile, uio_t * uiop, int rw)
     }
 
 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;