Here is a new improved blockget function, a little more general than
the one we have been using so far:

  * Works for both volume metadata and file data.

  * We can define whether high memory is used per, mapping, by setting
    allocation mask when inode is created,

       mapping_set_gfp_mask(inode->mapping, gfp_mask);

  * Uses ERR_PTR return for better error reporting (need to fix the two
    callers to use this).

  * Returned buffer state is update if page was uptodate, dirty if page
    was dirty

  * Does not care about ->i_size: if we tell it to create a buffer
    above i_size, it will happily do so, unlike the block library
    functions.  Special data transfer semantics related to ->i_size are
    only for Posix file IO, which we will implement by other means that
    by building the limitation into our block access functions.

  * Appears SMP-safe, not tested.

  * Unit tested in UML

The plan is to build our blockread on top of this in the classic
getblk/bread style, slightly improved with ERR_PTR returns.  Because it
locks the page, we do not want to mix this with the block library
block_write_full_page, at least for our allocation map, because the
library function holds the page lock across the get_block -> map_region
call, which will deadlock if an allocation happens to occur on the same
page that is being written out via ->writepage.

I will post the full patch, including the in-kernel unit test, pretty
soon.

struct buffer_head *blockget(struct address_space *mapping, block_t block)
{
        unsigned blockbits = ((struct inode *)mapping->host)->i_blkbits;
        unsigned subshift = PAGE_CACHE_SHIFT - blockbits;
        struct page *page = grab_cache_page(mapping, block >> subshift);
        struct buffer_head *buffer;
        if (!page)
                return ERR_PTR(-ENOMEM);
        if (!page_has_buffers(page))
                create_empty_buffers(page, 1 << blockbits, 0);
        buffer = page_buffer(page, block & ~(-1 << subshift));
        get_bh(buffer);
        unlock_page(page);
        page_cache_release(page);
        return buffer;
}

_______________________________________________
Tux3 mailing list
[email protected]
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3

Reply via email to