lkml.org 
[lkml]   [2020]   [Feb]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 15/25] iomap: Support large pages in iomap_adjust_read_range
    Date
    From: "Matthew Wilcox (Oracle)" <willy@infradead.org>

    Pass the struct page instead of the iomap_page so we can determine the
    size of the page. Introduce offset_in_this_page() and use thp_size()
    instead of PAGE_SIZE.

    Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
    ---
    fs/iomap/buffered-io.c | 16 +++++++++-------
    include/linux/mm.h | 2 ++
    2 files changed, 11 insertions(+), 7 deletions(-)

    diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
    index 5e5a6b038fc3..e522039f627f 100644
    --- a/fs/iomap/buffered-io.c
    +++ b/fs/iomap/buffered-io.c
    @@ -83,15 +83,16 @@ iomap_page_release(struct page *page)
    * Calculate the range inside the page that we actually need to read.
    */
    static void
    -iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop,
    +iomap_adjust_read_range(struct inode *inode, struct page *page,
    loff_t *pos, loff_t length, unsigned *offp, unsigned *lenp)
    {
    + struct iomap_page *iop = to_iomap_page(page);
    loff_t orig_pos = *pos;
    loff_t isize = i_size_read(inode);
    unsigned block_bits = inode->i_blkbits;
    unsigned block_size = (1 << block_bits);
    - unsigned poff = offset_in_page(*pos);
    - unsigned plen = min_t(loff_t, PAGE_SIZE - poff, length);
    + unsigned poff = offset_in_this_page(page, *pos);
    + unsigned plen = min_t(loff_t, thp_size(page) - poff, length);
    unsigned first = poff >> block_bits;
    unsigned last = (poff + plen - 1) >> block_bits;

    @@ -129,7 +130,8 @@ iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop,
    * page cache for blocks that are entirely outside of i_size.
    */
    if (orig_pos <= isize && orig_pos + length > isize) {
    - unsigned end = offset_in_page(isize - 1) >> block_bits;
    + unsigned end = offset_in_this_page(page, isize - 1) >>
    + block_bits;

    if (first <= end && last > end)
    plen -= (last - end) * block_size;
    @@ -256,7 +258,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
    }

    /* zero post-eof blocks as the page may be mapped */
    - iomap_adjust_read_range(inode, iop, &pos, length, &poff, &plen);
    + iomap_adjust_read_range(inode, page, &pos, length, &poff, &plen);
    if (plen == 0)
    goto done;

    @@ -547,7 +549,6 @@ static int
    __iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, int flags,
    struct page *page, struct iomap *srcmap)
    {
    - struct iomap_page *iop = iomap_page_create(inode, page);
    loff_t block_size = i_blocksize(inode);
    loff_t block_start = pos & ~(block_size - 1);
    loff_t block_end = (pos + len + block_size - 1) & ~(block_size - 1);
    @@ -556,9 +557,10 @@ __iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, int flags,

    if (PageUptodate(page))
    return 0;
    + iomap_page_create(inode, page);

    do {
    - iomap_adjust_read_range(inode, iop, &block_start,
    + iomap_adjust_read_range(inode, page, &block_start,
    block_end - block_start, &poff, &plen);
    if (plen == 0)
    break;
    diff --git a/include/linux/mm.h b/include/linux/mm.h
    index 52269e56c514..b4bf86590096 100644
    --- a/include/linux/mm.h
    +++ b/include/linux/mm.h
    @@ -1387,6 +1387,8 @@ static inline void clear_page_pfmemalloc(struct page *page)
    extern void pagefault_out_of_memory(void);

    #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
    +#define offset_in_this_page(page, p) \
    + ((unsigned long)(p) & (thp_size(page) - 1))

    /*
    * Flags passed to show_mem() and show_free_areas() to suppress output in
    --
    2.25.0
    \
     
     \ /
      Last update: 2020-02-12 05:20    [W:4.074 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site