From ad37c1d5de4f0c24496e7d75e47cab2c1c34a3b8 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Mon, 20 Oct 2008 13:38:27 +0000 Subject: [PATCH] STABLE14-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 (cherry picked from commit 4a587356a31ac5afdf17d329a8598f70cf8bc3af) --- src/afs/LINUX/osi_vm.c | 6 ++++++ src/afs/LINUX/osi_vnodeops.c | 15 +++++++++++++++ src/afs/afs.h | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/src/afs/LINUX/osi_vm.c b/src/afs/LINUX/osi_vm.c index 2776aff89..c7e39e29a 100644 --- a/src/afs/LINUX/osi_vm.c +++ b/src/afs/LINUX/osi_vm.c @@ -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. diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 459366e61..2091ff71a 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1556,6 +1556,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(); + 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); diff --git a/src/afs/afs.h b/src/afs/afs.h index 9df1f35fe..e98d55616 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -554,7 +554,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 */ -- 2.39.5