]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
linux-mmap-antirecursion-fix-20090512
authorFelix Frank <Felix.Frank@Desy.de>
Tue, 12 May 2009 18:56:30 +0000 (18:56 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 12 May 2009 18:56:30 +0000 (18:56 +0000)
LICENSE IPL10
FIXES 124627

fix the mmap anti-recursion protection to set and mask CPageWrite appropriately
and with the correct lock protection. this leaves us with an issue to handle
when the mmap'd file is larger (possibly considerably larger) than the
cache

src/afs/LINUX/osi_vm.c
src/afs/LINUX/osi_vnodeops.c

index c96babd6683721d7be6a24a415baca1764d7eec6..55a3737e78e7e49a15f98f6c7d35f482be2416c9 100644 (file)
@@ -102,9 +102,7 @@ osi_VM_StoreAllSegments(struct vcache *avc)
 {
     struct inode *ip = AFSTOV(avc);
 
-    if (!avc->f.states & CPageWrite)
-       avc->f.states |= CPageWrite;
-    else 
+    if (avc->f.states & CPageWrite)
        return; /* someone already writing */
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5)
@@ -120,7 +118,6 @@ osi_VM_StoreAllSegments(struct vcache *avc)
     AFS_GLOCK();
     ObtainWriteLock(&avc->lock, 121);
 #endif
-    avc->f.states &= ~CPageWrite;
 }
 
 /* Purge VM for a file when its callback is revoked.
index 67e7bad36b3621170e8731b987042f1ff955bbae..39bd08151bfb3d43aabff6eb19943ca737397a14 100644 (file)
@@ -1188,7 +1188,7 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
     if (code == ENOENT)
        return ERR_PTR(0);
 #endif
-    else if ((code >= 0) && (code <= MAX_ERRNO))
+    else if ((code > 0) && (code <= MAX_ERRNO))
         return ERR_PTR(-code);
     else 
        return ERR_PTR(-EIO);
@@ -1895,9 +1895,9 @@ 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);
+    ObtainWriteLock(&vcp->lock, 532);
     if (vcp->f.states & CPageWrite) {
-       ReleaseReadLock(&vcp->lock);
+       ReleaseWriteLock(&vcp->lock);
        AFS_GUNLOCK();
        maybe_unlock_kernel();
        crfree(credp);
@@ -1913,7 +1913,8 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp,
        return(0); 
 #endif
     }
-    ReleaseReadLock(&vcp->lock);
+    vcp->states |= CPageWrite;
+    ReleaseWriteLock(&vcp->lock);
 
     setup_uio(&tuio, &iovec, buffer, base, count, UIO_WRITE, AFS_UIOSYS);
 
@@ -1922,16 +1923,18 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp,
     i_size_write(ip, vcp->f.m.Length);
     ip->i_blocks = ((vcp->f.m.Length + 1023) >> 10) << 1;
 
+    ObtainWriteLock(&vcp->lock, 533);
     if (!code) {
        struct vrequest treq;
 
-       ObtainWriteLock(&vcp->lock, 533);
        if (!afs_InitReq(&treq, credp))
            code = afs_DoPartialWrite(vcp, &treq);
-       ReleaseWriteLock(&vcp->lock);
     }
     code = code ? -code : count - tuio.uio_resid;
 
+    vcp->states &= ~CPageWrite;
+    ReleaseWriteLock(&vcp->lock);
+
     afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp,
               ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, page_count(pp),
               ICL_TYPE_INT32, code);
@@ -1986,7 +1989,12 @@ afs_linux_writepage(struct page *pp)
   do_it:
     status = afs_linux_writepage_sync(inode, pp, 0, offset);
     SetPageUptodate(pp);
-    UnlockPage(pp);
+#if defined(WRITEPAGE_ACTIVATE)
+    if ( status != WRITEPAGE_ACTIVATE )
+#else
+    if ( status != AOP_WRITEPAGE_ACTIVATE )
+#endif
+       UnlockPage(pp);
     if (status == offset)
        return 0;
     else