Message ID | 20200414150233.24495-20-willy@infradead.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Change readahead API | expand |
On Tue, 14 Apr 2020 08:02:27 -0700 Matthew Wilcox <willy@infradead.org> wrote: > > Use the new readahead operation in erofs. > Well this is exciting. fs/erofs/data.c: In function erofs_raw_access_readahead: fs/erofs/data.c:149:18: warning: last_block may be used uninitialized in this function [-Wmaybe-uninitialized] *last_block + 1 != current_block) { It seems to be a preexisting bug, which your patch prompted gcc-7.2.0 to notice. erofs_read_raw_page() goes in and uses *last_block, but neither of its callers has initialized it. Could the erofs maintainers please take a look?
Hi Andrew, On Mon, Apr 20, 2020 at 10:42:10PM -0700, Andrew Morton wrote: > On Tue, 14 Apr 2020 08:02:27 -0700 Matthew Wilcox <willy@infradead.org> wrote: > > > > > Use the new readahead operation in erofs. > > > > Well this is exciting. > > fs/erofs/data.c: In function erofs_raw_access_readahead: > fs/erofs/data.c:149:18: warning: last_block may be used uninitialized in this function [-Wmaybe-uninitialized] > *last_block + 1 != current_block) { > > It seems to be a preexisting bug, which your patch prompted gcc-7.2.0 > to notice. > > erofs_read_raw_page() goes in and uses *last_block, but neither of its > callers has initialized it. Could the erofs maintainers please take a > look? simply because last_block doesn't need to be initialized at first, because bio == NULL in the begining anyway. I believe this is a gcc false warning because some gcc versions raised some before (many gccs don't, including my current gcc (Debian 8.3.0-6) 8.3.0). in detail, 146 /* note that for readpage case, bio also equals to NULL */ 147 if (bio && 148 /* not continuous */ 149 *last_block + 1 != current_block) { 150 submit_bio_retry: 151 submit_bio(bio); 152 bio = NULL; 153 } bio will be NULL and will bypass the next condition at first. after that, 155 if (!bio) { ... 221 bio = bio_alloc(GFP_NOIO, nblocks); ... } ... 230 err = bio_add_page(bio, page, PAGE_SIZE, 0); 231 /* out of the extent or bio is full */ 232 if (err < PAGE_SIZE) 233 goto submit_bio_retry; 234 235 *last_block = current_block; so bio != NULL, and last_block will be assigned then as well. Thanks, Gao Xiang
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index a78108128af3..187f93b4900e 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -1305,28 +1305,23 @@ static bool should_decompress_synchronously(struct erofs_sb_info *sbi, return nr <= sbi->max_sync_decompress_pages; } -static int z_erofs_readpages(struct file *filp, struct address_space *mapping, - struct list_head *pages, unsigned int nr_pages) +static void z_erofs_readahead(struct readahead_control *rac) { - struct inode *const inode = mapping->host; + struct inode *const inode = rac->mapping->host; struct erofs_sb_info *const sbi = EROFS_I_SB(inode); - bool sync = should_decompress_synchronously(sbi, nr_pages); + bool sync = should_decompress_synchronously(sbi, readahead_count(rac)); struct z_erofs_decompress_frontend f = DECOMPRESS_FRONTEND_INIT(inode); - gfp_t gfp = mapping_gfp_constraint(mapping, GFP_KERNEL); - struct page *head = NULL; + struct page *page, *head = NULL; LIST_HEAD(pagepool); - trace_erofs_readpages(mapping->host, lru_to_page(pages)->index, - nr_pages, false); + trace_erofs_readpages(inode, readahead_index(rac), + readahead_count(rac), false); - f.headoffset = (erofs_off_t)lru_to_page(pages)->index << PAGE_SHIFT; - - for (; nr_pages; --nr_pages) { - struct page *page = lru_to_page(pages); + f.headoffset = readahead_pos(rac); + while ((page = readahead_page(rac))) { prefetchw(&page->flags); - list_del(&page->lru); /* * A pure asynchronous readahead is indicated if @@ -1335,11 +1330,6 @@ static int z_erofs_readpages(struct file *filp, struct address_space *mapping, */ sync &= !(PageReadahead(page) && !head); - if (add_to_page_cache_lru(page, mapping, page->index, gfp)) { - list_add(&page->lru, &pagepool); - continue; - } - set_page_private(page, (unsigned long)head); head = page; } @@ -1368,11 +1358,10 @@ static int z_erofs_readpages(struct file *filp, struct address_space *mapping, /* clean up the remaining free pages */ put_pages_list(&pagepool); - return 0; } const struct address_space_operations z_erofs_aops = { .readpage = z_erofs_readpage, - .readpages = z_erofs_readpages, + .readahead = z_erofs_readahead, };