mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	ocfs2: use an array of folios instead of an array of pages
The ocfs2_zero_cluster_folios() / ocfs2_grab_folios() / ocfs2_grab_eof_folios() family of functions pass around an array of pages. Convert them to pass around an array of folios. This removes the last caller of ocfs2_unlock_and_free_pages(), so delete it. Link: https://lkml.kernel.org/r/20241205171653.3179945-17-willy@infradead.org Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com> Cc: Changwei Ge <gechangwei@live.cn> Cc: Joel Becker <jlbec@evilplan.org> Cc: Jun Piao <piaojun@huawei.com> Cc: Junxiao Bi <junxiao.bi@oracle.com> Cc: Mark Fasheh <mark@fasheh.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									4d434f5374
								
							
						
					
					
						commit
						9a5e08652d
					
				
					 4 changed files with 49 additions and 65 deletions
				
			
		|  | @ -6847,87 +6847,87 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle, | |||
| 	flush_dcache_folio(folio); | ||||
| } | ||||
| 
 | ||||
| static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start, | ||||
| 				     loff_t end, struct page **pages, | ||||
| 				     int numpages, u64 phys, handle_t *handle) | ||||
| static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start, | ||||
| 		loff_t end, struct folio **folios, int numfolios, | ||||
| 		u64 phys, handle_t *handle) | ||||
| { | ||||
| 	int i; | ||||
| 	struct page *page; | ||||
| 	unsigned int from, to = PAGE_SIZE; | ||||
| 	struct super_block *sb = inode->i_sb; | ||||
| 
 | ||||
| 	BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(sb))); | ||||
| 
 | ||||
| 	if (numpages == 0) | ||||
| 	if (numfolios == 0) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	to = PAGE_SIZE; | ||||
| 	for(i = 0; i < numpages; i++) { | ||||
| 		page = pages[i]; | ||||
| 	for (i = 0; i < numfolios; i++) { | ||||
| 		struct folio *folio = folios[i]; | ||||
| 
 | ||||
| 		from = start & (PAGE_SIZE - 1); | ||||
| 		if ((end >> PAGE_SHIFT) == page->index) | ||||
| 		if ((end >> PAGE_SHIFT) == folio->index) | ||||
| 			to = end & (PAGE_SIZE - 1); | ||||
| 
 | ||||
| 		BUG_ON(from > PAGE_SIZE); | ||||
| 		BUG_ON(to > PAGE_SIZE); | ||||
| 
 | ||||
| 		ocfs2_map_and_dirty_page(inode, handle, from, to, page, 1, | ||||
| 		ocfs2_map_and_dirty_page(inode, handle, from, to, &folio->page, 1, | ||||
| 					 &phys); | ||||
| 
 | ||||
| 		start = (page->index + 1) << PAGE_SHIFT; | ||||
| 		start = (folio->index + 1) << PAGE_SHIFT; | ||||
| 	} | ||||
| out: | ||||
| 	if (pages) | ||||
| 		ocfs2_unlock_and_free_pages(pages, numpages); | ||||
| 	if (folios) | ||||
| 		ocfs2_unlock_and_free_folios(folios, numfolios); | ||||
| } | ||||
| 
 | ||||
| int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end, | ||||
| 		     struct page **pages, int *num) | ||||
| static int ocfs2_grab_folios(struct inode *inode, loff_t start, loff_t end, | ||||
| 		struct folio **folios, int *num) | ||||
| { | ||||
| 	int numpages, ret = 0; | ||||
| 	int numfolios, ret = 0; | ||||
| 	struct address_space *mapping = inode->i_mapping; | ||||
| 	unsigned long index; | ||||
| 	loff_t last_page_bytes; | ||||
| 
 | ||||
| 	BUG_ON(start > end); | ||||
| 
 | ||||
| 	numpages = 0; | ||||
| 	numfolios = 0; | ||||
| 	last_page_bytes = PAGE_ALIGN(end); | ||||
| 	index = start >> PAGE_SHIFT; | ||||
| 	do { | ||||
| 		pages[numpages] = find_or_create_page(mapping, index, GFP_NOFS); | ||||
| 		if (!pages[numpages]) { | ||||
| 			ret = -ENOMEM; | ||||
| 		folios[numfolios] = __filemap_get_folio(mapping, index, | ||||
| 				FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_NOFS); | ||||
| 		if (IS_ERR(folios[numfolios])) { | ||||
| 			ret = PTR_ERR(folios[numfolios]); | ||||
| 			mlog_errno(ret); | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		numpages++; | ||||
| 		index++; | ||||
| 		index = folio_next_index(folios[numfolios]); | ||||
| 		numfolios++; | ||||
| 	} while (index < (last_page_bytes >> PAGE_SHIFT)); | ||||
| 
 | ||||
| out: | ||||
| 	if (ret != 0) { | ||||
| 		if (pages) | ||||
| 			ocfs2_unlock_and_free_pages(pages, numpages); | ||||
| 		numpages = 0; | ||||
| 		if (folios) | ||||
| 			ocfs2_unlock_and_free_folios(folios, numfolios); | ||||
| 		numfolios = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	*num = numpages; | ||||
| 	*num = numfolios; | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end, | ||||
| 				struct page **pages, int *num) | ||||
| static int ocfs2_grab_eof_folios(struct inode *inode, loff_t start, loff_t end, | ||||
| 				struct folio **folios, int *num) | ||||
| { | ||||
| 	struct super_block *sb = inode->i_sb; | ||||
| 
 | ||||
| 	BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits != | ||||
| 	       (end - 1) >> OCFS2_SB(sb)->s_clustersize_bits); | ||||
| 
 | ||||
| 	return ocfs2_grab_pages(inode, start, end, pages, num); | ||||
| 	return ocfs2_grab_folios(inode, start, end, folios, num); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -6941,8 +6941,8 @@ static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end, | |||
| int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, | ||||
| 				  u64 range_start, u64 range_end) | ||||
| { | ||||
| 	int ret = 0, numpages; | ||||
| 	struct page **pages = NULL; | ||||
| 	int ret = 0, numfolios; | ||||
| 	struct folio **folios = NULL; | ||||
| 	u64 phys; | ||||
| 	unsigned int ext_flags; | ||||
| 	struct super_block *sb = inode->i_sb; | ||||
|  | @ -6955,17 +6955,17 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, | |||
| 		return 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Avoid zeroing pages fully beyond current i_size. It is pointless as | ||||
| 	 * underlying blocks of those pages should be already zeroed out and | ||||
| 	 * Avoid zeroing folios fully beyond current i_size. It is pointless as | ||||
| 	 * underlying blocks of those folios should be already zeroed out and | ||||
| 	 * page writeback will skip them anyway. | ||||
| 	 */ | ||||
| 	range_end = min_t(u64, range_end, i_size_read(inode)); | ||||
| 	if (range_start >= range_end) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	pages = kcalloc(ocfs2_pages_per_cluster(sb), | ||||
| 			sizeof(struct page *), GFP_NOFS); | ||||
| 	if (pages == NULL) { | ||||
| 	folios = kcalloc(ocfs2_pages_per_cluster(sb), | ||||
| 			sizeof(struct folio *), GFP_NOFS); | ||||
| 	if (folios == NULL) { | ||||
| 		ret = -ENOMEM; | ||||
| 		mlog_errno(ret); | ||||
| 		goto out; | ||||
|  | @ -6986,18 +6986,18 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, | |||
| 	if (phys == 0 || ext_flags & OCFS2_EXT_UNWRITTEN) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	ret = ocfs2_grab_eof_pages(inode, range_start, range_end, pages, | ||||
| 				   &numpages); | ||||
| 	ret = ocfs2_grab_eof_folios(inode, range_start, range_end, folios, | ||||
| 				   &numfolios); | ||||
| 	if (ret) { | ||||
| 		mlog_errno(ret); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	ocfs2_zero_cluster_pages(inode, range_start, range_end, pages, | ||||
| 				 numpages, phys, handle); | ||||
| 	ocfs2_zero_cluster_folios(inode, range_start, range_end, folios, | ||||
| 				 numfolios, phys, handle); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Initiate writeout of the pages we zero'd here. We don't | ||||
| 	 * Initiate writeout of the folios we zero'd here. We don't | ||||
| 	 * wait on them - the truncate_inode_pages() call later will | ||||
| 	 * do that for us. | ||||
| 	 */ | ||||
|  | @ -7007,7 +7007,7 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, | |||
| 		mlog_errno(ret); | ||||
| 
 | ||||
| out: | ||||
| 	kfree(pages); | ||||
| 	kfree(folios); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -7060,7 +7060,7 @@ void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di) | |||
| int ocfs2_convert_inline_data_to_extents(struct inode *inode, | ||||
| 					 struct buffer_head *di_bh) | ||||
| { | ||||
| 	int ret, has_data, num_pages = 0; | ||||
| 	int ret, has_data, num_folios = 0; | ||||
| 	int need_free = 0; | ||||
| 	u32 bit_off, num; | ||||
| 	handle_t *handle; | ||||
|  | @ -7069,7 +7069,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||||
| 	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||||
| 	struct ocfs2_alloc_context *data_ac = NULL; | ||||
| 	struct page *page = NULL; | ||||
| 	struct folio *folio = NULL; | ||||
| 	struct ocfs2_extent_tree et; | ||||
| 	int did_quota = 0; | ||||
| 
 | ||||
|  | @ -7124,8 +7124,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 		 */ | ||||
| 		block = phys = ocfs2_clusters_to_blocks(inode->i_sb, bit_off); | ||||
| 
 | ||||
| 		ret = ocfs2_grab_eof_pages(inode, 0, page_end, &page, | ||||
| 					   &num_pages); | ||||
| 		ret = ocfs2_grab_eof_folios(inode, 0, page_end, &folio, | ||||
| 					   &num_folios); | ||||
| 		if (ret) { | ||||
| 			mlog_errno(ret); | ||||
| 			need_free = 1; | ||||
|  | @ -7136,14 +7136,14 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 		 * This should populate the 1st page for us and mark | ||||
| 		 * it up to date. | ||||
| 		 */ | ||||
| 		ret = ocfs2_read_inline_data(inode, page, di_bh); | ||||
| 		ret = ocfs2_read_inline_data(inode, &folio->page, di_bh); | ||||
| 		if (ret) { | ||||
| 			mlog_errno(ret); | ||||
| 			need_free = 1; | ||||
| 			goto out_unlock; | ||||
| 		} | ||||
| 
 | ||||
| 		ocfs2_map_and_dirty_page(inode, handle, 0, page_end, page, 0, | ||||
| 		ocfs2_map_and_dirty_page(inode, handle, 0, page_end, &folio->page, 0, | ||||
| 					 &phys); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -7175,8 +7175,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 	} | ||||
| 
 | ||||
| out_unlock: | ||||
| 	if (page) | ||||
| 		ocfs2_unlock_and_free_pages(&page, num_pages); | ||||
| 	if (folio) | ||||
| 		ocfs2_unlock_and_free_folios(&folio, num_folios); | ||||
| 
 | ||||
| out_commit: | ||||
| 	if (ret < 0 && did_quota) | ||||
|  |  | |||
|  | @ -254,8 +254,6 @@ static inline int ocfs2_is_empty_extent(struct ocfs2_extent_rec *rec) | |||
| 	return !rec->e_leaf_clusters; | ||||
| } | ||||
| 
 | ||||
| int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end, | ||||
| 		     struct page **pages, int *num); | ||||
| void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle, | ||||
| 			      unsigned int from, unsigned int to, | ||||
| 			      struct page *page, int zero, u64 *phys); | ||||
|  |  | |||
|  | @ -783,19 +783,6 @@ void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for(i = 0; i < num_pages; i++) { | ||||
| 		if (pages[i]) { | ||||
| 			unlock_page(pages[i]); | ||||
| 			mark_page_accessed(pages[i]); | ||||
| 			put_page(pages[i]); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void ocfs2_unlock_folios(struct ocfs2_write_ctxt *wc) | ||||
| { | ||||
| 	int i; | ||||
|  |  | |||
|  | @ -18,7 +18,6 @@ int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno, | |||
| 			  unsigned int to, int new); | ||||
| 
 | ||||
| void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios); | ||||
| void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages); | ||||
| 
 | ||||
| int walk_page_buffers(	handle_t *handle, | ||||
| 			struct buffer_head *head, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Mark Tinguely
						Mark Tinguely