forked from Minki/linux
ext4: Refactor mpage_map_and_submit_buffers function
This patch refactors mpage_map_and_submit_buffers to take out the page buffers processing, as a separate function. This will be required to add support for blocksize < pagesize for dioread_nolock feature. No functionality change in this patch. Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com> Link: https://lore.kernel.org/r/20191016073711.4141-4-riteshh@linux.ibm.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
a00713ea98
commit
2943fdbc68
125
fs/ext4/inode.c
125
fs/ext4/inode.c
@ -2340,6 +2340,75 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd,
|
||||
return lblk < blocks;
|
||||
}
|
||||
|
||||
/*
|
||||
* mpage_process_page - update page buffers corresponding to changed extent and
|
||||
* may submit fully mapped page for IO
|
||||
*
|
||||
* @mpd - description of extent to map, on return next extent to map
|
||||
* @m_lblk - logical block mapping.
|
||||
* @m_pblk - corresponding physical mapping.
|
||||
* @map_bh - determines on return whether this page requires any further
|
||||
* mapping or not.
|
||||
* Scan given page buffers corresponding to changed extent and update buffer
|
||||
* state according to new extent state.
|
||||
* We map delalloc buffers to their physical location, clear unwritten bits.
|
||||
* If the given page is not fully mapped, we update @map to the next extent in
|
||||
* the given page that needs mapping & return @map_bh as true.
|
||||
*/
|
||||
static int mpage_process_page(struct mpage_da_data *mpd, struct page *page,
|
||||
ext4_lblk_t *m_lblk, ext4_fsblk_t *m_pblk,
|
||||
bool *map_bh)
|
||||
{
|
||||
struct buffer_head *head, *bh;
|
||||
ext4_io_end_t *io_end = mpd->io_submit.io_end;
|
||||
ext4_lblk_t lblk = *m_lblk;
|
||||
ext4_fsblk_t pblock = *m_pblk;
|
||||
int err = 0;
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
do {
|
||||
if (lblk < mpd->map.m_lblk)
|
||||
continue;
|
||||
if (lblk >= mpd->map.m_lblk + mpd->map.m_len) {
|
||||
/*
|
||||
* Buffer after end of mapped extent.
|
||||
* Find next buffer in the page to map.
|
||||
*/
|
||||
mpd->map.m_len = 0;
|
||||
mpd->map.m_flags = 0;
|
||||
|
||||
/*
|
||||
* FIXME: If dioread_nolock supports
|
||||
* blocksize < pagesize, we need to make
|
||||
* sure we add size mapped so far to
|
||||
* io_end->size as the following call
|
||||
* can submit the page for IO.
|
||||
*/
|
||||
err = mpage_process_page_bufs(mpd, head, bh, lblk);
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
*map_bh = true;
|
||||
goto out;
|
||||
}
|
||||
if (buffer_delay(bh)) {
|
||||
clear_buffer_delay(bh);
|
||||
bh->b_blocknr = pblock++;
|
||||
}
|
||||
clear_buffer_unwritten(bh);
|
||||
} while (lblk++, (bh = bh->b_this_page) != head);
|
||||
/*
|
||||
* FIXME: This is going to break if dioread_nolock
|
||||
* supports blocksize < pagesize as we will try to
|
||||
* convert potentially unmapped parts of inode.
|
||||
*/
|
||||
io_end->size += PAGE_SIZE;
|
||||
*map_bh = false;
|
||||
out:
|
||||
*m_lblk = lblk;
|
||||
*m_pblk = pblock;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* mpage_map_buffers - update buffers corresponding to changed extent and
|
||||
* submit fully mapped pages for IO
|
||||
@ -2359,12 +2428,12 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
|
||||
struct pagevec pvec;
|
||||
int nr_pages, i;
|
||||
struct inode *inode = mpd->inode;
|
||||
struct buffer_head *head, *bh;
|
||||
int bpp_bits = PAGE_SHIFT - inode->i_blkbits;
|
||||
pgoff_t start, end;
|
||||
ext4_lblk_t lblk;
|
||||
sector_t pblock;
|
||||
ext4_fsblk_t pblock;
|
||||
int err;
|
||||
bool map_bh = false;
|
||||
|
||||
start = mpd->map.m_lblk >> bpp_bits;
|
||||
end = (mpd->map.m_lblk + mpd->map.m_len - 1) >> bpp_bits;
|
||||
@ -2380,50 +2449,19 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
struct page *page = pvec.pages[i];
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
do {
|
||||
if (lblk < mpd->map.m_lblk)
|
||||
continue;
|
||||
if (lblk >= mpd->map.m_lblk + mpd->map.m_len) {
|
||||
/*
|
||||
* Buffer after end of mapped extent.
|
||||
* Find next buffer in the page to map.
|
||||
*/
|
||||
mpd->map.m_len = 0;
|
||||
mpd->map.m_flags = 0;
|
||||
/*
|
||||
* FIXME: If dioread_nolock supports
|
||||
* blocksize < pagesize, we need to make
|
||||
* sure we add size mapped so far to
|
||||
* io_end->size as the following call
|
||||
* can submit the page for IO.
|
||||
*/
|
||||
err = mpage_process_page_bufs(mpd, head,
|
||||
bh, lblk);
|
||||
pagevec_release(&pvec);
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
return err;
|
||||
}
|
||||
if (buffer_delay(bh)) {
|
||||
clear_buffer_delay(bh);
|
||||
bh->b_blocknr = pblock++;
|
||||
}
|
||||
clear_buffer_unwritten(bh);
|
||||
} while (lblk++, (bh = bh->b_this_page) != head);
|
||||
|
||||
err = mpage_process_page(mpd, page, &lblk, &pblock,
|
||||
&map_bh);
|
||||
/*
|
||||
* FIXME: This is going to break if dioread_nolock
|
||||
* supports blocksize < pagesize as we will try to
|
||||
* convert potentially unmapped parts of inode.
|
||||
* If map_bh is true, means page may require further bh
|
||||
* mapping, or maybe the page was submitted for IO.
|
||||
* So we return to call further extent mapping.
|
||||
*/
|
||||
mpd->io_submit.io_end->size += PAGE_SIZE;
|
||||
if (err < 0 || map_bh == true)
|
||||
goto out;
|
||||
/* Page fully mapped - let IO run! */
|
||||
err = mpage_submit_page(mpd, page);
|
||||
if (err < 0) {
|
||||
pagevec_release(&pvec);
|
||||
return err;
|
||||
}
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
pagevec_release(&pvec);
|
||||
}
|
||||
@ -2431,6 +2469,9 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
|
||||
mpd->map.m_len = 0;
|
||||
mpd->map.m_flags = 0;
|
||||
return 0;
|
||||
out:
|
||||
pagevec_release(&pvec);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
|
||||
|
Loading…
Reference in New Issue
Block a user