[OpenAFS-devel] OpenAFS, Linux and truncate_inode_pages()
chas williams - CONTRACTOR
chas@cmf.nrl.navy.mil
Wed, 01 Mar 2006 16:09:43 -0500
In message <4405CB2C.1010702@pclella.cern.ch>,Rainer Toebbicke writes:
>Corrupted on the local client, in the chunk file (witnessed by grep on
>the cache files). File normal again after 'fs flush'.
i guess this wouldnt make me to suspect something wrong in osi_vm.c.
regardless, the following might be a little more "correct". give
it a try.
Index: src/afs/LINUX/osi_vm.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vm.c,v
retrieving revision 1.16.2.1
diff -u -u -r1.16.2.1 osi_vm.c
--- src/afs/LINUX/osi_vm.c 11 Jul 2005 19:29:56 -0000 1.16.2.1
+++ src/afs/LINUX/osi_vm.c 1 Mar 2006 20:50:45 -0000
@@ -51,6 +51,8 @@
if (avc->opens != 0)
return EBUSY;
+ down(&ip->i_sem);
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
truncate_inode_pages(&ip->i_data, 0);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15)
@@ -58,6 +60,9 @@
#else
invalidate_inode_pages(ip);
#endif
+
+ up(&ip->i_sem);
+
return 0;
}
@@ -100,18 +105,28 @@
void
osi_VM_StoreAllSegments(struct vcache *avc)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5)
struct inode *ip = AFSTOV(avc);
+ int err;
+ int need_unlock = 1;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5)
- /* filemap_fdatasync() only exported in 2.4.5 and above */
ReleaseWriteLock(&avc->lock);
AFS_GUNLOCK();
-#if defined(AFS_LINUX26_ENV)
- filemap_fdatawrite(ip->i_mapping);
+
+ if (down_trylock(&ip->i_sem))
+ need_unlock = 0;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ err = filemap_fdatawrite(ip->i_mapping);
#else
- filemap_fdatasync(ip->i_mapping);
+ err = filemap_fdatasync(ip->i_mapping);
#endif
- filemap_fdatawait(ip->i_mapping);
+ if (err == 0)
+ filemap_fdatawait(ip->i_mapping);
+
+ if (need_unlock)
+ up(&ip->i_sem);
+
AFS_GLOCK();
ObtainWriteLock(&avc->lock, 121);
#endif
@@ -124,17 +139,20 @@
void
osi_VM_FlushPages(struct vcache *avc, struct AFS_UCRED *credp)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
struct inode *ip = AFSTOV(avc);
+ down(&ip->i_sem);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
truncate_inode_pages(&ip->i_data, 0);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15)
- struct inode *ip = AFSTOV(avc);
truncate_inode_pages(ip, 0);
#else
- invalidate_inode_pages(AFSTOV(avc));
+ invalidate_inode_pages(ip);
#endif
+
+ up(&ip->i_sem);
}
/* Purge pages beyond end-of-file, when truncating a file.
@@ -146,15 +164,13 @@
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 = AFSTOV(avc);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
truncate_inode_pages(&ip->i_data, alen);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15)
- struct inode *ip = AFSTOV(avc);
-
truncate_inode_pages(ip, alen);
#else
- invalidate_inode_pages(AFSTOV(avc));
+ invalidate_inode_pages(ip);
#endif
}