Re: [PATCH 7/6] fat: Support a truncate() for expanding size

From: OGAWA Hirofumi
Date: Tue Nov 08 2005 - 00:22:43 EST


Andrew Morton <akpm@xxxxxxxx> writes:

>> The generic_cont_expand() is too generic.
>
> But can it be fixed??

Oh, probably we can...

>> If "size" is block boundary, generic_cont_expand() expands the
>> ->i_size to "size + 1", after it, the caller of it will truncate to
>> "size" by vmtruncate().
>
> Something like this?
>

[...]

> -int generic_cont_expand(struct inode *inode, loff_t size)
> +static int __generic_cont_expand(struct inode *inode, loff_t size, int dont_do_that)
> {
> struct address_space *mapping = inode->i_mapping;
> struct page *page;
> @@ -2182,9 +2182,8 @@ int generic_cont_expand(struct inode *in
> ** skip the prepare. make sure we never send an offset for the start
> ** of a block
> */
> - if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
> + if (!dont_do_that && (offset & (inode->i_sb->s_blocksize - 1)) == 0)
> offset++;

Yes. But, if size is the page boundary, index is different.

Probably something like the below. And I'd like to do vmtruncate()
if ->prepare_write() returns a error. The sync_page_range_nolock()
can do by caller, so not necessary.

Hmm, I'll rethink this at tonight (10 hours later), the result may be
same after all though.

Thanks.


if (!dont_do_that) {
offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */

/* ugh. in prepare/commit_write, if from==to==start of block, we
** skip the prepare. make sure we never send an offset for the start
** of a block
*/
if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
offset++;
}
index = size >> PAGE_CACHE_SHIFT;
} else {
/* calculate the stuff of last page */
loff_t pos = size - 1;
index = pos >> PAGE_CACHE_SHIFT;
offset = (pos & (PAGE_CACHE_SIZE - 1)) + 1;
}
--
OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/