@@ -2366,7 +2366,7 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block)
{
struct inode *inode = folio->mapping->host;
sector_t iblock, lblock;
- struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
+ struct buffer_head *bh, *head, *restart_bh = NULL, *arr[MAX_BUF_PER_PAGE];
size_t blocksize;
int nr, i;
int fully_mapped = 1;
@@ -2385,6 +2385,7 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block)
iblock = div_u64(folio_pos(folio), blocksize);
lblock = div_u64(limit + blocksize - 1, blocksize);
bh = head;
+restart:
nr = 0;
i = 0;
@@ -2417,7 +2418,12 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block)
continue;
}
arr[nr++] = bh;
- } while (i++, iblock++, (bh = bh->b_this_page) != head);
+ } while (i++, iblock++, (bh = bh->b_this_page) != head && nr < MAX_BUF_PER_PAGE);
+
+ if (nr == MAX_BUF_PER_PAGE && bh != head)
+ restart_bh = bh;
+ else
+ restart_bh = NULL;
if (fully_mapped)
folio_set_mappedtodisk(folio);
@@ -2450,6 +2456,15 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block)
else
submit_bh(REQ_OP_READ, bh);
}
+
+ /*
+ * Found more buffers than 'arr' could hold,
+ * restart to submit the remaining ones.
+ */
+ if (restart_bh) {
+ bh = restart_bh;
+ goto restart;
+ }
return 0;
}
EXPORT_SYMBOL(block_read_full_folio);