Author: dannf Date: Tue Mar 18 06:04:32 2008 New Revision: 10916 Log: * Fix potential nfs write corruption (closes: #470719)
Added: dists/etch/linux-2.6/debian/patches/bugfix/nfs-write-corruption.patch Modified: dists/etch/linux-2.6/debian/changelog dists/etch/linux-2.6/debian/patches/series/19 Modified: dists/etch/linux-2.6/debian/changelog ============================================================================== --- dists/etch/linux-2.6/debian/changelog (original) +++ dists/etch/linux-2.6/debian/changelog Tue Mar 18 06:04:32 2008 @@ -5,8 +5,9 @@ [ dann frazier ] * e1000: Add PCI-IDs for 82571EB 4-port cards (closes: #466401). + * Fix potential nfs write corruption (closes: #470719) - -- dann frazier <[EMAIL PROTECTED]> Thu, 28 Feb 2008 17:26:31 -0700 + -- dann frazier <[EMAIL PROTECTED]> Sun, 16 Mar 2008 20:57:06 -0600 linux-2.6 (2.6.18.dfsg.1-18) stable; urgency=high Added: dists/etch/linux-2.6/debian/patches/bugfix/nfs-write-corruption.patch ============================================================================== --- (empty file) +++ dists/etch/linux-2.6/debian/patches/bugfix/nfs-write-corruption.patch Tue Mar 18 06:04:32 2008 @@ -0,0 +1,76 @@ +From: Trond Myklebust <[EMAIL PROTECTED]> +Date: Thu, 7 Feb 2008 22:24:07 +0000 (-0500) +Subject: NFS: Fix a potential file corruption issue when writing +X-Git-Tag: v2.6.25-rc1~286^2~1 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=5d47a35600270e7115061cb1320ee60ae9bcb6b8 + +NFS: Fix a potential file corruption issue when writing + +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 +invaldate_inode_pages2() (typically by calling read()). + +Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]> +--- + +Backported to Debian's 2.6.18 by dann frazier <[EMAIL PROTECTED]> + +diff -urpN linux-source-2.6.18.orig/fs/nfs/write.c linux-source-2.6.18/fs/nfs/write.c +--- linux-source-2.6.18.orig/fs/nfs/write.c 2006-09-19 21:42:06.000000000 -0600 ++++ linux-source-2.6.18/fs/nfs/write.c 2008-03-13 01:16:30.000000000 -0600 +@@ -805,6 +805,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 +@@ -836,10 +847,13 @@ int nfs_updatepage(struct file *file, st + } + + /* 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_flags & O_SYNC)) { + loff_t end_offs = i_size_read(inode) - 1; + unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT; + Modified: dists/etch/linux-2.6/debian/patches/series/19 ============================================================================== --- dists/etch/linux-2.6/debian/patches/series/19 (original) +++ dists/etch/linux-2.6/debian/patches/series/19 Tue Mar 18 06:04:32 2008 @@ -1,2 +1,3 @@ + bugfix/mips/cobalt-raq1-uart.patch + features/e1000-quad-82571EB-ids.patch ++ bugfix/nfs-write-corruption.patch _______________________________________________ Kernel-svn-changes mailing list [email protected] http://lists.alioth.debian.org/mailman/listinfo/kernel-svn-changes

