]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-linux-mmap-antirecursion-fix-20090512
authorFelix Frank <Felix.Frank@Desy.de>
Tue, 12 May 2009 18:56:50 +0000 (18:56 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 12 May 2009 18:56:50 +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

(cherry picked from commit 5e0e1ea2540d0cb7d7274350eb1fadfd41733ea4)

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

index a08da8fafbca4d0a8969af7cf0ff79808fdc2ff0..4745b38193845a82afddd0b0337ae586a3cd48cf 100644 (file)
@@ -102,9 +102,7 @@ osi_VM_StoreAllSegments(struct vcache *avc)
 {
     struct inode *ip = AFSTOV(avc);
 
-    if (!avc->states & CPageWrite)
-       avc->states |= CPageWrite;
-    else 
+    if (avc->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->states &= ~CPageWrite;
 }
 
 /* Purge VM for a file when its callback is revoked.
index 9d2a6052a48176547ce7705d2ffe92d57bf0ce3c..76bebd77e2d7f953f4b5f9967f7670d069abe33e 100644 (file)
@@ -1091,7 +1091,7 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10)
     if (code == ENOENT)
        return ERR_PTR(0);
-    else if ((code >= 0) && (code <= MAX_ERRNO))
+    else if ((code > 0) && (code <= MAX_ERRNO))
        return ERR_PTR(-code);
     else 
        return ERR_PTR(-EIO);
@@ -1567,9 +1567,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->states & CPageWrite) {
-       ReleaseReadLock(&vcp->lock);
+       ReleaseWriteLock(&vcp->lock);
        AFS_GUNLOCK();
        unlock_kernel();
        crfree(credp);
@@ -1585,7 +1585,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);
 
@@ -1594,16 +1595,18 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp,
     i_size_write(ip, vcp->m.Length);
     ip->i_blocks = ((vcp->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);
@@ -1658,7 +1661,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