mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
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
1 changed files with 83 additions and 42 deletions
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;
|
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
|
* mpage_map_buffers - update buffers corresponding to changed extent and
|
||||||
* submit fully mapped pages for IO
|
* 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;
|
struct pagevec pvec;
|
||||||
int nr_pages, i;
|
int nr_pages, i;
|
||||||
struct inode *inode = mpd->inode;
|
struct inode *inode = mpd->inode;
|
||||||
struct buffer_head *head, *bh;
|
|
||||||
int bpp_bits = PAGE_SHIFT - inode->i_blkbits;
|
int bpp_bits = PAGE_SHIFT - inode->i_blkbits;
|
||||||
pgoff_t start, end;
|
pgoff_t start, end;
|
||||||
ext4_lblk_t lblk;
|
ext4_lblk_t lblk;
|
||||||
sector_t pblock;
|
ext4_fsblk_t pblock;
|
||||||
int err;
|
int err;
|
||||||
|
bool map_bh = false;
|
||||||
|
|
||||||
start = mpd->map.m_lblk >> bpp_bits;
|
start = mpd->map.m_lblk >> bpp_bits;
|
||||||
end = (mpd->map.m_lblk + mpd->map.m_len - 1) >> 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++) {
|
for (i = 0; i < nr_pages; i++) {
|
||||||
struct page *page = pvec.pages[i];
|
struct page *page = pvec.pages[i];
|
||||||
|
|
||||||
bh = head = page_buffers(page);
|
err = mpage_process_page(mpd, page, &lblk, &pblock,
|
||||||
do {
|
&map_bh);
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: This is going to break if dioread_nolock
|
* If map_bh is true, means page may require further bh
|
||||||
* supports blocksize < pagesize as we will try to
|
* mapping, or maybe the page was submitted for IO.
|
||||||
* convert potentially unmapped parts of inode.
|
* 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! */
|
/* Page fully mapped - let IO run! */
|
||||||
err = mpage_submit_page(mpd, page);
|
err = mpage_submit_page(mpd, page);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
pagevec_release(&pvec);
|
goto out;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pagevec_release(&pvec);
|
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_len = 0;
|
||||||
mpd->map.m_flags = 0;
|
mpd->map.m_flags = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
out:
|
||||||
|
pagevec_release(&pvec);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
|
static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
|
||||||
|
|
Loading…
Add table
Reference in a new issue