STABLE14101-linux-mmap-antirecursion-fix-20090512

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 5e0e1ea254)
This commit is contained in:
Felix Frank 2009-05-12 18:57:49 +00:00 committed by Derrick Brashear
parent a6403c0134
commit 3ef285cb11
2 changed files with 15 additions and 10 deletions

View 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.

View File

@ -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