lkml.org 
[lkml]   [2004]   [Aug]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectRe: data loss in 2.6.9-rc1-mm1
From
Date
On Fri, 2004-08-27 at 06:56, Hugh Dickins wrote:
> On Fri, 27 Aug 2004, Denis Vlasenko wrote:
> > On Friday 27 August 2004 13:55, Gergely Tamas wrote:
> > >
> > > I've hit the following data loss problem under 2.6.9-rc1-mm1.
> > >
> > > If I copy data from a file to another the target will be smaller then
> > > the source file.
> > >
> > > 2.6.9-rc1 does not have this problem
> > > 2.6.8.1-mm4 does not have this problem
> > > 2.6.9-rc1-mm1 _does have_ this problem
> >
> > I've seen some errors from KDE too. Let me do your test...
> >
> > # dd if=/dev/zero of=testfile bs=$((1024*1024)) count=10
> > 10+0 records in
> > 10+0 records out
> > # cat testfile > testfile.1
> > # ls -l test*
> > -rw-r--r-- 1 root root 10485760 Aug 27 14:53 testfile
> > -rw-r--r-- 1 root root 10481664 Aug 27 14:53 testfile.1
>
> Hmm, 2.6.9-rc1-mm1 looks like not a release to trust your (page
> size multiple) data to! You should find the patch below fixes it
> (and, I hope, the issue the erroneous patches were trying to fix).


Hmm.. now I fail to understand how this code works.

assuming page size is 4096, if the size of the file is 4096, is the
end_index 0 or is it 1?
I had this assumption:

file size in bytes end_index
----------------- ---------
1 to 4096 0
4097 to 2*4096 1
2*4096+1 to 3*4096 2
... ..

or is the isize value reported by i_size_read(inode) one less than the
size of the real file?

What am I missing?
RP


>
> Signed-off-by: Hugh Dickins <hugh@veritas.com>
>
> --- 2.6.9-rc1-mm1/mm/filemap.c 2004-08-26 12:09:50.000000000 +0100
> +++ linux/mm/filemap.c 2004-08-27 14:35:32.113359872 +0100
> @@ -722,10 +722,7 @@ void do_generic_mapping_read(struct addr
> offset = *ppos & ~PAGE_CACHE_MASK;
>
> isize = i_size_read(inode);
> - if (!isize)
> - goto out;
> -
> - end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
> + end_index = isize >> PAGE_CACHE_SHIFT;
>
> for (;;) {
> struct page *page;
> @@ -733,6 +730,11 @@ void do_generic_mapping_read(struct addr
>
> if (index > end_index)
> goto out;
> + if (index == end_index) {
> + nr = isize & ~PAGE_CACHE_MASK;
> + if (nr <= offset)
> + goto out;
> + }
>
> cond_resched();
> page_cache_readahead(mapping, &ra, filp, index);
> @@ -831,8 +833,8 @@ readpage:
> * another truncate extends the file - this is desired though).
> */
> isize = i_size_read(inode);
> - end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
> - if (unlikely(!isize || index > end_index)) {
> + end_index = isize >> PAGE_CACHE_SHIFT;
> + if (unlikely(index > end_index)) {
> page_cache_release(page);
> goto out;
> }
>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:05    [W:0.055 / U:1.228 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site