Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

block: refactor get_contig_folio_len

Move all of the logic to find the contigous length inside a folio into
get_contig_folio_len instead of keeping some of it in the caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Tested-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
4d77007d fa0bdd45

+27 -35
+27 -35
block/bio.c
··· 1172 1172 bio_set_flag(bio, BIO_CLONED); 1173 1173 } 1174 1174 1175 - static unsigned int get_contig_folio_len(unsigned int *num_pages, 1176 - struct page **pages, unsigned int i, 1177 - struct folio *folio, size_t left, 1175 + static unsigned int get_contig_folio_len(struct page **pages, 1176 + unsigned int *num_pages, size_t left, 1178 1177 size_t offset) 1179 1178 { 1180 - size_t bytes = left; 1181 - size_t contig_sz = min_t(size_t, PAGE_SIZE - offset, bytes); 1182 - unsigned int j; 1179 + struct folio *folio = page_folio(pages[0]); 1180 + size_t contig_sz = min_t(size_t, PAGE_SIZE - offset, left); 1181 + unsigned int max_pages, i; 1182 + size_t folio_offset, len; 1183 + 1184 + folio_offset = PAGE_SIZE * folio_page_idx(folio, pages[0]) + offset; 1185 + len = min(folio_size(folio) - folio_offset, left); 1183 1186 1184 1187 /* 1185 - * We might COW a single page in the middle of 1186 - * a large folio, so we have to check that all 1187 - * pages belong to the same folio. 1188 + * We might COW a single page in the middle of a large folio, so we have 1189 + * to check that all pages belong to the same folio. 1188 1190 */ 1189 - bytes -= contig_sz; 1190 - for (j = i + 1; j < i + *num_pages; j++) { 1191 - size_t next = min_t(size_t, PAGE_SIZE, bytes); 1191 + left -= contig_sz; 1192 + max_pages = DIV_ROUND_UP(offset + len, PAGE_SIZE); 1193 + for (i = 1; i < max_pages; i++) { 1194 + size_t next = min_t(size_t, PAGE_SIZE, left); 1192 1195 1193 - if (page_folio(pages[j]) != folio || 1194 - pages[j] != pages[j - 1] + 1) { 1196 + if (page_folio(pages[i]) != folio || 1197 + pages[i] != pages[i - 1] + 1) 1195 1198 break; 1196 - } 1197 1199 contig_sz += next; 1198 - bytes -= next; 1200 + left -= next; 1199 1201 } 1200 - *num_pages = j - i; 1201 1202 1203 + *num_pages = i; 1202 1204 return contig_sz; 1203 1205 } 1204 1206 ··· 1224 1222 struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt; 1225 1223 struct page **pages = (struct page **)bv; 1226 1224 ssize_t size; 1227 - unsigned int num_pages, i = 0; 1228 - size_t offset, folio_offset, left, len; 1225 + unsigned int i = 0; 1226 + size_t offset, left, len; 1229 1227 int ret = 0; 1230 1228 1231 1229 /* ··· 1246 1244 return size ? size : -EFAULT; 1247 1245 1248 1246 nr_pages = DIV_ROUND_UP(offset + size, PAGE_SIZE); 1249 - for (left = size, i = 0; left > 0; left -= len, i += num_pages) { 1250 - struct page *page = pages[i]; 1251 - struct folio *folio = page_folio(page); 1247 + for (left = size; left > 0; left -= len) { 1252 1248 unsigned int old_vcnt = bio->bi_vcnt; 1249 + unsigned int nr_to_add; 1253 1250 1254 - folio_offset = ((size_t)folio_page_idx(folio, page) << 1255 - PAGE_SHIFT) + offset; 1256 - 1257 - len = min(folio_size(folio) - folio_offset, left); 1258 - 1259 - num_pages = DIV_ROUND_UP(offset + len, PAGE_SIZE); 1260 - 1261 - if (num_pages > 1) 1262 - len = get_contig_folio_len(&num_pages, pages, i, 1263 - folio, left, offset); 1264 - 1265 - if (!bio_add_folio(bio, folio, len, folio_offset)) { 1251 + len = get_contig_folio_len(&pages[i], &nr_to_add, left, offset); 1252 + if (!bio_add_page(bio, pages[i], len, offset)) { 1266 1253 WARN_ON_ONCE(1); 1267 1254 ret = -EINVAL; 1268 1255 goto out; ··· 1266 1275 * single pin per page. 1267 1276 */ 1268 1277 if (offset && bio->bi_vcnt == old_vcnt) 1269 - unpin_user_folio(folio, 1); 1278 + unpin_user_folio(page_folio(pages[i]), 1); 1270 1279 } 1280 + i += nr_to_add; 1271 1281 offset = 0; 1272 1282 } 1273 1283