]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.22 nfs patch
authorGreg Kroah-Hartman <gregkh@suse.de>
Sat, 9 Feb 2008 01:09:01 +0000 (17:09 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 9 Feb 2008 01:09:01 +0000 (17:09 -0800)
queue-2.6.22/nfs-fix-a-potential-file-corruption-issue-when-writing.patch [new file with mode: 0644]
queue-2.6.22/series

diff --git a/queue-2.6.22/nfs-fix-a-potential-file-corruption-issue-when-writing.patch b/queue-2.6.22/nfs-fix-a-potential-file-corruption-issue-when-writing.patch
new file mode 100644 (file)
index 0000000..e066024
--- /dev/null
@@ -0,0 +1,83 @@
+From stable-bounces@linux.kernel.org Fri Feb  8 11:24:23 2008
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 08 Feb 2008 14:23:35 -0500
+Subject: NFS: Fix a potential file corruption issue when writing
+To: stable@kernel.org
+Message-ID: <1202498615.8383.11.camel@heimdal.trondhjem.org>
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+patch 5d47a35600270e7115061cb1320ee60ae9bcb6b8 in mainline.
+
+If the inode is flagged as having an invalid mapping, then we can't rely on
+the PageUptodate() flag. Ensure that we don't use the "anti-fragmentation"
+write optimisation in nfs_updatepage(), since that will cause NFS to write
+out areas of the page that are no longer guaranteed to be up to date.
+
+A potential corruption could occur in the following scenario:
+
+client 1                       client 2
+===============                        ===============
+                               fd=open("f",O_CREAT|O_WRONLY,0644);
+                               write(fd,"fubar\n",6);  // cache last page
+                               close(fd);
+fd=open("f",O_WRONLY|O_APPEND);
+write(fd,"foo\n",4);
+close(fd);
+
+                               fd=open("f",O_WRONLY|O_APPEND);
+                               write(fd,"bar\n",4);
+                               close(fd);
+-----
+The bug may lead to the file "f" reading 'fubar\n\0\0\0\nbar\n' because
+client 2 does not update the cached page after re-opening the file for
+write. Instead it keeps it marked as PageUptodate() until someone calls
+invalidate_inode_pages2() (typically by calling read()).
+
+The bug was introduced by commit 44b11874ff583b6e766a05856b04f3c492c32b84
+"NFS: Separate metadata and page cache revalidation mechanisms"
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nfs/write.c |   20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -710,6 +710,17 @@ int nfs_flush_incompatible(struct file *
+ }
+ /*
++ * If the page cache is marked as unsafe or invalid, then we can't rely on
++ * the PageUptodate() flag. In this case, we will need to turn off
++ * write optimisations that depend on the page contents being correct.
++ */
++static int nfs_write_pageuptodate(struct page *page, struct inode *inode)
++{
++      return PageUptodate(page) &&
++              !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA));
++}
++
++/*
+  * Update and possibly write a cached page of an NFS file.
+  *
+  * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad
+@@ -730,10 +741,13 @@ int nfs_updatepage(struct file *file, st
+               (long long)(page_offset(page) +offset));
+       /* If we're not using byte range locks, and we know the page
+-       * is entirely in cache, it may be more efficient to avoid
+-       * fragmenting write requests.
++       * is up to date, it may be more efficient to extend the write
++       * to cover the entire page in order to avoid fragmentation
++       * inefficiencies.
+        */
+-      if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
++      if (nfs_write_pageuptodate(page, inode) &&
++                      inode->i_flock == NULL &&
++                      !(file->f_mode & O_SYNC)) {
+               count = max(count + offset, nfs_page_length(page));
+               offset = 0;
+       }
index f6f31c1342b6ac914c2d23334161639ff1af07e8..eb8fde41582f3d8f34ba1175000dd9e8d11d5827 100644 (file)
@@ -2,3 +2,4 @@ sata_promise-fasttrack-tx4200-is-a-second-generation-chip.patch
 sata_promise-asic-prd-table-bug-workaround.patch
 pci-fix-fakephp-deadlock.patch
 quicklists-do-not-release-off-node-pages-early.patch
+nfs-fix-a-potential-file-corruption-issue-when-writing.patch