Re: [RFC][PATCH] problem of cont_prepare_write()

From: Andrew Morton
Date: Mon Nov 22 2004 - 05:56:15 EST


OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx> wrote:
>
> If I do the following operation on fatfs, and my box under heavy load,
>
> open("testfile", O_CREAT | O_TRUNC | O_RDWR, 0664);
> lseek(fd, 500*1024*1024 - 1, SEEK_SET);
> write(fd, "\0", 1);
>
> In cont_prepare_write(), kernel fills the hole by zero cleared page.
>
> fs/buffer.c:cont_prepare_write:2210,
> while(page->index > (pgpos = *bytes>>PAGE_CACHE_SHIFT)) {
>
> [...]
>
> status = __block_prepare_write(inode, new_page, zerofrom,
> PAGE_CACHE_SIZE, get_block);
> if (status)
> goto out_unmap;
> kaddr = kmap_atomic(new_page, KM_USER0);
> memset(kaddr+zerofrom, 0, PAGE_CACHE_SIZE-zerofrom);
> flush_dcache_page(new_page);
> kunmap_atomic(kaddr, KM_USER0);
> __block_commit_write(inode, new_page,
> zerofrom, PAGE_CACHE_SIZE);
> unlock_page(new_page);
> page_cache_release(new_page);
> }
>
> But until ->commit_write(), kernel doesn't update the ->i_size. Then,
> if kernel writes out that hole page before updates of ->i_size, dirty
> flag of buffer_head is cleared in __block_write_full_page(). So hole
> page was not writed to disk.

But the page remains locked across both the ->prepare_write() and
->commit_write() operations. So writeback cannot get in there to call
->writepage().

The page lock should correctly synchronise the prepare_write/commit_write
and writeback functions.

-
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/