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.

orangefs_readahead: don't overflow the bufmap slot.

generic/340 showed that this caller of wait_for_direct_io was
sometimes asking for more than a bufmap slot could hold. This splits
the calls up if needed.

Signed-off-by: Mike Marshall <hubcap@omnibond.com>

+27 -9
+27 -9
fs/orangefs/inode.c
··· 224 224 loff_t new_start = readahead_pos(rac); 225 225 int ret; 226 226 size_t new_len = 0; 227 + size_t this_size; 228 + size_t remaining; 227 229 228 230 loff_t bytes_remaining = inode->i_size - readahead_pos(rac); 229 231 loff_t pages_remaining = bytes_remaining / PAGE_SIZE; ··· 241 239 offset = readahead_pos(rac); 242 240 i_pages = &rac->mapping->i_pages; 243 241 244 - iov_iter_xarray(&iter, ITER_DEST, i_pages, offset, readahead_length(rac)); 242 + iov_iter_xarray(&iter, ITER_DEST, i_pages, 243 + offset, readahead_length(rac)); 245 244 246 - /* read in the pages. */ 247 - if ((ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, 248 - &offset, &iter, readahead_length(rac), 249 - inode->i_size, NULL, NULL, rac->file)) < 0) 250 - gossip_debug(GOSSIP_FILE_DEBUG, 251 - "%s: wait_for_direct_io failed. \n", __func__); 252 - else 253 - ret = 0; 245 + remaining = readahead_length(rac); 246 + while (remaining) { 247 + if (remaining > 4194304) 248 + this_size = 4194304; 249 + else 250 + this_size = remaining; 254 251 252 + /* read in the pages. */ 253 + if ((ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, 254 + &offset, &iter, this_size, 255 + inode->i_size, NULL, NULL, rac->file)) < 0) { 256 + gossip_debug(GOSSIP_FILE_DEBUG, 257 + "%s: wait_for_direct_io failed. :%d: \n", 258 + __func__, ret); 259 + goto cleanup; 260 + } else { 261 + ret = 0; 262 + } 263 + 264 + remaining -= this_size; 265 + offset += this_size; 266 + } 267 + 268 + cleanup: 255 269 /* clean up. */ 256 270 while ((folio = readahead_folio(rac))) { 257 271 if (!ret)