linux-mmap-antirecursion-20081020

LICENSE IPL10
FIXES 120491

avoid deadlocking ourselves due to recursion when flushing pages on an
mmap()ed file larger than the cache
This commit is contained in:
Derrick Brashear 2008-10-20 13:38:07 +00:00
parent bc9c0a1415
commit 4a587356a3
3 changed files with 25 additions and 0 deletions

View File

@ -102,6 +102,11 @@ osi_VM_StoreAllSegments(struct vcache *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 */
ReleaseWriteLock(&avc->lock);
@ -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.

View File

@ -1894,6 +1894,21 @@ 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);
if (vcp->states & CPageWrite) {
ReleaseReadLock(&vcp->lock);
AFS_GUNLOCK();
maybe_unlock_kernel();
crfree(credp);
kunmap(pp);
#if defined(WRITEPAGE_ACTIVATE)
return WRITEPAGE_ACTIVATE;
#else
return AOP_WRITEPAGE_ACTIVATE;
#endif
}
ReleaseReadLock(&vcp->lock);
setup_uio(&tuio, &iovec, buffer, base, count, UIO_WRITE, AFS_UIOSYS);
code = afs_write(vcp, &tuio, f_flags, credp, 0);

View File

@ -562,7 +562,11 @@ struct SimpleLocks {
#define CUnlinkedDel 0x00040000
#define CVFlushed 0x00080000
#define CCore1 0x00100000 /* osf1 core file; not same as CCore above */
#ifdef AFS_LINUX22_ENV
#define CPageWrite 0x00200000 /* to detect vm deadlock - linux */
#else
#define CWritingUFS 0x00200000 /* to detect vm deadlock - used by sgi */
#endif
#define CCreating 0x00400000 /* avoid needless store after open truncate */
#define CPageHog 0x00800000 /* AIX - dumping large cores is a page hog. */
#define CDCLock 0x02000000 /* Vnode lock held over call to GetDownD */