mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 15:00:12 +00:00
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
This commit is contained in:
parent
3b6bf1a057
commit
5e0e1ea254
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user