A query on page cache and writepage

Shreyansh Jain shrey.linux at gmail.com
Tue Dec 21 00:37:25 EST 2010


Hi Prasad,

(My comment inline)

On Sat, Dec 18, 2010 at 5:24 PM, Rajat Sharma <fs.rajat at gmail.com> wrote:
> I am not sure if memory what for your filesystem needs mapping, may be to
> support binary execution. Do you really need to support Writable or Shared
> memory mappings? If you are good with Read-only mappings or Private memory
> mapping (which does not modify data in page cache but modify a temporary
> COWed copy), the solution is simple - do not implement writepage method at
> all, there won't be any dirty data in page cache at any point of time, so no
> need to flush page cache, however you need to discard page cache range when
> you modify the file through f_op->write(), otherwise memory mapped files
> will read stale data.
>
> Rajat
>
> On Sat, Dec 18, 2010 at 6:51 AM, Prasad Joshi <prasadjoshi124 at gmail.com>
> wrote:
>>
>> Hello All,
>>
>> I am working on a file system, that uses page cache only if a file is
>> memory mapped. This is how the code is designed
>>
>> write()
>> {
>>    write the data onto the disk
>>
>>    if (file not memory mapped)
>>           return;
>>
>>    /* file is memory mapped */
>>    while (till all data is not syced with page cache) {
>>        if (data at current file offset held in page) {
>>            update the page
>>        }
>>    }
>> }
>>
>> The code that updates a page is something like this
>>        page = find_lock_page(mapping, index);
>>        if (likely(!page)) {
>>           /* page not cached */
>>                  continue;
>>        }
>>
>>        if (mapping_writably_mapped(mapping))
>>            flush_dcache_page(page);
>>
>>        pagefault_disable();
>>
>>        /* copy the data */
>>        BUG_ON(!in_atomic());
>>        page_buf = kmap_atomic(page, KM_USER0);
>>        if (__copy_from_user_inatomic(page_buf+offset, user_buf, size)) {
>>            kunmap(page);
>>            unlock_page(page);
>>            err = -EFAULT;
>>            goto out_error;
>>        }
>>        kunmap_atomic(page_buf, KM_USER0);
>>        pagefault_enable();
>>
>>        flush_dcache_page(page);
>>        mark_page_accessed(page);
>>
>>        SetPageUptodate(page);
>>        ClearPageError(page);
>>        unlock_page(page);
>>        page_cache_release(page);
>>
>> If a fops->write() is called the data in page cache is already on to
>> the disk. I don't want a page update from this function to trigger
>> writepage() function.
>>
>> The writepage() function should only be called if an user updates a
>> memory mapped page.
>>
>> Would calling page_clear_dirty() from the write() code be sufficient?

Are you sure that once you have cleared the dirty bit no other process
mapping this file is performing any modifications? If yes, probably
that should suffice.

>>
>> I need to call flush_dcache_page() as a page should be coherent with
>> other mappings. Does calling flush_dcache_page() result in call to
>> writepage()?

I very faintly remember that flush_dcache_page would invoke the mmap
operations which in turn would converge back into a filesystem
specific writepage call. Hence, I would expect writepage to be called
for dcache flush operation.

Probably this might be helpful:
http://lxr.linux.no/#linux+v2.6.36/Documentation/cachetlb.txt#L279

Also, had I been in your shoes, I would have actually put a printk
like thing in my writepage operation to confirm if indeed my function
was not getting called from any kernel specific threads (like pdflush
etc).

[Please take my suggestions with a pinch of salt as I have been out of
touch with this topic since ages - and in case you find them
incorrect, I would be very thankful in case you can correct me too]

--
Shreyansh



More information about the Kernelnewbies mailing list