]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Apply upstream STABLE14-linux-truncate-race-20090109
authorRuss Allbery <rra@debian.org>
Thu, 12 Feb 2009 18:54:35 +0000 (10:54 -0800)
committerRuss Allbery <rra@debian.org>
Thu, 12 Feb 2009 18:54:35 +0000 (10:54 -0800)
Avoid a race condition during truncation, and a preerequisite for later
upstream deltas.

acinclude.m4
debian/changelog
src/afs/LINUX/osi_file.c
src/afs/LINUX/osi_vfs.hin
src/afs/LINUX/osi_vfsops.c
src/afs/LINUX/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_attrs.c
src/cf/linux-test4.m4

index 40205442be0eb293d964c988af81f8cc047abd24..4e315455b260292ad2be69c4eef3e426f98b427b 100644 (file)
@@ -766,6 +766,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
                 LINUX_REGISTER_SYSCTL_TABLE_NOFLAG
                 LINUX_SYSCTL_TABLE_CHECKING
                 LINUX_HAVE_IGET
+                LINUX_HAVE_I_SIZE_READ
                 LINUX_FS_STRUCT_NAMEIDATA_HAS_PATH
                 LINUX_EXPORTS_INIT_MM
                  LINUX_EXPORTS_SYS_CHDIR
index f5ac050b3a7fd5027c38a2f68dd9438ae85d8778..786100e1b8d9d384fc225414abb5492db2588e29 100644 (file)
@@ -7,6 +7,8 @@ openafs (1.4.8.dfsg1-1) UNRELEASED; urgency=low
     - Include vos clone man page.  (LP: #324449)
   * Apply upstream CVS deltas:
     - STABLE14-libuafs-updates-20081229: prerequisite for other deltas.
+    - STABLE14-linux-truncate-race-20090109: avoid race condition during
+      truncation.
   * Make dynroot the default for new installations.  It works much better
     with systems that don't bring up their network until late in the boot
     process, such as wireless laptops.  (LP: #249240, #318605)
index 26891713079bcffff5d12fb0dac0be6ef405a58e..17d581110047dc03a14c4a07513b1909ecfbdff4 100644 (file)
@@ -11,7 +11,7 @@
 #include "afs/param.h"
 
 RCSID
-    ("$Header: /cvs/openafs/src/afs/LINUX/osi_file.c,v 1.19.2.16 2008/03/26 04:10:52 shadow Exp $");
+    ("$Header: /cvs/openafs/src/afs/LINUX/osi_file.c,v 1.19.2.17 2009/01/09 14:58:03 shadow Exp $");
 
 #ifdef AFS_LINUX24_ENV
 #include "h/module.h" /* early to avoid printf->printk mapping */
@@ -82,7 +82,7 @@ osi_UFSOpen(afs_int32 ainode)
     if (IS_ERR(filp))
        osi_Panic("Can't open inode %d\n", ainode);
     afile->filp = filp;
-    afile->size = FILE_INODE(filp)->i_size;
+    afile->size = i_size_read(FILE_INODE(filp)->i_size);
     AFS_GLOCK();
     afile->offset = 0;
     afile->proc = (int (*)())0;
@@ -133,7 +133,7 @@ osi_UFSOpen(afs_int32 ainode)
        code = filp->f_op->open(tip, filp);
     if (code)
        osi_Panic("Can't open inode %d\n", ainode);
-    afile->size = tip->i_size;
+    afile->size = i_size_read(tip);
     AFS_GLOCK();
     afile->offset = 0;
     afile->proc = (int (*)())0;
@@ -148,7 +148,7 @@ afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat)
     register afs_int32 code;
     AFS_STATCNT(osi_Stat);
     MObtainWriteLock(&afs_xosi, 320);
-    astat->size = OSIFILE_INODE(afile)->i_size;
+    astat->size = i_size_read(OSIFILE_INODE(afile));
 #if defined(AFS_LINUX26_ENV)
     astat->mtime = OSIFILE_INODE(afile)->i_mtime.tv_sec;
     astat->atime = OSIFILE_INODE(afile)->i_atime.tv_sec;
@@ -238,7 +238,7 @@ osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
     if (!code)
        truncate_inode_pages(&inode->i_data, asize);
 #else
-    inode->i_size = asize;
+    i_size_write(inode, asize);
     if (inode->i_sb->s_op && inode->i_sb->s_op->notify_change) {
        code = inode->i_sb->s_op->notify_change(&afile->dentry, &newattrs);
     }
index b94a2ca02b4471a79b621505d1805a641cd953aa..bd6de53646e17b64377f9262474ba7f28e58405e 100644 (file)
@@ -78,4 +78,9 @@ typedef struct vattr {
 
 #define VATTR_NULL(A) memset(A, 0, sizeof(struct vattr))
 
+#ifndef HAVE_LINUX_I_SIZE_READ
+#define i_size_read(X) ((X)->i_size)
+#define i_size_write(X,Y) (X)->i_size = Y
+#endif
+
 #endif /* OSI_VFS_H_ */
index d7fc11911b29c81153e6e9c98aa4e3f04ff47c26..0c72679b8652c7a434fc22774886bd19e3319c86 100644 (file)
@@ -16,7 +16,7 @@
 #include "afs/param.h"
 
 RCSID
-    ("$Header: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v 1.29.2.28 2007/11/23 13:45:04 shadow Exp $");
+    ("$Header: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v 1.29.2.30 2009/01/09 15:09:33 shadow Exp $");
 
 #define __NO_VERSION__         /* don't define kernel_version in module.h */
 #include <linux/module.h> /* early to avoid printf->printk mapping */
@@ -532,7 +532,7 @@ vattr2inode(struct inode *ip, struct vattr *vp)
     ip->i_mode = vp->va_mode;
     ip->i_uid = vp->va_uid;
     ip->i_gid = vp->va_gid;
-    ip->i_size = vp->va_size;
+    i_size_write(ip, vp->va_size);
 #if defined(AFS_LINUX26_ENV)
     ip->i_atime.tv_sec = vp->va_atime.tv_sec;
     ip->i_atime.tv_nsec = 0;
index 45fb5c8661f9b10df4945afbcfae17d29e329597..0027851dccfb2b3024bec78627c600d35b2dd0c3 100644 (file)
@@ -22,7 +22,7 @@
 #include "afs/param.h"
 
 RCSID
-    ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.81.2.73 2008/11/08 16:49:59 shadow Exp $");
+    ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.81.2.74 2009/01/09 14:58:03 shadow Exp $");
 
 #include "afs/sysincludes.h"
 #include "afsincludes.h"
@@ -1581,7 +1581,7 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp,
 
     code = afs_write(vcp, &tuio, f_flags, credp, 0);
 
-    ip->i_size = vcp->m.Length;
+    i_size_write(ip, vcp->m.Length);
     ip->i_blocks = ((vcp->m.Length + 1023) >> 10) << 1;
 
     if (!code) {
@@ -1635,13 +1635,13 @@ afs_linux_writepage(struct page *pp)
 #endif
 
     inode = (struct inode *)mapping->host;
-    end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+    end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT;
 
     /* easy case */
     if (pp->index < end_index)
        goto do_it;
     /* things got complicated... */
-    offset = inode->i_size & (PAGE_CACHE_SIZE - 1);
+    offset = i_size_read(inode) & (PAGE_CACHE_SIZE - 1);
     /* OK, are we completely out? */
     if (pp->index >= end_index + 1 || !offset)
        return -EIO;
@@ -1684,7 +1684,7 @@ afs_linux_updatepage(struct file *fp, struct page *pp, unsigned long offset,
 
     code = afs_write(vcp, &tuio, fp->f_flags, credp, 0);
 
-    ip->i_size = vcp->m.Length;
+    i_size_write(ip, vcp->m.Length);
     ip->i_blocks = ((vcp->m.Length + 1023) >> 10) << 1;
 
     if (!code) {
index 21fdbdff0ccb315d64fbef1cdabe9b6e7b07aa2c..0825f88ba248686075626b6f97e8eae3ddbc8141 100644 (file)
@@ -24,7 +24,7 @@
 #include "afs/param.h"
 
 RCSID
-    ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.27.2.12 2008/12/29 21:26:25 shadow Exp $");
+    ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_attrs.c,v 1.27.2.13 2009/01/09 14:58:03 shadow Exp $");
 
 #include "afs/sysincludes.h"   /* Standard vendor system headers */
 #include "afsincludes.h"       /* Afs-based standard headers */
@@ -530,6 +530,13 @@ afs_setattr(OSI_VC_DECL(avc), register struct vattr *attrs,
        ObtainWriteLock(&avc->lock, 128);
        avc->states |= CDirty;
        code = afs_TruncateAllSegments(avc, tsize, &treq, acred);
+#ifdef AFS_LINUX_26_ENV
+       /* We must update the Linux kernel's idea of file size as soon as
+        * possible, to avoid racing with delayed writepages delivered by
+        * pdflush */
+       if (code == 0) 
+           i_size_write(AFSTOV(avc), tsize);
+#endif
        /* if date not explicitly set by this call, set it ourselves, since we
         * changed the data */
        if (!(astat.Mask & AFS_SETMODTIME)) {
index 801f6d59ae9bb2eccac0fa022e6a95ed3b4db060..fad9c728ef9c19323d9124340838d2c67cea1de9 100644 (file)
@@ -816,6 +816,22 @@ AC_DEFUN([LINUX_GENERIC_FILE_AIO_READ], [
     AC_DEFINE([GENERIC_FILE_AIO_READ], 1, [define if your kernel has generic_file_aio_read()])
   fi])
 
+AC_DEFUN([LINUX_HAVE_I_SIZE_READ], [
+  AC_MSG_CHECKING([for linux i_size_read()])
+  AC_CACHE_VAL([ac_cv_linux_i_size_read], [
+    save_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS -Werror-implicit-function-declaration"
+    AC_TRY_KBUILD(
+[#include <linux/fs.h>],
+[i_size_read(NULL);],
+      ac_cv_linux_i_size_read=yes,
+      ac_cv_linux_i_size_read=no)
+    CPPFLAGS="$save_CPPFLAGS"])
+  AC_MSG_RESULT($ac_cv_linux_i_size_read)
+  if test "x$ac_cv_linux_i_size_read" = "xyes"; then
+    AC_DEFINE([HAVE_LINUX_I_SIZE_READ], 1, [define if your kernel has i_size_read()])
+  fi])
+
 AC_DEFUN([LINUX_FREEZER_H_EXISTS], [
   AC_MSG_CHECKING([for linux/freezer.h existance])
   AC_CACHE_VAL([ac_cv_linux_freezer_h_exists], [