gfs2: Multi-block allocations in gfs2_page_mkwrite
commitf53056c430
upstream. In gfs2_page_mkwrite's gfs2_allocate_page_backing helper, try to allocate as many blocks at once as we need. Pass in the size of the requested allocation. Fixes:35af80aef9
("gfs2: don't use buffer_heads in gfs2_allocate_page_backing") Cc: stable@vger.kernel.org # v5.3+ Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1948e76afc
commit
e697fd14db
|
@ -381,27 +381,28 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size)
|
||||||
/**
|
/**
|
||||||
* gfs2_allocate_page_backing - Allocate blocks for a write fault
|
* gfs2_allocate_page_backing - Allocate blocks for a write fault
|
||||||
* @page: The (locked) page to allocate backing for
|
* @page: The (locked) page to allocate backing for
|
||||||
|
* @length: Size of the allocation
|
||||||
*
|
*
|
||||||
* We try to allocate all the blocks required for the page in one go. This
|
* We try to allocate all the blocks required for the page in one go. This
|
||||||
* might fail for various reasons, so we keep trying until all the blocks to
|
* might fail for various reasons, so we keep trying until all the blocks to
|
||||||
* back this page are allocated. If some of the blocks are already allocated,
|
* back this page are allocated. If some of the blocks are already allocated,
|
||||||
* that is ok too.
|
* that is ok too.
|
||||||
*/
|
*/
|
||||||
static int gfs2_allocate_page_backing(struct page *page)
|
static int gfs2_allocate_page_backing(struct page *page, unsigned int length)
|
||||||
{
|
{
|
||||||
u64 pos = page_offset(page);
|
u64 pos = page_offset(page);
|
||||||
u64 size = PAGE_SIZE;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
struct iomap iomap = { };
|
struct iomap iomap = { };
|
||||||
|
|
||||||
if (gfs2_iomap_get_alloc(page->mapping->host, pos, 1, &iomap))
|
if (gfs2_iomap_get_alloc(page->mapping->host, pos, length, &iomap))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
iomap.length = min(iomap.length, size);
|
if (length < iomap.length)
|
||||||
size -= iomap.length;
|
iomap.length = length;
|
||||||
|
length -= iomap.length;
|
||||||
pos += iomap.length;
|
pos += iomap.length;
|
||||||
} while (size > 0);
|
} while (length > 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -501,7 +502,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
|
||||||
if (gfs2_is_stuffed(ip))
|
if (gfs2_is_stuffed(ip))
|
||||||
ret = gfs2_unstuff_dinode(ip, page);
|
ret = gfs2_unstuff_dinode(ip, page);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = gfs2_allocate_page_backing(page);
|
ret = gfs2_allocate_page_backing(page, PAGE_SIZE);
|
||||||
|
|
||||||
out_trans_end:
|
out_trans_end:
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in New Issue