All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tao Ma <tao.ma@oracle.com>
To: ocfs2-devel@oss.oracle.com
Subject: [Ocfs2-devel] [PATCH] ocfs2: make __ocfs2_page_mkwrite handle file end properly.
Date: Sat, 17 Jul 2010 16:14:46 +0800	[thread overview]
Message-ID: <4C416676.4020607@oracle.com> (raw)
In-Reply-To: <20100716195137.GA30859@mail.oracle.com>



Joel Becker wrote:
> On Fri, Jul 16, 2010 at 10:21:00PM +0800, Tao Ma wrote:
>    
>> __ocfs2_page_mkwrite now is broken in handling file end.
>> 1. the last page should be the page contains i_size - 1.
>> 2. the len in the last page is also calculated wrong.
>> So change them accordingly.
>>      
>
> 	How did you determine these broken?  They look correct to me,
> and they passed the mmap testing I ran against the tail zeroing fixes.
> Comments inline.
>
>    
>> diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
>> index af2b8fe..4c18f4a 100644
>> --- a/fs/ocfs2/mmap.c
>> +++ b/fs/ocfs2/mmap.c
>> @@ -74,9 +74,11 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh,
>>   	/*
>>   	 * Another node might have truncated while we were waiting on
>>   	 * cluster locks.
>> +	 * We don't check size == 0 before the shift. This is borrowed
>> +	 * from do_generic_file_read.
>>   	 */
>> -	last_index = size>>  PAGE_CACHE_SHIFT;
>> -	if (page->index>  last_index) {
>>      
>
> 	This original check seems correct.  If size is on a page
> boundary, sure the last_index is past the last page of the file.
> That's OK, we're checking that page->index isn't greater than that.
>    
No, it is broken.
so say i_size = 4096. the last valid page index should be 0 not 1.
and if the page that requirs to mk_write has page->index = 1, we should 
fail in this case.
While the old one let us go.
As I said in the comment, this code is borrowed from 
do_generic_file_read. So you can check
that file for detail.
1034                 isize = i_size_read(inode);
1035                 end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
1036                 if (unlikely(!isize || index > end_index)) {
1037                         page_cache_release(page);
1038                         goto out;
1039                 }

>    
>> @@ -107,7 +109,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh,
>>   	 * because the "write" would invalidate their data.
>>   	 */
>>   	if (page->index == last_index)
>> -		len = size&  ~PAGE_CACHE_MASK;
>> +		len = ((size - 1)&  ~PAGE_CACHE_MASK) + 1;
>>      
>
> 	And the len calculation is only broken because you changed what
> last_index meant.  Originally, if the page equals the last_index, size
> cannot be page aligned, and you are guaranteed a proper len.
> 	You know, if you don't like the way last_index reads, we can
> always steal the ext4 comparison:
>
> 5982         if (page->mapping != mapping || size<= page_offset(page)
> 5983             || !PageUptodate(page)) {
> 5984                 /* page got truncated from under us? */
> 5985                 goto out_unlock;
> 5986         }
>
> <snip>
>
> 5990
> 5991         if (page->index == size>>  PAGE_CACHE_SHIFT)
> 5992                 len = size&  ~PAGE_CACHE_MASK;
> 5993         else
> 5994                 len = PAGE_CACHE_SIZE;
>
> 	This is a direct compare on the page_offset, which doesn't
> confuse anyone about index vs i_size.  Later, they directly check "is
> this page the last in the file" before computing len.
>    
My code is borrowed from do_generic_file_read and I think it looks good. 
See here.
1042                 nr = PAGE_CACHE_SIZE;
1043                 if (index == end_index) {
1044                         nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
1045                         if (nr <= offset) {
1046                                 page_cache_release(page);
1047                                 goto out;
1048                         }
1049                 }

Regards,
Tao

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://oss.oracle.com/pipermail/ocfs2-devel/attachments/20100717/b492db37/attachment.html 

      reply	other threads:[~2010-07-17  8:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-16 14:21 [Ocfs2-devel] [PATCH] ocfs2: make __ocfs2_page_mkwrite handle file end properly Tao Ma
2010-07-16 19:51 ` Joel Becker
2010-07-17  8:14   ` Tao Ma [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C416676.4020607@oracle.com \
    --to=tao.ma@oracle.com \
    --cc=ocfs2-devel@oss.oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.