mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	ext4: let ext4 maintain extent status tree
This patch lets ext4 maintain extent status tree. Currently it only tracks delay extent status in extent status tree. When a delay allocation is issued, the related delay extent will be inserted into extent status tree. When a delay extent is written out or invalidated, it will be removed from this tree. Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com> Signed-off-by: Allison Henderson <achender@linux.vnet.ibm.com> Signed-off-by: Zheng Liu <wenqing.lz@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
		
							parent
							
								
									9a26b66175
								
							
						
					
					
						commit
						51865fda28
					
				
					 4 changed files with 51 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -4344,6 +4344,8 @@ void ext4_ext_truncate(struct inode *inode)
 | 
			
		|||
 | 
			
		||||
	last_block = (inode->i_size + sb->s_blocksize - 1)
 | 
			
		||||
			>> EXT4_BLOCK_SIZE_BITS(sb);
 | 
			
		||||
	err = ext4_es_remove_extent(inode, last_block,
 | 
			
		||||
				    EXT_MAX_BLOCKS - last_block);
 | 
			
		||||
	err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
 | 
			
		||||
 | 
			
		||||
	/* In a multi-transaction truncate, we only make the final
 | 
			
		||||
| 
						 | 
				
			
			@ -4971,6 +4973,8 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
 | 
			
		|||
	ext4_ext_invalidate_cache(inode);
 | 
			
		||||
	ext4_discard_preallocations(inode);
 | 
			
		||||
 | 
			
		||||
	err = ext4_es_remove_extent(inode, first_block,
 | 
			
		||||
				    stop_block - first_block);
 | 
			
		||||
	err = ext4_ext_remove_space(inode, first_block, stop_block - 1);
 | 
			
		||||
 | 
			
		||||
	ext4_ext_invalidate_cache(inode);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1411,6 +1411,7 @@ void ext4_ind_truncate(struct inode *inode)
 | 
			
		|||
	down_write(&ei->i_data_sem);
 | 
			
		||||
 | 
			
		||||
	ext4_discard_preallocations(inode);
 | 
			
		||||
	ext4_es_remove_extent(inode, last_block, EXT_MAX_BLOCKS - last_block);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The orphan list entry will now protect us from any crash which
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -574,7 +574,16 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
 | 
			
		|||
		up_read((&EXT4_I(inode)->i_data_sem));
 | 
			
		||||
 | 
			
		||||
	if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
 | 
			
		||||
		int ret = check_block_validity(inode, map);
 | 
			
		||||
		int ret;
 | 
			
		||||
		if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) {
 | 
			
		||||
			/* delayed alloc may be allocated by fallocate and
 | 
			
		||||
			 * coverted to initialized by directIO.
 | 
			
		||||
			 * we need to handle delayed extent here.
 | 
			
		||||
			 */
 | 
			
		||||
			down_write((&EXT4_I(inode)->i_data_sem));
 | 
			
		||||
			goto delayed_mapped;
 | 
			
		||||
		}
 | 
			
		||||
		ret = check_block_validity(inode, map);
 | 
			
		||||
		if (ret != 0)
 | 
			
		||||
			return ret;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -656,8 +665,16 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
 | 
			
		|||
		 * set the BH_Da_Mapped bit on them. Its important to do this
 | 
			
		||||
		 * under the protection of i_data_sem.
 | 
			
		||||
		 */
 | 
			
		||||
		if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED)
 | 
			
		||||
		if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
 | 
			
		||||
			int ret;
 | 
			
		||||
			set_buffers_da_mapped(inode, map);
 | 
			
		||||
delayed_mapped:
 | 
			
		||||
			/* delayed allocation blocks has been allocated */
 | 
			
		||||
			ret = ext4_es_remove_extent(inode, map->m_lblk,
 | 
			
		||||
						    map->m_len);
 | 
			
		||||
			if (ret < 0)
 | 
			
		||||
				retval = ret;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	up_write((&EXT4_I(inode)->i_data_sem));
 | 
			
		||||
| 
						 | 
				
			
			@ -1303,6 +1320,7 @@ static void ext4_da_page_release_reservation(struct page *page,
 | 
			
		|||
	struct inode *inode = page->mapping->host;
 | 
			
		||||
	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 | 
			
		||||
	int num_clusters;
 | 
			
		||||
	ext4_fsblk_t lblk;
 | 
			
		||||
 | 
			
		||||
	head = page_buffers(page);
 | 
			
		||||
	bh = head;
 | 
			
		||||
| 
						 | 
				
			
			@ -1317,11 +1335,15 @@ static void ext4_da_page_release_reservation(struct page *page,
 | 
			
		|||
		curr_off = next_off;
 | 
			
		||||
	} while ((bh = bh->b_this_page) != head);
 | 
			
		||||
 | 
			
		||||
	if (to_release) {
 | 
			
		||||
		lblk = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
 | 
			
		||||
		ext4_es_remove_extent(inode, lblk, to_release);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If we have released all the blocks belonging to a cluster, then we
 | 
			
		||||
	 * need to release the reserved space for that cluster. */
 | 
			
		||||
	num_clusters = EXT4_NUM_B2C(sbi, to_release);
 | 
			
		||||
	while (num_clusters > 0) {
 | 
			
		||||
		ext4_fsblk_t lblk;
 | 
			
		||||
		lblk = (page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits)) +
 | 
			
		||||
			((num_clusters - 1) << sbi->s_cluster_bits);
 | 
			
		||||
		if (sbi->s_cluster_ratio == 1 ||
 | 
			
		||||
| 
						 | 
				
			
			@ -1502,9 +1524,15 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd)
 | 
			
		|||
	struct pagevec pvec;
 | 
			
		||||
	struct inode *inode = mpd->inode;
 | 
			
		||||
	struct address_space *mapping = inode->i_mapping;
 | 
			
		||||
	ext4_lblk_t start, last;
 | 
			
		||||
 | 
			
		||||
	index = mpd->first_page;
 | 
			
		||||
	end   = mpd->next_page - 1;
 | 
			
		||||
 | 
			
		||||
	start = index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
 | 
			
		||||
	last = end << (PAGE_CACHE_SHIFT - inode->i_blkbits);
 | 
			
		||||
	ext4_es_remove_extent(inode, start, last - start + 1);
 | 
			
		||||
 | 
			
		||||
	while (index <= end) {
 | 
			
		||||
		nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
 | 
			
		||||
		if (nr_pages == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -1816,6 +1844,10 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
 | 
			
		|||
				goto out_unlock;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		retval = ext4_es_insert_extent(inode, map->m_lblk, map->m_len);
 | 
			
		||||
		if (retval)
 | 
			
		||||
			goto out_unlock;
 | 
			
		||||
 | 
			
		||||
		/* Clear EXT4_MAP_FROM_CLUSTER flag since its purpose is served
 | 
			
		||||
		 * and it should not appear on the bh->b_state.
 | 
			
		||||
		 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,6 +50,7 @@
 | 
			
		|||
#include "xattr.h"
 | 
			
		||||
#include "acl.h"
 | 
			
		||||
#include "mballoc.h"
 | 
			
		||||
#include "ext4_extents.h"
 | 
			
		||||
 | 
			
		||||
#define CREATE_TRACE_POINTS
 | 
			
		||||
#include <trace/events/ext4.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -1033,6 +1034,7 @@ void ext4_clear_inode(struct inode *inode)
 | 
			
		|||
	clear_inode(inode);
 | 
			
		||||
	dquot_drop(inode);
 | 
			
		||||
	ext4_discard_preallocations(inode);
 | 
			
		||||
	ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
 | 
			
		||||
	if (EXT4_I(inode)->jinode) {
 | 
			
		||||
		jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode),
 | 
			
		||||
					       EXT4_I(inode)->jinode);
 | 
			
		||||
| 
						 | 
				
			
			@ -5296,9 +5298,14 @@ static int __init ext4_init_fs(void)
 | 
			
		|||
		init_waitqueue_head(&ext4__ioend_wq[i]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = ext4_init_pageio();
 | 
			
		||||
	err = ext4_init_es();
 | 
			
		||||
	if (err)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	err = ext4_init_pageio();
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto out7;
 | 
			
		||||
 | 
			
		||||
	err = ext4_init_system_zone();
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto out6;
 | 
			
		||||
| 
						 | 
				
			
			@ -5348,6 +5355,9 @@ static int __init ext4_init_fs(void)
 | 
			
		|||
	ext4_exit_system_zone();
 | 
			
		||||
out6:
 | 
			
		||||
	ext4_exit_pageio();
 | 
			
		||||
out7:
 | 
			
		||||
	ext4_exit_es();
 | 
			
		||||
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue