[OpenAFS-devel] patch to use kmap instead of afs_linux_page_address

Chas Williams chas@cmf.nrl.navy.mil
Mon, 2 Apr 2001 08:38:02 -0400


here is a little patch to use kmap instead of afs_linux_page_address 
(atleast on the 2.4.0 kernels and up)  kmap seems to be the preferred
interface now.  the 2.4 port already uses kmap half of the time.  this
just finishes the job.  i have also included a little patch for 
read_symlink.  it was unlocking before it had finished modifying the
inode.  probably not a big deal.

--- osi_vnodeops.c	Thu Mar 29 18:12:38 2001
+++ /afs/cmf/project/openafs/src/afs/LINUX/osi_vnodeops.c	Mon Apr  2 08:18:30 2001
@@ -1109,7 +1073,13 @@
 {
     int code;
     cred_t *credp = crref();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+    char *address;
+    loff_t offset = pp->index << PAGE_CACHE_SHIFT;
+#else
     ulong address = afs_linux_page_address(pp);
+    loff_t offset = pageoff(pp);
+#endif
     uio_t tuio;
     struct iovec iovec;
     struct inode *ip = FILE_INODE(fp);
@@ -1121,26 +1091,22 @@
 	       ICL_TYPE_POINTER, pp,
 	       ICL_TYPE_INT32, cnt,
 	       ICL_TYPE_INT32, 99999); /* not a possible code value */
-    atomic_add(1, &pp->count);
-#if defined(AFS_LINUX24_ENV)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+    address = kmap(pp);
     ClearPageError(pp);
+
+    lock_kernel();
 #else
+    atomic_add(1, &pp->count);
     set_bit(PG_locked, &pp->flags); /* other bits? See mm.h */
     clear_bit(PG_error, &pp->flags);
 #endif
 
-#if defined(AFS_LINUX24_ENV)
-    setup_uio(&tuio, &iovec, (char*)address, pp->index << PAGE_CACHE_SHIFT,
-	      PAGESIZE, UIO_READ, AFS_UIOSYS);
-#else
-    setup_uio(&tuio, &iovec, (char*)address, pageoff(pp), PAGESIZE,
+    setup_uio(&tuio, &iovec, (char*)address, offset, PAGESIZE,
 	      UIO_READ, AFS_UIOSYS);
-#endif
-#if defined(AFS_LINUX24_ENV)
-    lock_kernel();
-#endif
     code = afs_rdwr((struct vcache*)ip, &tuio, UIO_READ, 0, credp);
-#if defined(AFS_LINUX24_ENV)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     unlock_kernel();
 #endif
 
@@ -1148,23 +1114,22 @@
 	if (tuio.uio_resid) /* zero remainder of page */
 	    memset((void*)(address+(PAGESIZE-tuio.uio_resid)), 0,
 		   tuio.uio_resid);
-#if defined(AFS_LINUX24_ENV)
-#ifndef __powerpc__
-        flush_dcache_page(pp);
-#endif
-        SetPageUptodate(pp);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	flush_dcache_page(pp);
+	SetPageUptodate(pp);
 #else
 	set_bit(PG_uptodate, &pp->flags);
 #endif
     }
 
-#if defined(AFS_LINUX24_ENV)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+    kunmap(pp);
     UnlockPage(pp);
 #else
     clear_bit(PG_locked, &pp->flags);
     wake_up(&pp->wait);
-#endif
     free_page(address);
+#endif
 
     crfree(credp);
     afs_Trace4(afs_iclSetp, CM_TRACE_READPAGE,
@@ -1202,7 +1167,6 @@
     AFS_GUNLOCK();
     SetPageUptodate(pp);
     UnlockPage(pp);
-    /* kunmap(pp); */
     if (status == offset)
 	return 0;
     else
@@ -1255,21 +1219,23 @@
                         unsigned int count)
 {
     struct vcache *vcp = (struct vcache *) ip;
-    u8 *page_addr = (u8*) afs_linux_page_address(pp);
+    char *buffer;
+    loff_t base;
     int code = 0;
     cred_t *credp;
     uio_t tuio;
     struct iovec iovec;
     int f_flags = 0;
 
+    buffer = kmap(pp) + offset;
+    base = (pp->index << PAGE_CACHE_SHIFT) + offset;
+
     credp = crref();
     afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
               ICL_TYPE_POINTER, pp,
               ICL_TYPE_INT32, atomic_read(&pp->count),
               ICL_TYPE_INT32, 99999);
-    setup_uio(&tuio, &iovec, page_addr + offset,
-             (pp->index << PAGE_CACHE_SHIFT) + offset, count,
-             UIO_WRITE, AFS_UIOSYS);
+    setup_uio(&tuio, &iovec, buffer, base, count, UIO_WRITE, AFS_UIOSYS);
 
     code = afs_write(vcp, &tuio, f_flags, credp, 0);
 
@@ -1282,6 +1248,7 @@
               ICL_TYPE_INT32, code);
 
     crfree(credp);
+    kunmap(pp);
 
     return code;
 }
@@ -1319,7 +1286,7 @@
 	       ICL_TYPE_POINTER, pp,
 	       ICL_TYPE_INT32, atomic_read(&pp->count),
 	       ICL_TYPE_INT32, 99999);
-    setup_uio(&tuio, &iovec, page_addr + offset, pageoff(pp) + offset, count,
+    setup_uio(&tuio, &iovec, page_addr + offset, pp->offset + offset, count,
 	      UIO_WRITE, AFS_UIOSYS);
 
     code = afs_write(vcp, &tuio, fp->f_flags, credp, 0);
@@ -1343,16 +1310,16 @@
 #if defined(AFS_LINUX24_ENV)
 static int afs_linux_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
 {
-    long status;
+    int code;
 
     AFS_GLOCK();
     lock_kernel();
-    status = afs_linux_updatepage(file, page, offset, to-offset);
+    code = afs_linux_updatepage(file, page, offset, to-offset);
     unlock_kernel();
     AFS_GUNLOCK();
     kunmap(page);
 
-    return status;
+    return code;
 }
 
 static int afs_linux_prepare_write(struct file *file, struct page *page,
@@ -1461,18 +1428,22 @@
     AFS_GLOCK();
     lock_kernel();
     code = afs_linux_ireadlink(ip, p, PAGE_SIZE, AFS_UIOSYS);
-    unlock_kernel();
-    AFS_GUNLOCK();
 
     if (code<0)
            goto fail;
     p[code] = '\0';            /* null terminate? */
+    unlock_kernel();
+    AFS_GUNLOCK();
+
     SetPageUptodate(page);
     kunmap(page);
     UnlockPage(page);
     return 0;
 
 fail:
+    unlock_kernel();
+    AFS_GUNLOCK();
+
     SetPageError(page);
     kunmap(page);
     UnlockPage(page);