linux-mmap-antirecursion-20081020
[openafs.git] / src / afs / LINUX / osi_vm.c
index 552697f..c7e39e2 100644 (file)
@@ -43,9 +43,9 @@ RCSID
 int
 osi_VM_FlushVCache(struct vcache *avc, int *slept)
 {
-    struct inode *ip = AFSTOI(avc);
+    struct inode *ip = AFSTOV(avc);
 
-    if (VREFCOUNT(avc) != 0)
+    if (VREFCOUNT(avc) > 1)
        return EBUSY;
 
     if (avc->opens != 0)
@@ -73,7 +73,7 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept)
 void
 osi_VM_TryToSmush(struct vcache *avc, struct AFS_UCRED *acred, int sync)
 {
-    struct inode *ip = AFSTOI(avc);
+    struct inode *ip = AFSTOV(avc);
 
 #if defined(AFS_LINUX26_ENV)
     invalidate_inode_pages(ip->i_mapping);
@@ -100,7 +100,12 @@ osi_VM_FSyncInval(struct vcache *avc)
 void
 osi_VM_StoreAllSegments(struct vcache *avc)
 {
-    struct inode *ip = AFSTOI(avc);
+    struct inode *ip = AFSTOV(avc);
+
+    if (!avc->states & CPageWrite)
+       avc->states |= CPageWrite;
+    else 
+       return; /* someone already writing */
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5)
     /* filemap_fdatasync() only exported in 2.4.5 and above */
@@ -115,6 +120,7 @@ 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.
@@ -125,15 +131,15 @@ void
 osi_VM_FlushPages(struct vcache *avc, struct AFS_UCRED *credp)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    struct inode *ip = AFSTOI(avc);
+    struct inode *ip = AFSTOV(avc);
 
     truncate_inode_pages(&ip->i_data, 0);
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15)
-    struct inode *ip = AFSTOI(avc);
+    struct inode *ip = AFSTOV(avc);
 
     truncate_inode_pages(ip, 0);
 #else
-    invalidate_inode_pages(AFSTOI(avc));
+    invalidate_inode_pages(AFSTOV(avc));
 #endif
 }
 
@@ -147,14 +153,14 @@ void
 osi_VM_Truncate(struct vcache *avc, int alen, struct AFS_UCRED *acred)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    struct inode *ip = AFSTOI(avc);
+    struct inode *ip = AFSTOV(avc);
 
     truncate_inode_pages(&ip->i_data, alen);
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15)
-    struct inode *ip = AFSTOI(avc);
+    struct inode *ip = AFSTOV(avc);
 
     truncate_inode_pages(ip, alen);
 #else
-    invalidate_inode_pages(AFSTOI(avc));
+    invalidate_inode_pages(AFSTOV(avc));
 #endif
 }