From 2b604351bc99b4e4504758cbac369b660b71de0b Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Fri, 22 Jun 2007 15:45:27 -0700 Subject: ocfs2: simplify deallocation locking Deallocation of suballocator blocks, most notably extent blocks, might involve multiple suballocator inodes. The locking for this can get extremely complicated, especially when the suballocator inodes to delete from aren't known until deep within an unrelated codepath. Implement a simple scheme for recording the blocks to be unlinked so that the actual deallocation can be done in a context which won't deadlock. Signed-off-by: Mark Fasheh --- fs/ocfs2/alloc.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'fs/ocfs2/alloc.h') diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index fbcb593..01db0ad 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -63,6 +63,25 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb, int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, struct ocfs2_dinode *tl_copy); +/* + * Process local structure which describes the block unlinks done + * during an operation. This is populated via + * ocfs2_cache_block_dealloc(). + * + * ocfs2_run_deallocs() should be called after the potentially + * de-allocating routines. No journal handles should be open, and most + * locks should have been dropped. + */ +struct ocfs2_cached_dealloc_ctxt { + struct ocfs2_per_slot_free_list *c_first_suballocator; +}; +static inline void ocfs2_init_dealloc_ctxt(struct ocfs2_cached_dealloc_ctxt *c) +{ + c->c_first_suballocator = NULL; +} +int ocfs2_run_deallocs(struct ocfs2_super *osb, + struct ocfs2_cached_dealloc_ctxt *ctxt); + struct ocfs2_truncate_context { struct inode *tc_ext_alloc_inode; struct buffer_head *tc_ext_alloc_bh; -- cgit v1.1 From 59a5e416d1ab543a5248a2b34d83202c4d55d132 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Fri, 22 Jun 2007 15:52:36 -0700 Subject: ocfs2: plug truncate into cached dealloc routines Signed-off-by: Mark Fasheh --- fs/ocfs2/alloc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/ocfs2/alloc.h') diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 01db0ad..cb02e53 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -83,8 +83,7 @@ int ocfs2_run_deallocs(struct ocfs2_super *osb, struct ocfs2_cached_dealloc_ctxt *ctxt); struct ocfs2_truncate_context { - struct inode *tc_ext_alloc_inode; - struct buffer_head *tc_ext_alloc_bh; + struct ocfs2_cached_dealloc_ctxt tc_dealloc; int tc_ext_alloc_locked; /* is it cluster locked? */ /* these get destroyed once it's passed to ocfs2_commit_truncate. */ struct buffer_head *tc_last_eb_bh; -- cgit v1.1 From 328d5752e1259dfb29b7e65f6c2d145fddbaa750 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Mon, 18 Jun 2007 10:48:04 -0700 Subject: ocfs2: btree changes for unwritten extents Writes to a region marked as unwritten might result in a record split or merge. We can support splits by making minor changes to the existing insert code. Merges require left rotations which mostly re-use right rotation support functions. Signed-off-by: Mark Fasheh --- fs/ocfs2/alloc.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'fs/ocfs2/alloc.h') diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index cb02e53..d3acf45 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -35,6 +35,11 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, u64 start_blk, u32 new_clusters, struct ocfs2_alloc_context *meta_ac); +struct ocfs2_cached_dealloc_ctxt; +int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh, + handle_t *handle, u32 cpos, u32 len, u32 phys, + struct ocfs2_alloc_context *meta_ac, + struct ocfs2_cached_dealloc_ctxt *dealloc); int ocfs2_num_free_extents(struct ocfs2_super *osb, struct inode *inode, struct ocfs2_dinode *fe); @@ -102,6 +107,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, int ocfs2_find_leaf(struct inode *inode, struct ocfs2_extent_list *root_el, u32 cpos, struct buffer_head **leaf_bh); +int ocfs2_search_extent_list(struct ocfs2_extent_list *el, u32 v_cluster); /* * Helper function to look at the # of clusters in an extent record. -- cgit v1.1 From 2ae99a60374f360ba07037ebbf33d19b89ac43a6 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Fri, 9 Mar 2007 16:43:28 -0800 Subject: ocfs2: Support creation of unwritten extents This can now be trivially supported with re-use of our existing extend code. ocfs2_allocate_unwritten_extents() takes a start offset and a byte length and iterates over the inode, adding extents (marked as unwritten) until len is reached. Existing extents are skipped over. Signed-off-by: Mark Fasheh --- fs/ocfs2/alloc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'fs/ocfs2/alloc.h') diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index d3acf45..e3284f3 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -34,6 +34,7 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, u32 cpos, u64 start_blk, u32 new_clusters, + u8 flags, struct ocfs2_alloc_context *meta_ac); struct ocfs2_cached_dealloc_ctxt; int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh, -- cgit v1.1 From 35edec1d52c075975991471d624b33b9336226f2 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Fri, 6 Jul 2007 14:41:18 -0700 Subject: ocfs2: update truncate handling of partial clusters The partial cluster zeroing code used during truncate usually assumes that the rightmost byte in the range to be zeroed lies on a cluster boundary. This makes sense for truncate, but punching holes might require zeroing on non-aligned rightmost boundaries. Signed-off-by: Mark Fasheh --- fs/ocfs2/alloc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/ocfs2/alloc.h') diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index e3284f3..752ef86 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -95,8 +95,8 @@ struct ocfs2_truncate_context { struct buffer_head *tc_last_eb_bh; }; -int ocfs2_zero_tail_for_truncate(struct inode *inode, handle_t *handle, - u64 new_i_size); +int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, + u64 range_start, u64 range_end); int ocfs2_prepare_truncate(struct ocfs2_super *osb, struct inode *inode, struct buffer_head *fe_bh, -- cgit v1.1 From 063c4561f52a74de686fe0ff2f96f4f54c9fecd2 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Tue, 3 Jul 2007 13:34:11 -0700 Subject: ocfs2: support for removing file regions Provide an internal interface for the removal of arbitrary file regions. ocfs2_remove_inode_range() takes a byte range within a file and will remove existing extents within that range. Partial clusters will be zeroed so that any read from within the region will return zeros. Signed-off-by: Mark Fasheh --- fs/ocfs2/alloc.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'fs/ocfs2/alloc.h') diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 752ef86..990df48 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -41,6 +41,10 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh, handle_t *handle, u32 cpos, u32 len, u32 phys, struct ocfs2_alloc_context *meta_ac, struct ocfs2_cached_dealloc_ctxt *dealloc); +int ocfs2_remove_extent(struct inode *inode, struct buffer_head *di_bh, + u32 cpos, u32 len, handle_t *handle, + struct ocfs2_alloc_context *meta_ac, + struct ocfs2_cached_dealloc_ctxt *dealloc); int ocfs2_num_free_extents(struct ocfs2_super *osb, struct inode *inode, struct ocfs2_dinode *fe); @@ -68,6 +72,12 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb, struct ocfs2_dinode **tl_copy); int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, struct ocfs2_dinode *tl_copy); +int ocfs2_truncate_log_needs_flush(struct ocfs2_super *osb); +int ocfs2_truncate_log_append(struct ocfs2_super *osb, + handle_t *handle, + u64 start_blk, + unsigned int num_clusters); +int __ocfs2_flush_truncate_log(struct ocfs2_super *osb); /* * Process local structure which describes the block unlinks done -- cgit v1.1