forked from mirrors/linux
		
	erofs: use read_cache_page_gfp for erofs_get_meta_page
As Christoph said [1], "I'd much prefer to just use read_cache_page_gfp, and live with the fact that this allocates bufferheads behind you for now. I'll try to speed up my attempts to get rid of the buffer heads on the block device mapping instead. " This simplifies the code a lot and a minor thing is "no REQ_META (e.g. for blktrace) on metadata at all..." [1] https://lore.kernel.org/r/20190903153704.GA2201@infradead.org/ Reported-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Gao Xiang <gaoxiang25@huawei.com> Link: https://lore.kernel.org/r/20190904020912.63925-26-gaoxiang25@huawei.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									4231138fe0
								
							
						
					
					
						commit
						618f40ea02
					
				
					 1 changed files with 9 additions and 61 deletions
				
			
		| 
						 | 
					@ -32,71 +32,13 @@ static void erofs_readendio(struct bio *bio)
 | 
				
			||||||
	bio_put(bio);
 | 
						bio_put(bio);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct bio *erofs_grab_raw_bio(struct super_block *sb,
 | 
					 | 
				
			||||||
				      erofs_blk_t blkaddr,
 | 
					 | 
				
			||||||
				      unsigned int nr_pages,
 | 
					 | 
				
			||||||
				      bool ismeta)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bio *bio = bio_alloc(GFP_NOIO, nr_pages);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bio->bi_end_io = erofs_readendio;
 | 
					 | 
				
			||||||
	bio_set_dev(bio, sb->s_bdev);
 | 
					 | 
				
			||||||
	bio->bi_iter.bi_sector = (sector_t)blkaddr << LOG_SECTORS_PER_BLOCK;
 | 
					 | 
				
			||||||
	if (ismeta)
 | 
					 | 
				
			||||||
		bio->bi_opf = REQ_OP_READ | REQ_META;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		bio->bi_opf = REQ_OP_READ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return bio;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr)
 | 
					struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct inode *const bd_inode = sb->s_bdev->bd_inode;
 | 
						struct inode *const bd_inode = sb->s_bdev->bd_inode;
 | 
				
			||||||
	struct address_space *const mapping = bd_inode->i_mapping;
 | 
						struct address_space *const mapping = bd_inode->i_mapping;
 | 
				
			||||||
	const gfp_t gfp = mapping_gfp_constraint(mapping, ~__GFP_FS);
 | 
					 | 
				
			||||||
	struct page *page;
 | 
					 | 
				
			||||||
	int err;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
repeat:
 | 
						return read_cache_page_gfp(mapping, blkaddr,
 | 
				
			||||||
	page = find_or_create_page(mapping, blkaddr, gfp);
 | 
									   mapping_gfp_constraint(mapping, ~__GFP_FS));
 | 
				
			||||||
	if (!page)
 | 
					 | 
				
			||||||
		return ERR_PTR(-ENOMEM);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	DBG_BUGON(!PageLocked(page));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PageUptodate(page)) {
 | 
					 | 
				
			||||||
		struct bio *bio;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		bio = erofs_grab_raw_bio(sb, blkaddr, 1, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) {
 | 
					 | 
				
			||||||
			err = -EFAULT;
 | 
					 | 
				
			||||||
			goto err_out;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		submit_bio(bio);
 | 
					 | 
				
			||||||
		lock_page(page);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* this page has been truncated by others */
 | 
					 | 
				
			||||||
		if (page->mapping != mapping) {
 | 
					 | 
				
			||||||
			unlock_page(page);
 | 
					 | 
				
			||||||
			put_page(page);
 | 
					 | 
				
			||||||
			goto repeat;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* more likely a read error */
 | 
					 | 
				
			||||||
		if (!PageUptodate(page)) {
 | 
					 | 
				
			||||||
			err = -EIO;
 | 
					 | 
				
			||||||
			goto err_out;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return page;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
err_out:
 | 
					 | 
				
			||||||
	unlock_page(page);
 | 
					 | 
				
			||||||
	put_page(page);
 | 
					 | 
				
			||||||
	return ERR_PTR(err);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int erofs_map_blocks_flatmode(struct inode *inode,
 | 
					static int erofs_map_blocks_flatmode(struct inode *inode,
 | 
				
			||||||
| 
						 | 
					@ -272,7 +214,13 @@ static inline struct bio *erofs_read_raw_page(struct bio *bio,
 | 
				
			||||||
		if (nblocks > BIO_MAX_PAGES)
 | 
							if (nblocks > BIO_MAX_PAGES)
 | 
				
			||||||
			nblocks = BIO_MAX_PAGES;
 | 
								nblocks = BIO_MAX_PAGES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bio = erofs_grab_raw_bio(sb, blknr, nblocks, false);
 | 
							bio = bio_alloc(GFP_NOIO, nblocks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bio->bi_end_io = erofs_readendio;
 | 
				
			||||||
 | 
							bio_set_dev(bio, sb->s_bdev);
 | 
				
			||||||
 | 
							bio->bi_iter.bi_sector = (sector_t)blknr <<
 | 
				
			||||||
 | 
								LOG_SECTORS_PER_BLOCK;
 | 
				
			||||||
 | 
							bio->bi_opf = REQ_OP_READ;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = bio_add_page(bio, page, PAGE_SIZE, 0);
 | 
						err = bio_add_page(bio, page, PAGE_SIZE, 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue