linux-disable-readahad-20081108
[openafs.git] / src / afs / LINUX / osi_vnodeops.c
index 60b11ca..bb3e499 100644 (file)
@@ -53,6 +53,7 @@ RCSID
 #if defined(AFS_LINUX26_ENV)
 #define LockPage(pp) lock_page(pp)
 #define UnlockPage(pp) unlock_page(pp)
+extern struct backing_dev_info afs_backing_dev_info;
 #endif
 
 extern struct vcache *afs_globalVp;
@@ -94,21 +95,24 @@ afs_linux_read(struct file *fp, char *buf, size_t count, loff_t * offp)
     if (code)
        code = -code;
     else {
-        isize = (i_size_read(fp->f_mapping->host) - 1) >> PAGE_CACHE_SHIFT;
+#if defined(AFS_CACHE_BYPASS)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+       isize = (i_size_read(fp->f_mapping->host) - 1) >> PAGE_CACHE_SHIFT;
         offindex = *offp >> PAGE_CACHE_SHIFT;
         if(offindex > isize) {
             code=0;
             goto done;
         }
-
-           osi_FlushPages(vcp, credp); /* ensure stale pages are gone */
-           AFS_GUNLOCK();
+#endif
+#endif
+       osi_FlushPages(vcp, credp);     /* ensure stale pages are gone */
+       AFS_GUNLOCK();
 #ifdef DO_SYNC_READ
-           code = do_sync_read(fp, buf, count, offp);
+       code = do_sync_read(fp, buf, count, offp);
 #else
-           code = generic_file_read(fp, buf, count, offp);
+       code = generic_file_read(fp, buf, count, offp);
 #endif
-           AFS_GLOCK();
+       AFS_GLOCK();
     }
 
     afs_Trace4(afs_iclSetp, CM_TRACE_READOP, ICL_TYPE_POINTER, vcp,
@@ -1734,6 +1738,8 @@ afs_linux_readpage(struct file *fp, struct page *pp)
         set_bit(PG_locked, &pp->flags);        /* other bits? See mm.h */
         clear_bit(PG_error, &pp->flags);
 #endif
+#if defined(AFS_CACHE_BYPASS)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         /* If the page is past the end of the file, skip it */
         isize = (i_size_read(fp->f_mapping->host) - 1) >> PAGE_CACHE_SHIFT;
         if(pp->index > isize) {
@@ -1741,6 +1747,8 @@ afs_linux_readpage(struct file *fp, struct page *pp)
                           UnlockPage(pp);
                  goto done;
         }
+#endif
+#endif
         /* if bypasscache, receiver frees, else we do */
         auio = osi_Alloc(sizeof(uio_t));
         iovecp = osi_Alloc(sizeof(struct iovec));
@@ -1887,6 +1895,26 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp,
               ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
               ICL_TYPE_INT32, 99999);
 
+    ObtainReadLock(&vcp->lock);
+    if (vcp->states & CPageWrite) {
+       ReleaseReadLock(&vcp->lock);
+       AFS_GUNLOCK();
+       maybe_unlock_kernel();
+       crfree(credp);
+       kunmap(pp);
+#ifdef AFS_LINUX26_ENV
+#if defined(WRITEPAGE_ACTIVATE)
+       return WRITEPAGE_ACTIVATE;
+#else
+       return AOP_WRITEPAGE_ACTIVATE;
+#endif
+#else
+       /* should mark it dirty? */
+       return(0); 
+#endif
+    }
+    ReleaseReadLock(&vcp->lock);
+
     setup_uio(&tuio, &iovec, buffer, base, count, UIO_WRITE, AFS_UIOSYS);
 
     code = afs_write(vcp, &tuio, f_flags, credp, 0);
@@ -2204,6 +2232,7 @@ afs_fill_inode(struct inode *ip, struct vattr *vattr)
     if (vattr)
        vattr2inode(ip, vattr);
 
+    ip->i_mapping->backing_dev_info = &afs_backing_dev_info;
 /* Reset ops if symlink or directory. */
     if (S_ISREG(ip->i_mode)) {
        ip->i_op = &afs_file_iops;