btrfs: Error Handling Patchset
Subsystems (2)
cover btrfs: Error Handling Patchset
This is the error handling patchset for btrfs.
The series is comprised of several groups of patches:
- Adding new btrfs_panic and btrfs_error routines
- Adding the ability to abort transactions
- Converting functions that don't have error conditions to return void
- Eliminating the gfp_t argument to lock_ and unlock_extent, as they are always called with GFP_NOFS
- Pushing up errors to handle them and eliminate BUG_ON sites
- Several other bug fixes for issues we encountered during testing
I'd like to thank David Sterba for a putting a ton of effort into testing and review.
-Jeff
PATCH 1/35 btrfs: Add btrfs_panic()
As part of the effort to eliminate BUG_ON as an error handling technique, we need to determine which errors are actual logic errors, which are on-disk corruption, and which are normal runtime errors e.g. -ENOMEM.
Annotating these error cases is helpful to understand and report them.
This patch adds a btrfs_panic() routine that will either panic or BUG depending on the new -ofatal_errors={panic,bug} mount option. Since there are still so many BUG_ONs, it defaults to BUG for now but I expect that to change once the error handling effort has made significant progress.
--- fs/btrfs/ctree.h | 11 +++++++++++ fs/btrfs/super.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletions(-)
fs/btrfs/ctree.h +11 -0
@@ -1503,6 +1503,7 @@ struct btrfs_ioctl_defrag_range_args {#define BTRFS_MOUNT_SKIP_BALANCE (1 << 19)#define BTRFS_MOUNT_CHECK_INTEGRITY (1 << 20)#define BTRFS_MOUNT_CHECK_INTEGRITY_INCLUDING_EXTENT_DATA (1 << 21) +#define BTRFS_MOUNT_PANIC_ON_FATAL_ERROR (1 << 22)#define btrfs_clear_opt (o, opt) ((o) &= ~BTRFS_MOUNT_##opt)#define btrfs_set_opt (o, opt) ((o) |= BTRFS_MOUNT_##opt)
@@ -2970,6 +2971,16 @@ do { \__btrfs_std_error ((fs_info), __func__, __LINE__, (errno));\ }while (0 ) +void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, + unsigned int line, int errno, const char *fmt, ...); + +#define btrfs_panic(fs_info, errno, fmt, args...) \ +do { \ + struct btrfs_fs_info *_i = (fs_info); \ + __btrfs_panic(_i, __func__, __LINE__, errno, fmt, ##args); \ + BUG_ON(!(_i->mount_opt & BTRFS_MOUNT_PANIC_ON_FATAL_ERROR)); \ +} while (0) +/* acl.c */ #ifdef CONFIG_BTRFS_FS_POSIX_ACL struct posix_acl *btrfs_get_acl (struct inode *inode,int type);
fs/btrfs/super.c +49 -1
86 lines not on this page · raw message
Signature · 1 line
1.7.9
PATCH 2/35 btrfs: Catch locking failures in {set,clear,convert}_extent_bit
In reply to Jeff MahoneyThe *_state functions can only return 0 or -EEXIST. This patch addresses the cases where those functions returning -EEXIST represent a locking failure. It handles them by panicking with an appropriate error message.
--- fs/btrfs/extent_io.c | 58 ++++++++++++++++++++++++++++++++----------------- 1 files changed, 38 insertions(+), 20 deletions(-)
fs/btrfs/extent_io.c +38 -20
@@ -53,6 +53,12 @@ struct extent_page_data { unsigned int sync_io:1; }; +static inline struct btrfs_fs_info * +tree_fs_info (struct extent_io_tree *tree) +{ +return btrfs_sb (tree->mapping->host->i_sb); +} +int __init extent_io_init (void ) { extent_state_cache = kmem_cache_create("extent_state",
@@ -439,6 +445,13 @@ alloc_extent_state_atomic(struct extent_state *prealloc)return prealloc; } +void extent_io_tree_panic (struct extent_io_tree *tree,int err) +{ +btrfs_panic (tree_fs_info (tree), err,"Locking error: " +"Extent tree was modified by another " +"thread while locked." ); +} +/* * clear some bits on a range in the tree. This may require splitting * or inserting elements in the tree, so the gfp mask is used to
@@ -542,7 +555,9 @@ hit_next: prealloc =alloc_extent_state_atomic (prealloc);BUG_ON (!prealloc); err =split_state (tree, state, prealloc, start); -BUG_ON (err == -EEXIST ); +if (err) +extent_io_tree_panic (tree, err); + prealloc =NULL ;if (err) goto out;
@@ -564,7 +579,9 @@ hit_next: prealloc =alloc_extent_state_atomic (prealloc);BUG_ON (!prealloc); err =split_state (tree, state, prealloc, end +1 ); -BUG_ON (err == -EEXIST ); +if (err) +extent_io_tree_panic (tree, err); +if (wake)wake_up (&state->wq);
@@ -742,8 +759,10 @@ again: prealloc =alloc_extent_state_atomic (prealloc);BUG_ON (!prealloc); err =insert_state (tree, prealloc, start, end, &bits); +if (err) +extent_io_tree_panic (tree, err); + prealloc =NULL ; -BUG_ON (err == -EEXIST ); goto out; } state = rb_entry(node, struct extent_state, rb_node);
@@ -809,7 +828,9 @@ hit_next: prealloc =alloc_extent_state_atomic (prealloc);BUG_ON (!prealloc); err =split_state (tree, state, prealloc, start); -BUG_ON (err == -EEXIST ); +if (err) +extent_io_tree_panic (tree, err); + prealloc =NULL ;if (err) goto out;
@@ -846,12 +867,9 @@ hit_next:*/ err =insert_state (tree, prealloc, start, this_end, &bits); -BUG_ON (err == -EEXIST ); -if (err) { -free_extent_state (prealloc); - prealloc =NULL ; - goto out; - } +if (err) +extent_io_tree_panic (tree, err); +cache_state (prealloc, cached_state); prealloc =NULL ; start = this_end +1 ;
@@ -873,7 +891,8 @@ hit_next: prealloc =alloc_extent_state_atomic (prealloc);BUG_ON (!prealloc); err =split_state (tree, state, prealloc, end +1 ); -BUG_ON (err == -EEXIST ); +if (err) +extent_io_tree_panic (tree, err);set_state_bits (tree, prealloc, &bits);cache_state (prealloc, cached_state);
@@ -946,7 +965,8 @@ again: } err =insert_state (tree, prealloc, start, end, &bits); prealloc =NULL ; -BUG_ON (err == -EEXIST ); +if (err) +extent_io_tree_panic (tree, err); goto out; } state = rb_entry(node, struct extent_state, rb_node);
@@ -1002,7 +1022,8 @@ hit_next: goto out; } err =split_state (tree, state, prealloc, start); -BUG_ON (err == -EEXIST ); +if (err) +extent_io_tree_panic (tree, err); prealloc =NULL ;if (err) goto out;
@@ -1041,12 +1062,8 @@ hit_next:*/ err =insert_state (tree, prealloc, start, this_end, &bits); -BUG_ON (err == -EEXIST ); -if (err) { -free_extent_state (prealloc); - prealloc =NULL ; - goto out; - } +if (err) +extent_io_tree_panic (tree, err); prealloc =NULL ; start = this_end +1 ; goto search_again;
@@ -1065,7 +1082,8 @@ hit_next: } err =split_state (tree, state, prealloc, end +1 ); -BUG_ON (err == -EEXIST ); +if (err) +extent_io_tree_panic (tree, err);set_state_bits (tree, prealloc, &bits);clear_state_bit (tree, prealloc, &clear_bits,0 );
Signature · 1 line
1.7.9
PATCH 3/35 btrfs: Panic on bad rbtree operations
In reply to Jeff MahoneyThe ordered data and relocation trees have BUG_ONs to protect against bad tree operations.
This patch replaces them with a panic that will report the problem.
--- fs/btrfs/ordered-data.c | 12 ++++++++++-- fs/btrfs/relocation.c | 36 +++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 9 deletions(-)
fs/btrfs/ordered-data.c +10 -2
@@ -59,6 +59,14 @@ static struct rb_node *tree_insert(struct rb_root *root, u64 file_offset,return NULL ; } +static void ordered_data_tree_panic (struct inode *inode,int errno, +u64 offset) +{ +struct btrfs_fs_info *fs_info =btrfs_sb (inode->i_sb); +btrfs_panic (fs_info, errno,"Inconsistency in ordered tree at offset " +"%llu\n" , (unsigned long long )offset); +} +/* * look for a given offset in the tree, and if it can't be found return the * first lesser offset
@@ -207,7 +215,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,spin_lock (&tree->lock); node =tree_insert (&tree->tree, file_offset, &entry->rb_node); -BUG_ON (node); +if (node) +ordered_data_tree_panic (inode, -EEXIST , file_offset);spin_unlock (&tree->lock);spin_lock (&BTRFS_I (inode)->root->fs_info->ordered_extent_lock);
@@ -215,7 +224,6 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, &BTRFS_I(inode)->root->fs_info->ordered_extents);spin_unlock (&BTRFS_I (inode)->root->fs_info->ordered_extent_lock); -BUG_ON (node);return 0 ; }
fs/btrfs/relocation.c +29 -7
@@ -326,6 +326,19 @@ static struct rb_node *tree_search(struct rb_root *root, u64 bytenr)return NULL ; } +void backref_tree_panic (struct rb_node *rb_node,int errno, +u64 bytenr) +{ + +struct btrfs_fs_info *fs_info =NULL ; + struct backref_node *bnode = rb_entry(rb_node, struct backref_node, + rb_node); +if (bnode->root) + fs_info = bnode->root->fs_info; +btrfs_panic (fs_info, errno,"Inconsistency in backref cache " +"found at offset %llu\n" , (unsigned long long )bytenr); +} +/* * walk up backref nodes until reach node presents tree root */
@@ -452,7 +465,8 @@ static void update_backref_node(struct backref_cache *cache,rb_erase (&node->rb_node, &cache->rb_root); node->bytenr = bytenr; rb_node =tree_insert (&cache->rb_root, node->bytenr, &node->rb_node); -BUG_ON (rb_node); +if (rb_node) +backref_tree_panic (rb_node, -EEXIST , bytenr); }/*
@@ -999,7 +1013,8 @@ next:if (!cowonly) { rb_node =tree_insert (&cache->rb_root, node->bytenr, &node->rb_node); -BUG_ON (rb_node); +if (rb_node) +backref_tree_panic (rb_node, -EEXIST , node->bytenr);list_add_tail (&node->lower, &cache->leaves); }
@@ -1034,7 +1049,9 @@ next:if (!cowonly) { rb_node =tree_insert (&cache->rb_root, upper->bytenr, &upper->rb_node); -BUG_ON (rb_node); +if (rb_node) +backref_tree_panic (rb_node, -EEXIST , + upper->bytenr); }list_add_tail (&edge->list[UPPER ], &upper->lower);
@@ -1180,7 +1197,8 @@ static int clone_backref_node(struct btrfs_trans_handle *trans, rb_node =tree_insert (&cache->rb_root, new_node->bytenr, &new_node->rb_node); -BUG_ON (rb_node); +if (rb_node) +backref_tree_panic (rb_node, -EEXIST , new_node->bytenr);if (!new_node->lowest) {list_for_each_entry (new_edge, &new_node->lower, list[UPPER ]) {
@@ -1252,7 +1270,8 @@ static int __update_reloc_root(struct btrfs_root *root, int del) rb_node =tree_insert (&rc->reloc_root_tree.rb_root, node->bytenr, &node->rb_node);spin_unlock (&rc->reloc_root_tree.lock); -BUG_ON (rb_node); +if (rb_node) +backref_tree_panic (rb_node, -EEXIST , node->bytenr); }else {list_del_init (&root->root_list);kfree (node);
@@ -3154,7 +3173,8 @@ static int add_tree_block(struct reloc_control *rc, block->key_ready =0 ; rb_node =tree_insert (blocks, block->bytenr, &block->rb_node); -BUG_ON (rb_node); +if (rb_node) +backref_tree_panic (rb_node, -EEXIST , block->bytenr);return 0 ; }
@@ -3426,7 +3446,9 @@ static int find_data_references(struct reloc_control *rc, block->key_ready =1 ; rb_node =tree_insert (blocks, block->bytenr, &block->rb_node); -BUG_ON (rb_node); +if (rb_node) +backref_tree_panic (rb_node, -EEXIST , + block->bytenr); }if (counted) added =1 ;
Signature · 1 line
1.7.9
PATCH 4/35 btrfs: Fix kfree of member instead of structure
In reply to Jeff MahoneyCorrectness fix: The kfree calls in the add_delayed_* functions free the node that's passed into it, but the node is a member of another structure. It works because it's always the first member of the containing structure, but it should really be using the containing structure itself.
--- fs/btrfs/delayed-ref.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
fs/btrfs/delayed-ref.c +3 -3
@@ -487,7 +487,7 @@ static noinline int add_delayed_ref_head(struct btrfs_fs_info *fs_info,* we've updated the existing ref, free the newly * allocated ref */ -kfree (ref); +kfree (head_ref); }else { delayed_refs->num_heads++; delayed_refs->num_heads_ready++;
@@ -549,7 +549,7 @@ static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info,* we've updated the existing ref, free the newly * allocated ref */ -kfree (ref); +kfree (full_ref); }else { delayed_refs->num_entries++; trans->delayed_ref_updates++;
@@ -611,7 +611,7 @@ static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info,* we've updated the existing ref, free the newly * allocated ref */ -kfree (ref); +kfree (full_ref); }else { delayed_refs->num_entries++; trans->delayed_ref_updates++;
Signature · 1 line
1.7.9
PATCH 5/35 btrfs: Simplify btrfs_insert_root
In reply to Jeff Mahoneybtrfs_insert_root is just a wrapper for btrfs_insert_item. Just return the error directly.
--- fs/btrfs/root-tree.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-)
fs/btrfs/root-tree.c +3 -6
@@ -116,13 +116,10 @@ out:return ret; } -int btrfs_insert_root (struct btrfs_trans_handle *trans,struct btrfs_root - *root,struct btrfs_key *key,struct btrfs_root_item - *item) +int btrfs_insert_root (struct btrfs_trans_handle *trans,struct btrfs_root *root, +struct btrfs_key *key,struct btrfs_root_item *item) { -int ret; - ret =btrfs_insert_item (trans, root, key, item,sizeof (*item)); -return ret; +return btrfs_insert_item (trans, root, key, item,sizeof (*item)); }/*
Signature · 1 line
1.7.9
PATCH 6/35 btrfs: clean_tree_block should panic on observed memory corruption and return void
In reply to Jeff Mahoney The only error condition in clean_tree_block is an accounting bug. Returning without modifying dirty_metadata_bytes and as if the cleaning as been performed may cause problems later so it should panic instead.
It should probably be a BUG_ON but we have btrfs_panic now.
--- fs/btrfs/disk-io.c | 15 ++++++++++----- fs/btrfs/disk-io.h | 4 ++-- 2 files changed, 12 insertions(+), 7 deletions(-)
fs/btrfs/disk-io.c +10 -5
@@ -1109,8 +1109,8 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, } -int clean_tree_block (struct btrfs_trans_handle *trans,struct btrfs_root *root, -struct extent_buffer *buf) +void clean_tree_block (struct btrfs_trans_handle *trans,struct btrfs_root *root, +struct extent_buffer *buf) {struct inode *btree_inode = root->fs_info->btree_inode; if (btrfs_header_generation(buf) ==
@@ -1121,8 +1121,14 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,spin_lock (&root->fs_info->delalloc_lock);if (root->fs_info->dirty_metadata_bytes >= buf->len) root->fs_info->dirty_metadata_bytes -= buf->len; -else -WARN_ON (1 ); +else { +spin_unlock (&root->fs_info->delalloc_lock); +btrfs_panic (root->fs_info, -EOVERFLOW , +"Can't clear %lu bytes from " +" dirty_mdatadata_bytes (%lu)" , + buf->len, + root->fs_info->dirty_metadata_bytes); + }spin_unlock (&root->fs_info->delalloc_lock); }
@@ -1131,7 +1137,6 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,clear_extent_buffer_dirty (&BTRFS_I (btree_inode)->io_tree, buf); } -return 0 ; } static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
fs/btrfs/disk-io.h +2 -2
@@ -44,8 +44,8 @@ int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize, int mirror_num, struct extent_buffer **eb);struct extent_buffer *btrfs_find_create_tree_block (struct btrfs_root *root,u64 bytenr,u32 blocksize); -int clean_tree_block (struct btrfs_trans_handle *trans, -struct btrfs_root *root,struct extent_buffer *buf); +void clean_tree_block (struct btrfs_trans_handle *trans, +struct btrfs_root *root,struct extent_buffer *buf);int open_ctree (struct super_block *sb,struct btrfs_fs_devices *fs_devices,char *options);
Signature · 1 line
1.7.9
PATCH 7/35 btrfs: avoid NULL deref in btrfs_reserve_extent with DEBUG_ENOSPC
In reply to Jeff Mahoney __find_space_info can return NULL but we don't check it before calling dump_space_info().
--- fs/btrfs/extent-tree.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
fs/btrfs/extent-tree.c +2 -1
@@ -5838,7 +5838,8 @@ again:printk (KERN_ERR "btrfs allocation failed flags %llu, " "wanted %llu\n" , (unsigned long long )data, (unsigned long long )num_bytes); -dump_space_info (sinfo, num_bytes,1 ); +if (sinfo) +dump_space_info (sinfo, num_bytes,1 ); } }
Signature · 1 line
1.7.9
PATCH 8/35 btrfs: Remove set bits return from clear_extent_bit
In reply to Jeff MahoneyThere is only one caller of clear_extent_bit that checks the return value and it only checks if it's negative. Since there are no users of the returned bits functionality of clear_extent_bit, stop returning it and avoid complicating error handling.
--- fs/btrfs/extent_io.c | 12 +++++------- 1 files changed, 5 insertions(+), 7 deletions(-)
fs/btrfs/extent_io.c +5 -7
@@ -462,8 +462,7 @@ void extent_io_tree_panic(struct extent_io_tree *tree, int err)* * the range [start, end] is inclusive. * -* This takes the tree lock, and returns < 0 on error, > 0 if any of the -* bits were already set, or zero if none of the bits were already set. +* This takes the tree lock, and returns 0 on success and < 0 on error. */ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits, int wake, int delete,
@@ -477,7 +476,6 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,struct rb_node *node;u64 last_end;int err; -int set =0 ;int clear =0 ;if (delete)
@@ -562,7 +560,7 @@ hit_next:if (err) goto out;if (state->end <= end) { - set |=clear_state_bit (tree, state, &bits, wake); +clear_state_bit (tree, state, &bits, wake);if (last_end == (u64)-1 ) goto out; start = last_end +1 ;
@@ -585,13 +583,13 @@ hit_next:if (wake)wake_up (&state->wq); - set |=clear_state_bit (tree, prealloc, &bits, wake); +clear_state_bit (tree, prealloc, &bits, wake); prealloc =NULL ; goto out; } - set |=clear_state_bit (tree, state, &bits, wake); +clear_state_bit (tree, state, &bits, wake); next:if (last_end == (u64)-1 ) goto out;
@@ -608,7 +606,7 @@ out:if (prealloc)free_extent_state (prealloc); -return set; +return 0 ; search_again:if (start > end)
Signature · 1 line
1.7.9
Re: [patch 08/35] btrfs: Remove set bits return from clear_extent_bit
Quoted 5 lines · Jeff Mahoney
There is only one caller of
clear_extent_bitthat checks the return value and it only checks if it's negative. Since there are no users of the returned bits functionality ofclear_extent_bit, stop returning it and avoid complicating error handling.
A similar one from Li:
http://www.spinics.net/lists/linux-btrfs/msg15458.html
thanks,
liubo
Quoted 61 lines
Signed-off-by Jeff Mahoney <[email protected]>--- fs/btrfs/extent_io.c | 12 +++++------- 1 files changed, 5 insertions(+), 7 deletions(-)fs/btrfs/extent_io.c +5
-7@@ -462,8 +462,7 @@ void extent_io_tree_panic(struct extent_io_tree *tree, int err)* * the range [start, end] is inclusive. * -* This takes the tree lock, and returns < 0 on error, > 0 if any of the -* bits were already set, or zero if none of the bits were already set. +* This takes the tree lock, and returns 0 on success and < 0 on error. */ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits, int wake, int delete,@@ -477,7 +476,6 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,struct rb_node *node;u64 last_end;int err; -int set =0 ;int clear =0 ;if (delete)@@ -562,7 +560,7 @@ hit_next:if (err) goto out;if (state->end <= end) { - set |=clear_state_bit (tree, state, &bits, wake); +clear_state_bit (tree, state, &bits, wake);if (last_end == (u64)-1 ) goto out; start = last_end +1 ;@@ -585,13 +583,13 @@ hit_next:if (wake)wake_up (&state->wq); - set |=clear_state_bit (tree, prealloc, &bits, wake); +clear_state_bit (tree, prealloc, &bits, wake); prealloc =NULL ; goto out; } - set |=clear_state_bit (tree, state, &bits, wake); +clear_state_bit (tree, state, &bits, wake); next:if (last_end == (u64)-1 ) goto out;@@ -608,7 +606,7 @@ out:if (prealloc)free_extent_state (prealloc); -return set; +return 0 ; search_again:if (start > end)
Re: [patch 08/35] btrfs: Remove set bits return from clear_extent_bit
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 9 lines · Liu Bo
Quoted 5 lines · Jeff Mahoney
There is only one caller of
clear_extent_bitthat checks the return value and it only checks if it's negative. Since there are no users of the returned bits functionality ofclear_extent_bit, stop returning it and avoid complicating error handling.A similar one from Li:
http://www.spinics.net/lists/linux-btrfs/msg15458.html
Yep, I saw that one fly by. This one has been part of this patchset for months.
- -Jeff
Quoted 29 lines
Quoted 29 lines
Signed-off-by Jeff Mahoney <[email protected]> ---
fs/btrfs/extent_io.c| 12 +++++------- 1 files changed, 5
insertions(+), 7 deletions(-)fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +0
-0601f23b..a4a7a18 100644 ---
a/fs/btrfs/extent_io.c+++b/fs/btrfs/extent_io.c@@ -462,8 +462,7 @@ voidextent_io_tree_panic(struct extent_io_tree *tree, int err)* * the range [start, end] is inclusive. * - * This takes the tree lock, and returns < 0 on error, > 0 if any of the - * bits were already set, or zero if none of the bits were already set. + * This takes the tree lock, and returns 0 on success and < 0 on error. */ int clear_extent_bit(structextent_io_tree*tree, u64 start, u64 end, int bits, int wake, int delete, @@ -477,7 +476,6 @@ int clear_extent_bit(structextent_io_tree*tree, u64 start,
u64 end, structrb_node*node; u64last_end; int err; - int set =
0; int clear = 0;if (delete) @@ -562,7 +560,7 @@
hit_next: if (err) goto out; if
(state->end<= end) { - set |= clear_state_bit(tree, state,
&bits, wake); +clear_state_bit(tree, state, &bits, wake); if
(last_end== (u64)-1) goto out; start =last_end+ 1; @@ -585,13 +583,13 @@hit_next: if (wake)wake_up(&state->wq);fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +0
-1- set |= clear_state_bit(tree, prealloc, &bits, wake); +
clear_state_bit(tree, prealloc, &bits, wake);prealloc = NULL; goto out; }
Quoted 10 lines
Quoted 8 lines
fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +0
-1- set |= clear_state_bit(tree, state, &bits, wake); +
clear_state_bit(tree, state, &bits, wake); next: if (last_end== (u64)-1) goto out; @@ -608,7 +606,7 @@ out: if (prealloc)free_extent_state(prealloc);fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +0
-1- return set; + return 0;
search_again: if (start > end)
- --
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.18 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQIcBAEBAgAGBQJPao+0AAoJEB57S2MheeWyUkQP/2aHj9EnC1o6QffQ/Z0xykJp O5e/qoLaAJ9bbvcn0fsaa2qjXOZTx40m0L+VqAfuzSQ9U4ScJr16GoaLkwXBOSOO P2/L5PX5sMzDZYGlG2WAcHras97adr/kViNgT79jwmscaTqs/QBftTajADbwF8rL 1vI5CRsrxd/iWvNrjTDyMYT8lVZmVhuRLOGtS99SGrRkkKQCk+L6edyPUH9/mduV xhayJjAjVyVwzIk1hCJQ7ybM1975vVY92p0XEh8Oa46FSEa2puTZ+fVQjMEjPtcu J/91jgOy2u/h7m2RlYguPmAKN3U2XIlOpIrAcbiU49ugbe4DUiCPV+77gPUU+Ch5 LCJhIHHZulqlB8KM985r5eyxFSYXVdZjN63zhEeptU9z8XY5wDODLcweeKLBW0E5 AAyjeobBJYWKDauisbjeBCuIuiltNyK95pjRtPjVu3pAlAmaKZgJmXPw/8hglgLD hm/g5e3Zk6LHxFhOb4gBa+5qqQ6XUNcgSk5FOOR6abSHZlJ7LBm2TIbKYlrhsWib RssmxAlRAbY7supvJilHEVnVV/RN4ggFVeQ9nzRN2LV5gJychfTBst5xFRRxHoOX Ob8fqxz32iqyCQBFXkqqAbr4j67ok0DW8bBYCL+O8fQE63ZJeiZ71fphWKh0P4GX /WNlhKTSN1BSIaVlqmvm
=iuYq
-----END PGP SIGNATURE-----
PATCH 9/35 btrfs: find_and_setup_root error push-up
In reply to Jeff Mahoneyfind_and_setup_root BUGs when it encounters an error from btrfs_find_last_root, which can occur if a path can't be allocated.
This patch pushes it up to its callers where it is already handled.
--- fs/btrfs/disk-io.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-)
fs/btrfs/disk-io.c +6 -5
@@ -1197,10 +1197,10 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,return 0 ; } -static int find_and_setup_root (struct btrfs_root *tree_root, -struct btrfs_fs_info *fs_info, -u64 objectid, -struct btrfs_root *root) +static int __must_check find_and_setup_root (struct btrfs_root *tree_root, +struct btrfs_fs_info *fs_info, +u64 objectid, +struct btrfs_root *root) {int ret;u32 blocksize;
@@ -1213,7 +1213,8 @@ static int find_and_setup_root(struct btrfs_root *tree_root, &root->root_item, &root->root_key);if (ret >0 )return -ENOENT ; -BUG_ON (ret); +else if (ret <0 ) +return ret; generation =btrfs_root_generation (&root->root_item); blocksize =btrfs_level_size (root,btrfs_root_level (&root->root_item));
Signature · 1 line
1.7.9
PATCH 10/35 btrfs: btrfs_update_root error push-up
In reply to Jeff Mahoneybtrfs_update_root BUG's when it can't alloc a path, yet it can recover from a search error. This patch returns -ENOMEM instead.
--- fs/btrfs/ctree.h | 7 ++++--- fs/btrfs/root-tree.c | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-)
fs/btrfs/ctree.h +4 -3
@@ -2724,9 +2724,10 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,int btrfs_insert_root (struct btrfs_trans_handle *trans,struct btrfs_root *root,struct btrfs_key *key,struct btrfs_root_item *item); -int btrfs_update_root (struct btrfs_trans_handle *trans,struct btrfs_root - *root,struct btrfs_key *key,struct btrfs_root_item - *item); +int __must_check btrfs_update_root (struct btrfs_trans_handle *trans, +struct btrfs_root *root, +struct btrfs_key *key, +struct btrfs_root_item *item);int btrfs_find_last_root (struct btrfs_root *root,u64 objectid,struct btrfs_root_item *item,struct btrfs_key *key);int btrfs_find_dead_roots (struct btrfs_root *root,u64 objectid);
fs/btrfs/root-tree.c +3 -1
@@ -93,7 +93,9 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_rootunsigned long ptr; path =btrfs_alloc_path (); -BUG_ON (!path); +if (!path) +return -ENOMEM ; + ret =btrfs_search_slot (trans, root, key, path,0 ,1 );if (ret <0 ) goto out;
Signature · 1 line
1.7.9
PATCH 11/35 btrfs: Simplify btrfs_submit_bio_hook
In reply to Jeff Mahoneybtrfs_submit_bio_hook currently calls btrfs_bio_wq_end_io in either case of an if statement that determines one of the arguments.
This patch moves the function call outside of the if statement and uses it to only determine the different argument. This allows us to catch an error in one place in a more visually obvious way.
--- fs/btrfs/inode.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
fs/btrfs/inode.c +4 -3
@@ -1479,13 +1479,14 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,struct btrfs_root *root =BTRFS_I (inode)->root;int ret =0 ;int skip_sum; +int metadata =0 ; skip_sum =BTRFS_I (inode)->flags &BTRFS_INODE_NODATASUM ;if (btrfs_is_free_space_inode (root, inode)) - ret =btrfs_bio_wq_end_io (root->fs_info, bio,2 ); -else - ret =btrfs_bio_wq_end_io (root->fs_info, bio,0 ); + metadata =2 ; + + ret =btrfs_bio_wq_end_io (root->fs_info, bio, metadata);BUG_ON (ret);if (!(rw &REQ_WRITE )) {
Signature · 1 line
1.7.9
PATCH 12/35 btrfs: Factor out tree->ops->merge_bio_hook call
In reply to Jeff MahoneyIn submit_extent_page, there's a visually noisy if statement that, in the midst of other conditions, does the tree dependency for tree->ops and tree->ops->merge_bio_hook before calling it, and then another condition afterwards. If an error is returned from merge_bio_hook, there's no way to catch it. It's considered a routine "1" return value instead of a failure.
This patch factors out the dependency check into a new local merge_bio routine and BUG's on an error. The if statement is less noisy as a side- effect.
--- fs/btrfs/extent_io.c | 17 ++++++++++++++--- fs/btrfs/inode.c | 5 +++-- 2 files changed, 17 insertions(+), 5 deletions(-)
fs/btrfs/extent_io.c +14 -3
@@ -2429,6 +2429,19 @@ static int submit_one_bio(int rw, struct bio *bio, int mirror_num,return ret; } +static int merge_bio (struct extent_io_tree *tree,struct page *page, +unsigned long offset,size_t size,struct bio *bio, +unsigned long bio_flags) +{ +int ret =0 ; +if (tree->ops && tree->ops->merge_bio_hook) + ret = tree->ops->merge_bio_hook (page, offset, size, bio, + bio_flags); +BUG_ON (ret <0 ); +return ret; + +} + static int submit_extent_page(int rw, struct extent_io_tree *tree, struct page *page, sector_t sector, size_t size, unsigned long offset,
@@ -2457,9 +2470,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, sector;if (prev_bio_flags != bio_flags || !contig || - (tree->ops && tree->ops->merge_bio_hook && - tree->ops->merge_bio_hook (page, offset, page_size, bio, - bio_flags)) || +merge_bio (tree, page, offset, page_size, bio, bio_flags) ||bio_add_page (bio, page, page_size, offset) < page_size) { ret =submit_one_bio (rw, bio, mirror_num, prev_bio_flags);
fs/btrfs/inode.c +3 -2
@@ -1425,10 +1425,11 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset, map_length = length; ret =btrfs_map_block (map_tree,READ , logical, &map_length,NULL ,0 ); - +/* Will always return 0 or 1 with map_multi == NULL */ +BUG_ON (ret <0 );if (map_length < length + size)return 1 ; -return ret; +return 0 ; }/*
Signature · 1 line
1.7.9
PATCH 13/35 btrfs: ->submit_bio_hook error push-up
In reply to Jeff MahoneyThis pushes failures from the submit_bio_hook callbacks, btrfs_submit_bio_hook and btree_submit_bio_hook into the callers, including callers of submit_one_bio where it catches the failures with BUG_ON.
It also pushes up through the ->readpage_io_failed_hook to end_bio_extent_writepage where the error is already caught with BUG_ON.
--- fs/btrfs/disk-io.c | 6 +++--- fs/btrfs/extent_io.c | 37 ++++++++++++++++++++++++++----------- fs/btrfs/inode.c | 3 ++- 3 files changed, 31 insertions(+), 15 deletions(-)
fs/btrfs/disk-io.c +3 -3
@@ -847,9 +847,9 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, {int ret; - ret =btrfs_bio_wq_end_io (BTRFS_I (inode)->root->fs_info, - bio,1 ); -BUG_ON (ret); + ret =btrfs_bio_wq_end_io (BTRFS_I (inode)->root->fs_info, bio,1 ); +if (ret) +return ret;if (!(rw &REQ_WRITE )) {/*
fs/btrfs/extent_io.c +26 -11
@@ -2199,6 +2199,7 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end)/* Writeback already completed */ if (ret ==0 )return 1 ; +BUG_ON (ret <0 ); }if (!uptodate) {
@@ -2351,6 +2352,7 @@ error_handled:if (ret ==0 ) goto error_handled; } +BUG_ON (ret <0 ); }if (uptodate) {
@@ -2402,8 +2404,8 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,return bio; } -static int submit_one_bio (int rw,struct bio *bio,int mirror_num, -unsigned long bio_flags) +static int __must_check submit_one_bio (int rw,struct bio *bio, +int mirror_num,unsigned long bio_flags) {int ret =0 ;struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt -1 ;
@@ -2474,6 +2476,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, bio_add_page(bio, page, page_size, offset) < page_size) { ret = submit_one_bio(rw, bio, mirror_num, prev_bio_flags); + BUG_ON(ret < 0); bio = NULL; } else {return 0 ;
@@ -2494,8 +2497,10 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,if (bio_ret) *bio_ret = bio; -else +else { ret =submit_one_bio (rw, bio, mirror_num, bio_flags); +BUG_ON (ret <0 ); + }return ret; }
@@ -2707,8 +2712,10 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page, ret =__extent_read_full_page (tree, page, get_extent, &bio, mirror_num, &bio_flags); -if (bio) +if (bio) { ret =submit_one_bio (READ , bio, mirror_num, bio_flags); +BUG_ON (ret <0 ); + }return ret; }
@@ -3126,10 +3133,14 @@ retry:static void flush_epd_write_bio (struct extent_page_data *epd) {if (epd->bio) { +int rw =WRITE ; +int ret; +if (epd->sync_io) -submit_one_bio (WRITE_SYNC , epd->bio,0 ,0 ); -else -submit_one_bio (WRITE , epd->bio,0 ,0 ); + rw =WRITE_SYNC ; + + ret =submit_one_bio (rw, epd->bio,0 ,0 ); +BUG_ON (ret <0 ); epd->bio =NULL ; } }
@@ -3245,8 +3256,10 @@ int extent_readpages(struct extent_io_tree *tree,page_cache_release (page); }BUG_ON (!list_empty (pages)); -if (bio) -submit_one_bio (READ , bio,0 , bio_flags); +if (bio) { +int ret =submit_one_bio (READ , bio,0 , bio_flags); +BUG_ON (ret <0 ); + }return 0 ; }
@@ -4075,8 +4088,10 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, } } -if (bio) -submit_one_bio (READ , bio, mirror_num, bio_flags); +if (bio) { + err =submit_one_bio (READ , bio, mirror_num, bio_flags); +BUG_ON (err <0 ); + }if (ret || wait !=WAIT_COMPLETE )return ret;
fs/btrfs/inode.c +2 -1
@@ -1488,7 +1488,8 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, metadata =2 ; ret =btrfs_bio_wq_end_io (root->fs_info, bio, metadata); -BUG_ON (ret); +if (ret) +return ret;if (!(rw &REQ_WRITE )) {if (bio_flags &EXTENT_BIO_COMPRESSED ) {
Signature · 1 line
1.7.9
PATCH 14/35 btrfs: __add_reloc_root error push-up
In reply to Jeff MahoneyThis patch pushes kmalloc errors up to the caller and BUGs in the caller.
The BUG_ON for duplicate reloc tree root insertion is replaced with a panic explaining the issue.
--- fs/btrfs/relocation.c | 22 ++++++++++++++++------ 1 files changed, 16 insertions(+), 6 deletions(-)
fs/btrfs/relocation.c +16 -6
@@ -1221,14 +1221,15 @@ fail:/* * helper to add 'address of tree root -> reloc tree' mapping */ -static int __add_reloc_root (struct btrfs_root *root) +static int __must_check __add_reloc_root (struct btrfs_root *root) {struct rb_node *rb_node;struct mapping_node *node;struct reloc_control *rc = root->fs_info->reloc_ctl; node =kmalloc (sizeof (*node),GFP_NOFS ); -BUG_ON (!node); +if (!node) +return -ENOMEM ; node->bytenr = root->node->start; node->data = root;
@@ -1237,7 +1238,12 @@ static int __add_reloc_root(struct btrfs_root *root) rb_node =tree_insert (&rc->reloc_root_tree.rb_root, node->bytenr, &node->rb_node);spin_unlock (&rc->reloc_root_tree.lock); -BUG_ON (rb_node); +if (rb_node) { +kfree (node); +btrfs_panic (root->fs_info, -EEXIST ,"Duplicate root found " +"for start=%llu while inserting into relocation " +"tree\n" ); + }list_add_tail (&root->root_list, &rc->reloc_roots);return 0 ;
@@ -1353,6 +1359,7 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans,struct btrfs_root *reloc_root;struct reloc_control *rc = root->fs_info->reloc_ctl;int clear_rsv =0 ; +int ret;if (root->reloc_root) { reloc_root = root->reloc_root;
@@ -1372,7 +1379,8 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans,if (clear_rsv) trans->block_rsv =NULL ; -__add_reloc_root (reloc_root); + ret =__add_reloc_root (reloc_root); +BUG_ON (ret <0 ); root->reloc_root = reloc_root;return 0 ; }
@@ -4226,7 +4234,8 @@ int btrfs_recover_relocation(struct btrfs_root *root) reloc_root->root_key.offset);BUG_ON (IS_ERR (fs_root)); -__add_reloc_root (reloc_root); + err =__add_reloc_root (reloc_root); +BUG_ON (err <0 ); fs_root->reloc_root = reloc_root; }
@@ -4428,7 +4437,8 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, reloc_root =create_reloc_root (trans, root->reloc_root, new_root->root_key.objectid); -__add_reloc_root (reloc_root); + ret =__add_reloc_root (reloc_root); +BUG_ON (ret <0 ); new_root->reloc_root = reloc_root;if (rc->create_reloc_tree) {
Signature · 1 line
1.7.9
PATCH 15/35 btrfs: return void in functions without error conditions
In reply to Jeff Mahoney---
fs/btrfs/async-thread.c | 15 +-- fs/btrfs/async-thread.h | 4 fs/btrfs/compression.c | 8 - fs/btrfs/compression.h | 2 fs/btrfs/ctree.c | 200 ++++++++++++++----------------------------- fs/btrfs/ctree.h | 45 ++++----- fs/btrfs/delayed-inode.c | 6 - fs/btrfs/delayed-ref.c | 27 +---- fs/btrfs/dir-item.c | 9 - fs/btrfs/disk-io.c | 39 +++----- fs/btrfs/disk-io.h | 2 fs/btrfs/extent-tree.c | 60 +++++------- fs/btrfs/extent_io.c | 35 +++---- fs/btrfs/extent_io.h | 4 fs/btrfs/file-item.c | 25 ++--- fs/btrfs/inode-item.c | 4 fs/btrfs/inode.c | 7 - fs/btrfs/locking.c | 6 - fs/btrfs/locking.h | 4 fs/btrfs/ordered-data.c | 48 +++------- fs/btrfs/ordered-data.h | 24 ++--- fs/btrfs/scrub.c | 36 ++----- fs/btrfs/super.c | 5 - fs/btrfs/transaction.c | 3 fs/btrfs/tree-log.c | 17 +-- fs/btrfs/tree-log.h | 2 fs/btrfs/volumes.c | 18 +-- fs/btrfs/volumes.h | 4 include/trace/events/btrfs.h | 44 +++++++++ 29 files changed, 293 insertions(+), 410 deletions(-)
fs/btrfs/async-thread.c +5 -10
@@ -171,11 +171,11 @@ out:spin_unlock_irqrestore (&workers->lock, flags); } -static noinline int run_ordered_completions(struct btrfs_workers *workers, +static noinline void run_ordered_completions(struct btrfs_workers *workers,struct btrfs_work *work) {if (!workers->ordered) -return 0 ; +return ;set_bit (WORK_DONE_BIT , &work->flags);
@@ -213,7 +213,6 @@ static noinline int run_ordered_completions(struct btrfs_workers *workers, }spin_unlock (&workers->order_lock); -return 0 ; }static void put_worker (struct btrfs_worker_thread *worker)
@@ -399,7 +398,7 @@ again:/* * this will wait for all the worker threads to shutdown */ -int btrfs_stop_workers (struct btrfs_workers *workers) +void btrfs_stop_workers (struct btrfs_workers *workers) {struct list_head *cur;struct btrfs_worker_thread *worker;
@@ -427,7 +426,6 @@ int btrfs_stop_workers(struct btrfs_workers *workers)put_worker (worker); }spin_unlock_irq (&workers->lock); -return 0 ; }/*
@@ -615,14 +613,14 @@ found:* it was taken from. It is intended for use with long running work functions * that make some progress and want to give the cpu up for others. */ -int btrfs_requeue_work (struct btrfs_work *work) +void btrfs_requeue_work (struct btrfs_work *work) {struct btrfs_worker_thread *worker = work->worker;unsigned long flags;int wake =0 ;if (test_and_set_bit (WORK_QUEUED_BIT , &work->flags)) - goto out; +return ;spin_lock_irqsave (&worker->lock, flags);if (test_bit (WORK_HIGH_PRIO_BIT , &work->flags))
@@ -649,9 +647,6 @@ int btrfs_requeue_work(struct btrfs_work *work)if (wake)wake_up_process (worker->task);spin_unlock_irqrestore (&worker->lock, flags); -out: - -return 0 ; }void btrfs_set_work_high_prio (struct btrfs_work *work)
fs/btrfs/async-thread.h +2 -2
@@ -111,9 +111,9 @@ struct btrfs_workers {void btrfs_queue_worker (struct btrfs_workers *workers,struct btrfs_work *work);int btrfs_start_workers (struct btrfs_workers *workers); -int btrfs_stop_workers (struct btrfs_workers *workers); +void btrfs_stop_workers (struct btrfs_workers *workers);void btrfs_init_workers (struct btrfs_workers *workers,char *name,int max,struct btrfs_workers *async_starter); -int btrfs_requeue_work (struct btrfs_work *work); +void btrfs_requeue_work (struct btrfs_work *work);void btrfs_set_work_high_prio (struct btrfs_work *work);#endif
fs/btrfs/compression.c +3 -5
@@ -226,8 +226,8 @@ out:* Clear the writeback bits on all of the file * pages for a compressed write */ -static noinline int end_compressed_writeback(struct inode *inode, u64 start, -unsigned long ram_size) +static noinline void end_compressed_writeback(struct inode *inode, u64 start, +unsigned long ram_size) {unsigned long index = start >>PAGE_CACHE_SHIFT ;unsigned long end_index = (start + ram_size -1 ) >>PAGE_CACHE_SHIFT ;
@@ -253,7 +253,6 @@ static noinline int end_compressed_writeback(struct inode *inode, u64 start, index += ret; }/* the inode may be gone now */ -return 0 ; }/*
@@ -734,7 +733,7 @@ struct btrfs_compress_op *btrfs_compress_op[] = { &btrfs_lzo_compress, }; -int __init btrfs_init_compress (void ) +void __init btrfs_init_compress (void ) {int i;
@@ -744,7 +743,6 @@ int __init btrfs_init_compress(void)atomic_set (&comp_alloc_workspace[i],0 );init_waitqueue_head (&comp_workspace_wait[i]); } -return 0 ; }/*
fs/btrfs/compression.h +1 -1
@@ -19,7 +19,7 @@#ifndef __BTRFS_COMPRESSION_#define __BTRFS_COMPRESSION_ -int btrfs_init_compress (void ); +void btrfs_init_compress (void );void btrfs_exit_compress (void ); int btrfs_compress_pages(int type, struct address_space *mapping,
fs/btrfs/ctree.c +67 -133
477 lines not on this page · raw message
fs/btrfs/ctree.h +23 -22
87 lines not on this page · raw message
fs/btrfs/delayed-inode.c +2 -4
@@ -836,10 +836,8 @@ static int btrfs_batch_insert_items(struct btrfs_trans_handle *trans,btrfs_clear_path_blocking (path,NULL ,0 );/* insert the keys of the items */ - ret =setup_items_for_insert (trans, root, path, keys, data_size, - total_data_size, total_size, nitems); -if (ret) - goto error; +setup_items_for_insert (trans, root, path, keys, data_size, + total_data_size, total_size, nitems);/* insert the dir index items */ slot = path->slots[0 ];
fs/btrfs/delayed-ref.c +8 -19
@@ -420,7 +420,7 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing,* this does all the dirty work in terms of maintaining the correct * overall modification count. */ -static noinline int add_delayed_ref_head(struct btrfs_fs_info *fs_info, +static noinline void add_delayed_ref_head(struct btrfs_fs_info *fs_info, struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_node *ref, u64 bytenr, u64 num_bytes,
@@ -494,13 +494,12 @@ static noinline int add_delayed_ref_head(struct btrfs_fs_info *fs_info, delayed_refs->num_entries++; trans->delayed_ref_updates++; } -return 0 ; }/* * helper to insert a delayed tree ref into the rbtree. */ -static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info, +static noinline void add_delayed_tree_ref(struct btrfs_fs_info *fs_info, struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_node *ref, u64 bytenr, u64 num_bytes, u64 parent,
@@ -554,13 +553,12 @@ static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info, delayed_refs->num_entries++; trans->delayed_ref_updates++; } -return 0 ; }/* * helper to insert a delayed data ref into the rbtree. */ -static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info, +static noinline void add_delayed_data_ref(struct btrfs_fs_info *fs_info, struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_node *ref, u64 bytenr, u64 num_bytes, u64 parent,
@@ -616,7 +614,6 @@ static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info, delayed_refs->num_entries++; trans->delayed_ref_updates++; } -return 0 ; }/*
@@ -634,7 +631,6 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,struct btrfs_delayed_tree_ref *ref;struct btrfs_delayed_ref_head *head_ref;struct btrfs_delayed_ref_root *delayed_refs; -int ret;BUG_ON (extent_op && extent_op->is_data); ref =kmalloc (sizeof (*ref),GFP_NOFS );
@@ -656,14 +652,12 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,* insert both the head node and the new ref without dropping * the spin lock */ - ret =add_delayed_ref_head (fs_info, trans, &head_ref->node, bytenr, +add_delayed_ref_head (fs_info, trans, &head_ref->node, bytenr, num_bytes, action,0 ); -BUG_ON (ret); - ret =add_delayed_tree_ref (fs_info, trans, &ref->node, bytenr, +add_delayed_tree_ref (fs_info, trans, &ref->node, bytenr, num_bytes, parent, ref_root, level, action, for_cow); -BUG_ON (ret);if (!need_ref_seq (for_cow, ref_root) &&waitqueue_active (&delayed_refs->seq_wait))wake_up (&delayed_refs->seq_wait);
@@ -685,7 +679,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,struct btrfs_delayed_data_ref *ref;struct btrfs_delayed_ref_head *head_ref;struct btrfs_delayed_ref_root *delayed_refs; -int ret;BUG_ON (extent_op && !extent_op->is_data); ref =kmalloc (sizeof (*ref),GFP_NOFS );
@@ -707,14 +700,12 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,* insert both the head node and the new ref without dropping * the spin lock */ - ret =add_delayed_ref_head (fs_info, trans, &head_ref->node, bytenr, +add_delayed_ref_head (fs_info, trans, &head_ref->node, bytenr, num_bytes, action,1 ); -BUG_ON (ret); - ret =add_delayed_data_ref (fs_info, trans, &ref->node, bytenr, +add_delayed_data_ref (fs_info, trans, &ref->node, bytenr, num_bytes, parent, ref_root, owner, offset, action, for_cow); -BUG_ON (ret);if (!need_ref_seq (for_cow, ref_root) &&waitqueue_active (&delayed_refs->seq_wait))wake_up (&delayed_refs->seq_wait);
@@ -729,7 +720,6 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, {struct btrfs_delayed_ref_head *head_ref;struct btrfs_delayed_ref_root *delayed_refs; -int ret; head_ref =kmalloc (sizeof (*head_ref),GFP_NOFS );if (!head_ref)
@@ -740,10 +730,9 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, delayed_refs = &trans->transaction->delayed_refs;spin_lock (&delayed_refs->lock); - ret =add_delayed_ref_head (fs_info, trans, &head_ref->node, bytenr, +add_delayed_ref_head (fs_info, trans, &head_ref->node, bytenr, num_bytes,BTRFS_UPDATE_DELAYED_HEAD , extent_op->is_data); -BUG_ON (ret);if (waitqueue_active (&delayed_refs->seq_wait))wake_up (&delayed_refs->seq_wait);
fs/btrfs/dir-item.c +4 -5
@@ -49,9 +49,8 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle di =btrfs_match_dir_item_name (root, path, name, name_len);if (di)return ERR_PTR (-EEXIST ); - ret =btrfs_extend_item (trans, root, path, data_size); - } -if (ret <0 ) +btrfs_extend_item (trans, root, path, data_size); + }else if (ret <0 )return ERR_PTR (ret);WARN_ON (ret >0 ); leaf = path->nodes[0 ];
@@ -383,8 +382,8 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, start =btrfs_item_ptr_offset (leaf, path->slots[0 ]);memmove_extent_buffer (leaf, ptr, ptr + sub_item_len, item_len - (ptr + sub_item_len - start)); - ret =btrfs_truncate_item (trans, root, path, - item_len - sub_item_len,1 ); +btrfs_truncate_item (trans, root, path, + item_len - sub_item_len,1 ); }return ret; }
fs/btrfs/disk-io.c +14 -25
@@ -50,12 +50,12 @@ static void end_workqueue_fn(struct btrfs_work *work);static void free_fs_root (struct btrfs_root *root);static void btrfs_check_super_valid (struct btrfs_fs_info *fs_info,int read_only); -static int btrfs_destroy_ordered_operations (struct btrfs_root *root); -static int btrfs_destroy_ordered_extents (struct btrfs_root *root); +static void btrfs_destroy_ordered_operations (struct btrfs_root *root); +static void btrfs_destroy_ordered_extents (struct btrfs_root *root);static int btrfs_destroy_delayed_refs (struct btrfs_transaction *trans,struct btrfs_root *root); -static int btrfs_destroy_pending_snapshots (struct btrfs_transaction *t); -static int btrfs_destroy_delalloc_inodes (struct btrfs_root *root); +static void btrfs_destroy_pending_snapshots (struct btrfs_transaction *t); +static void btrfs_destroy_delalloc_inodes (struct btrfs_root *root);static int btrfs_destroy_marked_extents (struct btrfs_root *root,struct extent_io_tree *dirty_pages,int mark);
@@ -1139,10 +1139,10 @@ void clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, } } -static int __setup_root (u32 nodesize,u32 leafsize,u32 sectorsize, -u32 stripesize,struct btrfs_root *root, -struct btrfs_fs_info *fs_info, -u64 objectid) +static void __setup_root (u32 nodesize,u32 leafsize,u32 sectorsize, +u32 stripesize,struct btrfs_root *root, +struct btrfs_fs_info *fs_info, +u64 objectid) { root->node =NULL ; root->commit_root =NULL ;
@@ -1194,7 +1194,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, root->defrag_running =0 ; root->root_key.objectid = objectid; root->anon_dev =0 ; -return 0 ; } static int __must_check find_and_setup_root(struct btrfs_root *tree_root,
@@ -2897,7 +2896,7 @@ int write_ctree_super(struct btrfs_trans_handle *trans,return ret; } -int btrfs_free_fs_root (struct btrfs_fs_info *fs_info,struct btrfs_root *root) +void btrfs_free_fs_root (struct btrfs_fs_info *fs_info,struct btrfs_root *root) {spin_lock (&fs_info->fs_roots_radix_lock); radix_tree_delete(&fs_info->fs_roots_radix,
@@ -2910,7 +2909,6 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)__btrfs_remove_free_space_cache (root->free_ino_pinned);__btrfs_remove_free_space_cache (root->free_ino_ctl);free_fs_root (root); -return 0 ; }static void free_fs_root (struct btrfs_root *root)
@@ -2927,7 +2925,7 @@ static void free_fs_root(struct btrfs_root *root)kfree (root); } -static int del_fs_roots (struct btrfs_fs_info *fs_info) +static void del_fs_roots (struct btrfs_fs_info *fs_info) {int ret;struct btrfs_root *gang[8 ];
@@ -2956,7 +2954,6 @@ static int del_fs_roots(struct btrfs_fs_info *fs_info)for (i =0 ; i < ret; i++)btrfs_free_fs_root (fs_info, gang[i]); } -return 0 ; }int btrfs_cleanup_fs_roots (struct btrfs_fs_info *fs_info)
@@ -3299,7 +3296,7 @@ int btrfs_error_commit_super(struct btrfs_root *root)return ret; } -static int btrfs_destroy_ordered_operations (struct btrfs_root *root) +static void btrfs_destroy_ordered_operations (struct btrfs_root *root) {struct btrfs_inode *btrfs_inode;struct list_head splice;
@@ -3321,11 +3318,9 @@ static int btrfs_destroy_ordered_operations(struct btrfs_root *root)spin_unlock (&root->fs_info->ordered_extent_lock);mutex_unlock (&root->fs_info->ordered_operations_mutex); - -return 0 ; } -static int btrfs_destroy_ordered_extents (struct btrfs_root *root) +static void btrfs_destroy_ordered_extents (struct btrfs_root *root) {struct list_head splice;struct btrfs_ordered_extent *ordered;
@@ -3357,8 +3352,6 @@ static int btrfs_destroy_ordered_extents(struct btrfs_root *root) }spin_unlock (&root->fs_info->ordered_extent_lock); - -return 0 ; } static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
@@ -3413,7 +3406,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,return ret; } -static int btrfs_destroy_pending_snapshots (struct btrfs_transaction *t) +static void btrfs_destroy_pending_snapshots (struct btrfs_transaction *t) {struct btrfs_pending_snapshot *snapshot;struct list_head splice;
@@ -3431,11 +3424,9 @@ static int btrfs_destroy_pending_snapshots(struct btrfs_transaction *t)kfree (snapshot); } - -return 0 ; } -static int btrfs_destroy_delalloc_inodes (struct btrfs_root *root) +static void btrfs_destroy_delalloc_inodes (struct btrfs_root *root) {struct btrfs_inode *btrfs_inode;struct list_head splice;
@@ -3455,8 +3446,6 @@ static int btrfs_destroy_delalloc_inodes(struct btrfs_root *root) }spin_unlock (&root->fs_info->delalloc_lock); - -return 0 ; } static int btrfs_destroy_marked_extents(struct btrfs_root *root,
fs/btrfs/disk-io.h +1 -1
@@ -64,7 +64,7 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,int btrfs_cleanup_fs_roots (struct btrfs_fs_info *fs_info);void btrfs_btree_balance_dirty (struct btrfs_root *root,unsigned long nr);void __btrfs_btree_balance_dirty (struct btrfs_root *root,unsigned long nr); -int btrfs_free_fs_root (struct btrfs_fs_info *fs_info,struct btrfs_root *root); +void btrfs_free_fs_root (struct btrfs_fs_info *fs_info,struct btrfs_root *root);void btrfs_mark_buffer_dirty (struct extent_buffer *buf);int btrfs_buffer_uptodate (struct extent_buffer *buf,u64 parent_transid);int btrfs_set_buffer_uptodate (struct extent_buffer *buf);
fs/btrfs/extent-tree.c +27 -33
150 lines not on this page · raw message
fs/btrfs/extent_io.c +14 -21
@@ -142,6 +142,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask)#endif atomic_set (&state->refs,1 );init_waitqueue_head (&state->wq); +trace_alloc_extent_state (state, mask, _RET_IP_);return state; }
@@ -159,6 +160,7 @@ void free_extent_state(struct extent_state *state)list_del (&state->leak_list);spin_unlock_irqrestore (&leak_lock, flags);#endif +trace_free_extent_state (state, _RET_IP_);kmem_cache_free (extent_state_cache, state); } }
@@ -617,8 +619,8 @@ search_again: goto again; } -static int wait_on_state (struct extent_io_tree *tree, -struct extent_state *state) +static void wait_on_state (struct extent_io_tree *tree, +struct extent_state *state) __releases(tree->lock) __acquires(tree->lock) {
@@ -628,7 +630,6 @@ static int wait_on_state(struct extent_io_tree *tree,schedule ();spin_lock (&tree->lock);finish_wait (&state->wq, &wait); -return 0 ; }/*
@@ -636,7 +637,7 @@ static int wait_on_state(struct extent_io_tree *tree,* The range [start, end] is inclusive. * The tree lock is taken by this function */ -int wait_extent_bit (struct extent_io_tree *tree,u64 start,u64 end,int bits) +void wait_extent_bit (struct extent_io_tree *tree,u64 start,u64 end,int bits) {struct extent_state *state;struct rb_node *node;
@@ -673,7 +674,6 @@ again: } out:spin_unlock (&tree->lock); -return 0 ; } static void set_state_bits(struct extent_io_tree *tree,
@@ -1359,9 +1359,9 @@ out:return found; } -static noinline int __unlock_for_delalloc(struct inode *inode, -struct page *locked_page, -u64 start,u64 end) +static noinline void __unlock_for_delalloc(struct inode *inode, +struct page *locked_page, +u64 start,u64 end) {int ret;struct page *pages[16 ];
@@ -1371,7 +1371,7 @@ static noinline int __unlock_for_delalloc(struct inode *inode,int i;if (index == locked_page->index && end_index == index) -return 0 ; +return ;while (nr_pages >0 ) { ret = find_get_pages_contig(inode->i_mapping, index,
@@ -1386,7 +1386,6 @@ static noinline int __unlock_for_delalloc(struct inode *inode, index += ret;cond_resched (); } -return 0 ; } static noinline int lock_delalloc_pages(struct inode *inode,
@@ -1777,39 +1776,34 @@ int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end,* helper function to set a given page up to date if all the * extents in the tree for that page are up to date */ -static int check_page_uptodate (struct extent_io_tree *tree, -struct page *page) +static void check_page_uptodate (struct extent_io_tree *tree,struct page *page) {u64 start = (u64 )page->index <<PAGE_CACHE_SHIFT ;u64 end = start +PAGE_CACHE_SIZE -1 ;if (test_range_bit (tree, start, end,EXTENT_UPTODATE ,1 ,NULL ))SetPageUptodate (page); -return 0 ; }/* * helper function to unlock a page if all the extents in the tree * for that page are unlocked */ -static int check_page_locked (struct extent_io_tree *tree, -struct page *page) +static void check_page_locked (struct extent_io_tree *tree,struct page *page) {u64 start = (u64 )page->index <<PAGE_CACHE_SHIFT ;u64 end = start +PAGE_CACHE_SIZE -1 ;if (!test_range_bit (tree, start, end,EXTENT_LOCKED ,0 ,NULL ))unlock_page (page); -return 0 ; }/* * helper function to end page writeback if all the extents * in the tree for that page are done with writeback */ -static int check_page_writeback (struct extent_io_tree *tree, -struct page *page) +static void check_page_writeback (struct extent_io_tree *tree, +struct page *page) {end_page_writeback (page); -return 0 ; }/*
@@ -3835,7 +3829,7 @@ void free_extent_buffer(struct extent_buffer *eb)WARN_ON (1 ); } -int clear_extent_buffer_dirty (struct extent_io_tree *tree, +void clear_extent_buffer_dirty (struct extent_io_tree *tree,struct extent_buffer *eb) {unsigned long i;
@@ -3867,7 +3861,6 @@ int clear_extent_buffer_dirty(struct extent_io_tree *tree,ClearPageError (page);unlock_page (page); } -return 0 ; } int set_extent_buffer_dirty(struct extent_io_tree *tree,
fs/btrfs/extent_io.h +2 -2
@@ -287,8 +287,8 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, unsigned long src_offset, unsigned long len);void memset_extent_buffer (struct extent_buffer *eb,char c,unsigned long start,unsigned long len); -int wait_extent_bit (struct extent_io_tree *tree,u64 start,u64 end,int bits); -int clear_extent_buffer_dirty (struct extent_io_tree *tree, +void wait_extent_bit (struct extent_io_tree *tree,u64 start,u64 end,int bits); +void clear_extent_buffer_dirty (struct extent_io_tree *tree,struct extent_buffer *eb);int set_extent_buffer_dirty (struct extent_io_tree *tree,struct extent_buffer *eb);
fs/btrfs/file-item.c +10 -15
@@ -483,18 +483,17 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,* This calls btrfs_truncate_item with the correct args based on the * overlap, and fixes up the key as required. */ -static noinline int truncate_one_csum(struct btrfs_trans_handle *trans, -struct btrfs_root *root, -struct btrfs_path *path, -struct btrfs_key *key, -u64 bytenr,u64 len) +static noinline void truncate_one_csum(struct btrfs_trans_handle *trans, +struct btrfs_root *root, +struct btrfs_path *path, +struct btrfs_key *key, +u64 bytenr,u64 len) {struct extent_buffer *leaf;u16 csum_size =btrfs_super_csum_size (root->fs_info->super_copy);u64 csum_end;u64 end_byte = bytenr + len;u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits; -int ret; leaf = path->nodes[0 ]; csum_end =btrfs_item_size_nr (leaf, path->slots[0 ]) / csum_size;
@@ -510,7 +509,7 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans,*/ u32 new_size = (bytenr - key->offset) >> blocksize_bits; new_size *= csum_size; - ret =btrfs_truncate_item (trans, root, path, new_size,1 ); +btrfs_truncate_item (trans, root, path, new_size,1 ); }else if (key->offset >= bytenr && csum_end > end_byte && end_byte > key->offset) {/*
@@ -522,15 +521,13 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans,u32 new_size = (csum_end - end_byte) >> blocksize_bits; new_size *= csum_size; - ret =btrfs_truncate_item (trans, root, path, new_size,0 ); +btrfs_truncate_item (trans, root, path, new_size,0 ); key->offset = end_byte; - ret =btrfs_set_item_key_safe (trans, root, path, key); -BUG_ON (ret); +btrfs_set_item_key_safe (trans, root, path, key); }else {BUG (); } -return 0 ; }/*
@@ -639,9 +636,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, key.offset = end_byte -1 ; }else { - ret =truncate_one_csum (trans, root, path, - &key, bytenr, len); -BUG_ON (ret); +truncate_one_csum (trans, root, path, &key, bytenr, len);if (key.offset < bytenr)break ; }
@@ -772,7 +767,7 @@ again:if (diff != csum_size) goto insert; - ret =btrfs_extend_item (trans, root, path, diff); +btrfs_extend_item (trans, root, path, diff); goto csum; }
fs/btrfs/inode-item.c +2 -2
@@ -128,7 +128,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, item_start =btrfs_item_ptr_offset (leaf, path->slots[0 ]);memmove_extent_buffer (leaf, ptr, ptr + sub_item_len, item_size - (ptr + sub_item_len - item_start)); - ret =btrfs_truncate_item (trans, root, path, +btrfs_truncate_item (trans, root, path, item_size - sub_item_len,1 ); out:btrfs_free_path (path);
@@ -165,7 +165,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, goto out; old_size =btrfs_item_size_nr (path->nodes[0 ], path->slots[0 ]); - ret =btrfs_extend_item (trans, root, path, ins_len); +btrfs_extend_item (trans, root, path, ins_len); ref =btrfs_item_ptr (path->nodes[0 ], path->slots[0 ], struct btrfs_inode_ref); ref = (struct btrfs_inode_ref *)((unsigned long )ref + old_size);
fs/btrfs/inode.c +3 -4
@@ -3164,8 +3164,8 @@ search_again: } size =btrfs_file_extent_calc_inline_size (size); - ret =btrfs_truncate_item (trans, root, path, - size,1 ); +btrfs_truncate_item (trans, root, path, + size,1 ); }else if (root->ref_cows) {inode_sub_bytes (inode, item_end +1 - found_key.offset);
@@ -3782,7 +3782,7 @@ static void inode_tree_del(struct inode *inode) } } -int btrfs_invalidate_inodes (struct btrfs_root *root) +void btrfs_invalidate_inodes (struct btrfs_root *root) {struct rb_node *node;struct rb_node *prev;
@@ -3842,7 +3842,6 @@ again: node =rb_next (node); }spin_unlock (&root->inode_lock); -return 0 ; }static int btrfs_init_locked_inode (struct inode *inode,void *p)
fs/btrfs/locking.c +2 -4
@@ -208,7 +208,7 @@ void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb)* take a spinning write lock. This will wait for both * blocking readers or writers */ -int btrfs_tree_lock (struct extent_buffer *eb) +void btrfs_tree_lock (struct extent_buffer *eb) { again:wait_event (eb->read_lock_wq,atomic_read (&eb->blocking_readers) ==0 );
@@ -230,13 +230,12 @@ again:atomic_inc (&eb->spinning_writers);atomic_inc (&eb->write_locks); eb->lock_owner = current->pid; -return 0 ; }/* * drop a spinning or a blocking write lock. */ -int btrfs_tree_unlock (struct extent_buffer *eb) +void btrfs_tree_unlock (struct extent_buffer *eb) {int blockers =atomic_read (&eb->blocking_writers);
@@ -255,7 +254,6 @@ int btrfs_tree_unlock(struct extent_buffer *eb)atomic_dec (&eb->spinning_writers);write_unlock (&eb->lock); } -return 0 ; }void btrfs_assert_tree_locked (struct extent_buffer *eb)
fs/btrfs/locking.h +2 -2
@@ -24,8 +24,8 @@#define BTRFS_WRITE_LOCK_BLOCKING 3#define BTRFS_READ_LOCK_BLOCKING 4 -int btrfs_tree_lock (struct extent_buffer *eb); -int btrfs_tree_unlock (struct extent_buffer *eb); +void btrfs_tree_lock (struct extent_buffer *eb); +void btrfs_tree_unlock (struct extent_buffer *eb);int btrfs_try_spin_lock (struct extent_buffer *eb);void btrfs_tree_read_lock (struct extent_buffer *eb);
fs/btrfs/ordered-data.c +17 -31
155 lines not on this page · raw message
fs/btrfs/ordered-data.h +12 -12
@@ -138,8 +138,8 @@ btrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t) t->last =NULL ; } -int btrfs_put_ordered_extent (struct btrfs_ordered_extent *entry); -int btrfs_remove_ordered_extent (struct inode *inode, +void btrfs_put_ordered_extent (struct btrfs_ordered_extent *entry); +void btrfs_remove_ordered_extent (struct inode *inode,struct btrfs_ordered_extent *entry); int btrfs_dec_test_ordered_pending(struct inode *inode, struct btrfs_ordered_extent **cached,
@@ -154,14 +154,14 @@ int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset,int btrfs_add_ordered_extent_compress (struct inode *inode,u64 file_offset,u64 start,u64 len,u64 disk_len,int type,int compress_type); -int btrfs_add_ordered_sum (struct inode *inode, -struct btrfs_ordered_extent *entry, -struct btrfs_ordered_sum *sum); +void btrfs_add_ordered_sum (struct inode *inode, +struct btrfs_ordered_extent *entry, +struct btrfs_ordered_sum *sum);struct btrfs_ordered_extent *btrfs_lookup_ordered_extent (struct inode *inode,u64 file_offset);void btrfs_start_ordered_extent (struct inode *inode,struct btrfs_ordered_extent *entry,int wait); -int btrfs_wait_ordered_range (struct inode *inode,u64 start,u64 len); +void btrfs_wait_ordered_range (struct inode *inode,u64 start,u64 len);struct btrfs_ordered_extent *btrfs_lookup_first_ordered_extent (struct inode * inode,u64 file_offset); struct btrfs_ordered_extent *btrfs_lookup_ordered_range(struct inode *inode,
@@ -170,10 +170,10 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_range(struct inode *inode,int btrfs_ordered_update_i_size (struct inode *inode,u64 offset,struct btrfs_ordered_extent *ordered);int btrfs_find_ordered_sum (struct inode *inode,u64 offset,u64 disk_bytenr,u32 *sum); -int btrfs_run_ordered_operations (struct btrfs_root *root,int wait); -int btrfs_add_ordered_operation (struct btrfs_trans_handle *trans, -struct btrfs_root *root, -struct inode *inode); -int btrfs_wait_ordered_extents (struct btrfs_root *root, -int nocow_only,int delay_iput); +void btrfs_run_ordered_operations (struct btrfs_root *root,int wait); +void btrfs_add_ordered_operation (struct btrfs_trans_handle *trans, +struct btrfs_root *root, +struct inode *inode); +void btrfs_wait_ordered_extents (struct btrfs_root *root, +int nocow_only,int delay_iput);#endif
fs/btrfs/scrub.c +10 -26
@@ -948,12 +948,12 @@ static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer)return fail; } -static int scrub_submit (struct scrub_dev *sdev) +static void scrub_submit (struct scrub_dev *sdev) {struct scrub_bio *sbio;if (sdev->curr ==-1 ) -return 0 ; +return ; sbio = sdev->bios[sdev->curr]; sbio->err =0 ;
@@ -961,8 +961,6 @@ static int scrub_submit(struct scrub_dev *sdev)atomic_inc (&sdev->in_flight);btrfsic_submit_bio (READ , sbio->bio); - -return 0 ; } static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len,
@@ -1008,9 +1006,7 @@ again: sbio->bio = bio; }else if (sbio->physical + sbio->count *PAGE_SIZE != physical || sbio->logical + sbio->count *PAGE_SIZE != logical) { - ret =scrub_submit (sdev); -if (ret) -return ret; +scrub_submit (sdev); goto again; } sbio->spag[sbio->count].flags = flags;
@@ -1025,9 +1021,7 @@ again: ret =bio_add_page (sbio->bio, page,PAGE_SIZE ,0 );if (!ret) {__free_page (page); - ret =scrub_submit (sdev); -if (ret) -return ret; +scrub_submit (sdev); goto again; }
@@ -1036,13 +1030,8 @@ again:memcpy (sbio->spag[sbio->count].csum, csum, sdev->csum_size); } ++sbio->count; -if (sbio->count ==SCRUB_PAGES_PER_BIO || force) { -int ret; - - ret =scrub_submit (sdev); -if (ret) -return ret; - } +if (sbio->count ==SCRUB_PAGES_PER_BIO || force) +scrub_submit (sdev);return 0 ; }
@@ -1656,7 +1645,7 @@ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end,return ret; } -int btrfs_scrub_pause (struct btrfs_root *root) +void btrfs_scrub_pause (struct btrfs_root *root) {struct btrfs_fs_info *fs_info = root->fs_info;
@@ -1671,29 +1660,24 @@ int btrfs_scrub_pause(struct btrfs_root *root)mutex_lock (&fs_info->scrub_lock); }mutex_unlock (&fs_info->scrub_lock); - -return 0 ; } -int btrfs_scrub_continue (struct btrfs_root *root) +void btrfs_scrub_continue (struct btrfs_root *root) {struct btrfs_fs_info *fs_info = root->fs_info;atomic_dec (&fs_info->scrub_pause_req);wake_up (&fs_info->scrub_pause_wait); -return 0 ; } -int btrfs_scrub_pause_super (struct btrfs_root *root) +void btrfs_scrub_pause_super (struct btrfs_root *root) {down_write (&root->fs_info->scrub_super_lock); -return 0 ; } -int btrfs_scrub_continue_super (struct btrfs_root *root) +void btrfs_scrub_continue_super (struct btrfs_root *root) {up_write (&root->fs_info->scrub_super_lock); -return 0 ; }int btrfs_scrub_cancel (struct btrfs_root *root)
fs/btrfs/super.c +1 -4
@@ -1408,9 +1408,7 @@ static int __init init_btrfs_fs(void)if (err)return err; - err =btrfs_init_compress (); -if (err) - goto free_sysfs; +btrfs_init_compress (); err =btrfs_init_cachep ();if (err)
@@ -1451,7 +1449,6 @@ free_cachep:btrfs_destroy_cachep (); free_compress:btrfs_exit_compress (); -free_sysfs:btrfs_exit_sysfs ();return err; }
fs/btrfs/transaction.c +1 -2
@@ -1214,8 +1214,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,if (flush_on_commit || snap_pending) {btrfs_start_delalloc_inodes (root,1 ); - ret =btrfs_wait_ordered_extents (root,0 ,1 ); -BUG_ON (ret); +btrfs_wait_ordered_extents (root,0 ,1 ); } ret =btrfs_run_delayed_items (trans, root);
fs/btrfs/tree-log.c +7 -10
@@ -212,14 +212,13 @@ int btrfs_pin_log_trans(struct btrfs_root *root)* indicate we're done making changes to the log tree * and wake up anyone waiting to do a sync */ -int btrfs_end_log_trans (struct btrfs_root *root) +void btrfs_end_log_trans (struct btrfs_root *root) {if (atomic_dec_and_test (&root->log_writers)) {smp_mb ();if (waitqueue_active (&root->log_writer_wait))wake_up (&root->log_writer_wait); } -return 0 ; }
@@ -378,12 +377,11 @@ insert:u32 found_size; found_size =btrfs_item_size_nr (path->nodes[0 ], path->slots[0 ]); -if (found_size > item_size) { +if (found_size > item_size)btrfs_truncate_item (trans, root, path, item_size,1 ); - }else if (found_size < item_size) { - ret =btrfs_extend_item (trans, root, path, - item_size - found_size); - } +else if (found_size < item_size) +btrfs_extend_item (trans, root, path, + item_size - found_size); }else if (ret) {return ret; }
@@ -1963,8 +1961,8 @@ static int wait_log_commit(struct btrfs_trans_handle *trans,return 0 ; } -static int wait_for_writer (struct btrfs_trans_handle *trans, -struct btrfs_root *root) +static void wait_for_writer (struct btrfs_trans_handle *trans, +struct btrfs_root *root) {DEFINE_WAIT (wait); while (root->fs_info->last_trans_log_full_commit !=
@@ -1978,7 +1976,6 @@ static int wait_for_writer(struct btrfs_trans_handle *trans,mutex_lock (&root->log_mutex);finish_wait (&root->log_writer_wait, &wait); } -return 0 ; }/*
fs/btrfs/tree-log.h +1 -1
@@ -38,7 +38,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans,struct btrfs_root *root, const char *name, int name_len, struct inode *inode, u64 dirid); -int btrfs_end_log_trans (struct btrfs_root *root); +void btrfs_end_log_trans (struct btrfs_root *root);int btrfs_pin_log_trans (struct btrfs_root *root); int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode,
fs/btrfs/volumes.c +6 -12
@@ -67,7 +67,7 @@ static void free_fs_devices(struct btrfs_fs_devices *fs_devices)kfree (fs_devices); } -int btrfs_cleanup_fs_uuids (void ) +void btrfs_cleanup_fs_uuids (void ) {struct btrfs_fs_devices *fs_devices;
@@ -77,7 +77,6 @@ int btrfs_cleanup_fs_uuids(void)list_del (&fs_devices->list);free_fs_devices (fs_devices); } -return 0 ; } static noinline struct btrfs_device *__find_device(struct list_head *head,
@@ -130,7 +129,7 @@ static void requeue_list(struct btrfs_pending_bios *pending_bios,* the list if the block device is congested. This way, multiple devices * can make progress from a single worker thread. */ -static noinline int run_scheduled_bios(struct btrfs_device *device) +static noinline void run_scheduled_bios(struct btrfs_device *device) {struct bio *pending;struct backing_dev_info *bdi;
@@ -316,7 +315,6 @@ loop_lock: done:blk_finish_plug (&plug); -return 0 ; }static void pending_bios_fn (struct btrfs_work *work)
@@ -455,7 +453,7 @@ error:return ERR_PTR (-ENOMEM ); } -int btrfs_close_extra_devices (struct btrfs_fs_devices *fs_devices) +void btrfs_close_extra_devices (struct btrfs_fs_devices *fs_devices) {struct btrfs_device *device, *next;
@@ -503,7 +501,6 @@ again: fs_devices->latest_trans = latest_transid;mutex_unlock (&uuid_mutex); -return 0 ; }static void __free_device (struct work_struct *work)
@@ -3967,7 +3964,7 @@ struct async_sched {* This will add one bio to the pending list for a device and make sure * the work struct is scheduled. */ -static noinline int schedule_bio(struct btrfs_root *root, +static noinline void schedule_bio(struct btrfs_root *root,struct btrfs_device *device,int rw,struct bio *bio) {
@@ -3979,7 +3976,7 @@ static noinline int schedule_bio(struct btrfs_root *root,bio_get (bio);btrfsic_submit_bio (rw, bio);bio_put (bio); -return 0 ; +return ; }/*
@@ -4013,7 +4009,6 @@ static noinline int schedule_bio(struct btrfs_root *root,if (should_queue)btrfs_queue_worker (&root->fs_info->submit_workers, &device->work); -return 0 ; } int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
@@ -4215,7 +4210,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,return 0 ; } -static int fill_device_from_item (struct extent_buffer *leaf, +static void fill_device_from_item (struct extent_buffer *leaf,struct btrfs_dev_item *dev_item,struct btrfs_device *device) {
@@ -4232,8 +4227,6 @@ static int fill_device_from_item(struct extent_buffer *leaf, ptr = (unsigned long )btrfs_device_uuid (dev_item);read_extent_buffer (leaf, device->uuid, ptr,BTRFS_UUID_SIZE ); - -return 0 ; }static int open_seed_devices (struct btrfs_root *root,u8 *fsid)
fs/btrfs/volumes.h +2 -2
@@ -260,12 +260,12 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,int btrfs_scan_one_device (const char *path,fmode_t flags,void *holder,struct btrfs_fs_devices **fs_devices_ret);int btrfs_close_devices (struct btrfs_fs_devices *fs_devices); -int btrfs_close_extra_devices (struct btrfs_fs_devices *fs_devices); +void btrfs_close_extra_devices (struct btrfs_fs_devices *fs_devices);int btrfs_add_device (struct btrfs_trans_handle *trans,struct btrfs_root *root,struct btrfs_device *device);int btrfs_rm_device (struct btrfs_root *root,char *device_path); -int btrfs_cleanup_fs_uuids (void ); +void btrfs_cleanup_fs_uuids (void );int btrfs_num_copies (struct btrfs_mapping_tree *map_tree,u64 logical,u64 len);int btrfs_grow_device (struct btrfs_trans_handle *trans,struct btrfs_device *device,u64 new_size);
include/trace/events/btrfs.h +44 -0
56 lines not on this page · raw message
Signature · 1 line
1.7.9
PATCH 16/35 btrfs: drop gfp_t from lock_extent
In reply to Jeff Mahoney lock_extent and unlock_extent are always called with GFP_NOFS, drop the argument and use GFP_NOFS consistently.
--- fs/btrfs/compression.c | 6 +++--- fs/btrfs/disk-io.c | 2 +- fs/btrfs/extent_io.c | 41 +++++++++++++++++++---------------------- fs/btrfs/extent_io.h | 9 ++++----- fs/btrfs/file.c | 7 +++---- fs/btrfs/free-space-cache.c | 2 +- fs/btrfs/inode.c | 33 ++++++++++++++------------------- fs/btrfs/ioctl.c | 17 ++++++++--------- fs/btrfs/relocation.c | 22 ++++++++++------------ 9 files changed, 63 insertions(+), 76 deletions(-)
fs/btrfs/compression.c +3 -3
@@ -496,7 +496,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,* sure they map to this compressed extent on disk. */ set_page_extent_mapped (page); -lock_extent (tree, last_offset, end,GFP_NOFS ); +lock_extent (tree, last_offset, end);read_lock (&em_tree->lock); em =lookup_extent_mapping (em_tree, last_offset,PAGE_CACHE_SIZE );
@@ -506,7 +506,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, (last_offset + PAGE_CACHE_SIZE > extent_map_end(em)) || (em->block_start >> 9) != cb->orig_bio->bi_sector) {free_extent_map (em); -unlock_extent (tree, last_offset, end,GFP_NOFS ); +unlock_extent (tree, last_offset, end);unlock_page (page);page_cache_release (page);break ;
@@ -534,7 +534,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, nr_pages++;page_cache_release (page); }else { -unlock_extent (tree, last_offset, end,GFP_NOFS ); +unlock_extent (tree, last_offset, end);unlock_page (page);page_cache_release (page);break ;
fs/btrfs/disk-io.c +1 -1
@@ -332,7 +332,7 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,return 0 ;lock_extent_bits (io_tree, eb->start, eb->start + eb->len -1 , -0 , &cached_state,GFP_NOFS ); +0 , &cached_state);if (extent_buffer_uptodate (io_tree, eb, cached_state) &&btrfs_header_generation (eb) == parent_transid) { ret =0 ;
fs/btrfs/extent_io.c +19 -22
125 lines not on this page · raw message
fs/btrfs/extent_io.h +4 -5
@@ -182,14 +182,13 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page);int try_release_extent_state (struct extent_map_tree *map,struct extent_io_tree *tree,struct page *page,gfp_t mask); -int lock_extent (struct extent_io_tree *tree,u64 start,u64 end,gfp_t mask); +int lock_extent (struct extent_io_tree *tree,u64 start,u64 end);int lock_extent_bits (struct extent_io_tree *tree,u64 start,u64 end, -int bits,struct extent_state **cached,gfp_t mask); -int unlock_extent (struct extent_io_tree *tree,u64 start,u64 end,gfp_t mask); +int bits,struct extent_state **cached); +int unlock_extent (struct extent_io_tree *tree,u64 start,u64 end);int unlock_extent_cached (struct extent_io_tree *tree,u64 start,u64 end,struct extent_state **cached,gfp_t mask); -int try_lock_extent (struct extent_io_tree *tree,u64 start,u64 end, -gfp_t mask); +int try_lock_extent (struct extent_io_tree *tree,u64 start,u64 end);int extent_read_full_page (struct extent_io_tree *tree,struct page *page,get_extent_t *get_extent,int mirror_num);int __init extent_io_init (void );
fs/btrfs/file.c +3 -4
@@ -1105,8 +1105,7 @@ again:if (start_pos < inode->i_size) {struct btrfs_ordered_extent *ordered;lock_extent_bits (&BTRFS_I (inode)->io_tree, - start_pos, last_pos -1 ,0 , &cached_state, -GFP_NOFS ); + start_pos, last_pos -1 ,0 , &cached_state); ordered =btrfs_lookup_first_ordered_extent (inode, last_pos -1 ); if (ordered &&
@@ -1638,7 +1637,7 @@ static long btrfs_fallocate(struct file *file, int mode,* transaction */ lock_extent_bits (&BTRFS_I (inode)->io_tree, alloc_start, - locked_end,0 , &cached_state,GFP_NOFS ); + locked_end,0 , &cached_state); ordered =btrfs_lookup_first_ordered_extent (inode, alloc_end -1 ); if (ordered &&
@@ -1737,7 +1736,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)return -ENXIO ;lock_extent_bits (&BTRFS_I (inode)->io_tree, lockstart, lockend,0 , - &cached_state,GFP_NOFS ); + &cached_state);/* * Delalloc is such a pain. If we have a hole and we have pending
fs/btrfs/free-space-cache.c +1 -1
@@ -869,7 +869,7 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,io_ctl_prepare_pages (&io_ctl, inode,0 );lock_extent_bits (&BTRFS_I (inode)->io_tree,0 ,i_size_read (inode) -1 , -0 , &cached_state,GFP_NOFS ); +0 , &cached_state); node =rb_first (&ctl->free_space_offset);if (!node && cluster) {
fs/btrfs/inode.c +14 -19
@@ -597,7 +597,7 @@ retry:lock_extent (io_tree, async_extent->start, async_extent->start + - async_extent->ram_size -1 ,GFP_NOFS ); + async_extent->ram_size -1 );/* allocate blocks */ ret = cow_file_range(inode, async_cow->locked_page,
@@ -625,8 +625,7 @@ retry: }lock_extent (io_tree, async_extent->start, - async_extent->start + async_extent->ram_size -1 , -GFP_NOFS ); + async_extent->start + async_extent->ram_size -1 ); trans =btrfs_join_transaction (root);BUG_ON (IS_ERR (trans));
@@ -649,7 +648,7 @@ retry: async_extent->pages =NULL ;unlock_extent (io_tree, async_extent->start, async_extent->start + - async_extent->ram_size -1 ,GFP_NOFS ); + async_extent->ram_size -1 ); goto retry; }
@@ -1574,7 +1573,7 @@ again: page_end =page_offset (page) +PAGE_CACHE_SIZE -1 ;lock_extent_bits (&BTRFS_I (inode)->io_tree, page_start, page_end,0 , - &cached_state,GFP_NOFS ); + &cached_state);/* already ordered? We're done */ if (PagePrivate2 (page))
@@ -1765,7 +1764,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)lock_extent_bits (io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len -1 , -0 , &cached_state,GFP_NOFS ); +0 , &cached_state);if (nolock) trans =btrfs_join_transaction_nolock (root);
@@ -3285,8 +3284,7 @@ again: }wait_on_page_writeback (page); -lock_extent_bits (io_tree, page_start, page_end,0 , &cached_state, -GFP_NOFS ); +lock_extent_bits (io_tree, page_start, page_end,0 , &cached_state);set_page_extent_mapped (page); ordered =btrfs_lookup_ordered_extent (inode, page_start);
@@ -3362,7 +3360,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)btrfs_wait_ordered_range (inode, hole_start, block_end - hole_start);lock_extent_bits (io_tree, hole_start, block_end -1 ,0 , - &cached_state,GFP_NOFS ); + &cached_state); ordered =btrfs_lookup_ordered_extent (inode, hole_start);if (!ordered)break ;
@@ -5604,7 +5602,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,free_extent_map (em);/* DIO will do one hole at a time, so just unlock a sector */ unlock_extent (&BTRFS_I (inode)->io_tree, start, - start + root->sectorsize -1 ,GFP_NOFS ); + start + root->sectorsize -1 );return 0 ; }
@@ -5745,7 +5743,7 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) }while (bvec <= bvec_end);unlock_extent (&BTRFS_I (inode)->io_tree, dip->logical_offset, - dip->logical_offset + dip->bytes -1 ,GFP_NOFS ); + dip->logical_offset + dip->bytes -1 ); bio->bi_private = dip->private;kfree (dip->csums);
@@ -5796,7 +5794,7 @@ again:lock_extent_bits (&BTRFS_I (inode)->io_tree, ordered->file_offset, ordered->file_offset + ordered->len -1 ,0 , - &cached_state,GFP_NOFS ); + &cached_state);if (test_bit (BTRFS_ORDERED_PREALLOC , &ordered->flags)) { ret = btrfs_mark_extent_written(trans, inode,
@@ -6211,7 +6209,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,while (1 ) {lock_extent_bits (&BTRFS_I (inode)->io_tree, lockstart, lockend, -0 , &cached_state,GFP_NOFS ); +0 , &cached_state);/* * We're concerned with the entire range that we're going to be * doing DIO to, so we need to make sure theres no ordered
@@ -6365,8 +6363,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)btrfs_releasepage (page,GFP_NOFS );return ; } -lock_extent_bits (tree, page_start, page_end,0 , &cached_state, -GFP_NOFS ); +lock_extent_bits (tree, page_start, page_end,0 , &cached_state); ordered =btrfs_lookup_ordered_extent (page->mapping->host,page_offset (page));if (ordered) {
@@ -6388,8 +6385,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) }btrfs_put_ordered_extent (ordered); cached_state =NULL ; -lock_extent_bits (tree, page_start, page_end,0 , &cached_state, -GFP_NOFS ); +lock_extent_bits (tree, page_start, page_end,0 , &cached_state); } clear_extent_bit(tree, page_start, page_end, EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
@@ -6464,8 +6460,7 @@ again: }wait_on_page_writeback (page); -lock_extent_bits (io_tree, page_start, page_end,0 , &cached_state, -GFP_NOFS ); +lock_extent_bits (io_tree, page_start, page_end,0 , &cached_state);set_page_extent_mapped (page);/*
fs/btrfs/ioctl.c +8 -9
@@ -797,9 +797,9 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,if (!em) {/* get the big lock and read metadata off disk */ -lock_extent (io_tree, start, start + len -1 ,GFP_NOFS ); +lock_extent (io_tree, start, start + len -1 ); em =btrfs_get_extent (inode,NULL ,0 , start, len,0 ); -unlock_extent (io_tree, start, start + len -1 ,GFP_NOFS ); +unlock_extent (io_tree, start, start + len -1 );if (IS_ERR (em))return 0 ;
@@ -887,10 +887,10 @@ again: page_start =page_offset (page); page_end = page_start +PAGE_CACHE_SIZE -1 ;while (1 ) { -lock_extent (tree, page_start, page_end,GFP_NOFS ); +lock_extent (tree, page_start, page_end); ordered =btrfs_lookup_ordered_extent (inode, page_start); -unlock_extent (tree, page_start, page_end,GFP_NOFS ); +unlock_extent (tree, page_start, page_end);if (!ordered)break ;
@@ -946,8 +946,7 @@ again: page_end =page_offset (pages[i_done -1 ]) +PAGE_CACHE_SIZE ;lock_extent_bits (&BTRFS_I (inode)->io_tree, - page_start, page_end -1 ,0 , &cached_state, -GFP_NOFS ); + page_start, page_end -1 ,0 , &cached_state); clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
@@ -2326,13 +2325,13 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,another, and lock file content */ while (1 ) {struct btrfs_ordered_extent *ordered; -lock_extent (&BTRFS_I (src)->io_tree, off, off+len,GFP_NOFS ); +lock_extent (&BTRFS_I (src)->io_tree, off, off+len); ordered =btrfs_lookup_first_ordered_extent (src, off+len);if (!ordered && !test_range_bit (&BTRFS_I (src)->io_tree, off, off+len,EXTENT_DELALLOC ,0 ,NULL ))break ; -unlock_extent (&BTRFS_I (src)->io_tree, off, off+len,GFP_NOFS ); +unlock_extent (&BTRFS_I (src)->io_tree, off, off+len);if (ordered)btrfs_put_ordered_extent (ordered);btrfs_wait_ordered_range (src, off, len);
@@ -2551,7 +2550,7 @@ next: ret =0 ; out:btrfs_release_path (path); -unlock_extent (&BTRFS_I (src)->io_tree, off, off+len,GFP_NOFS ); +unlock_extent (&BTRFS_I (src)->io_tree, off, off+len); out_unlock:mutex_unlock (&src->i_mutex);mutex_unlock (&inode->i_mutex);
fs/btrfs/relocation.c +10 -12
@@ -1604,15 +1604,14 @@ int replace_file_extents(struct btrfs_trans_handle *trans,WARN_ON (!IS_ALIGNED (end, root->sectorsize)); end--; ret =try_lock_extent (&BTRFS_I (inode)->io_tree, - key.offset, end, -GFP_NOFS ); + key.offset, end);if (!ret)continue ;btrfs_drop_extent_cache (inode, key.offset, end,1 );unlock_extent (&BTRFS_I (inode)->io_tree, - key.offset, end,GFP_NOFS ); + key.offset, end); } }
@@ -1983,9 +1982,9 @@ static int invalidate_extent_cache(struct btrfs_root *root, }/* the lock_extent waits for readpage to complete */ -lock_extent (&BTRFS_I (inode)->io_tree, start, end,GFP_NOFS ); +lock_extent (&BTRFS_I (inode)->io_tree, start, end);btrfs_drop_extent_cache (inode, start, end,1 ); -unlock_extent (&BTRFS_I (inode)->io_tree, start, end,GFP_NOFS ); +unlock_extent (&BTRFS_I (inode)->io_tree, start, end); }return 0 ; }
@@ -2889,12 +2888,12 @@ int prealloc_file_extent_cluster(struct inode *inode,else end = cluster->end - offset; -lock_extent (&BTRFS_I (inode)->io_tree, start, end,GFP_NOFS ); +lock_extent (&BTRFS_I (inode)->io_tree, start, end); num_bytes = end +1 - start; ret =btrfs_prealloc_file_range (inode,0 , start, num_bytes, num_bytes, end +1 , &alloc_hint); -unlock_extent (&BTRFS_I (inode)->io_tree, start, end,GFP_NOFS ); +unlock_extent (&BTRFS_I (inode)->io_tree, start, end);if (ret)break ; nr++;
@@ -2926,7 +2925,7 @@ int setup_extent_mapping(struct inode *inode, u64 start, u64 end, em->bdev = root->fs_info->fs_devices->latest_bdev;set_bit (EXTENT_FLAG_PINNED , &em->flags); -lock_extent (&BTRFS_I (inode)->io_tree, start, end,GFP_NOFS ); +lock_extent (&BTRFS_I (inode)->io_tree, start, end);while (1 ) {write_lock (&em_tree->lock); ret =add_extent_mapping (em_tree, em);
@@ -2937,7 +2936,7 @@ int setup_extent_mapping(struct inode *inode, u64 start, u64 end, }btrfs_drop_extent_cache (inode, start, end,0 ); } -unlock_extent (&BTRFS_I (inode)->io_tree, start, end,GFP_NOFS ); +unlock_extent (&BTRFS_I (inode)->io_tree, start, end);return ret; }
@@ -3017,8 +3016,7 @@ static int relocate_file_extent_cluster(struct inode *inode, page_start = (u64 )page->index <<PAGE_CACHE_SHIFT ; page_end = page_start +PAGE_CACHE_SIZE -1 ; -lock_extent (&BTRFS_I (inode)->io_tree, - page_start, page_end,GFP_NOFS ); +lock_extent (&BTRFS_I (inode)->io_tree, page_start, page_end);set_page_extent_mapped (page);
@@ -3034,7 +3032,7 @@ static int relocate_file_extent_cluster(struct inode *inode,set_page_dirty (page);unlock_extent (&BTRFS_I (inode)->io_tree, - page_start, page_end,GFP_NOFS ); + page_start, page_end);unlock_page (page);page_cache_release (page);
Signature · 1 line
1.7.9
PATCH 17/35 btrfs: split extent_state ops
In reply to Jeff Mahoney set_extent_bit can do exclusive locking but only when called by lock_extent*,
Drop the exclusive bits argument except when called by lock_extent.
--- fs/btrfs/extent_io.c | 36 +++++++++++++++++++++++------------- fs/btrfs/extent_io.h | 2 +- fs/btrfs/inode.c | 2 +- 3 files changed, 25 insertions(+), 15 deletions(-)
fs/btrfs/extent_io.c +23 -13
@@ -721,9 +721,10 @@ static void uncache_state(struct extent_state **cached_ptr)* [start, end] is inclusive This takes the tree lock. */ -int set_extent_bit (struct extent_io_tree *tree,u64 start,u64 end, -int bits,int exclusive_bits,u64 *failed_start, -struct extent_state **cached_state,gfp_t mask) +static int __must_check +__set_extent_bit (struct extent_io_tree *tree,u64 start,u64 end, +int bits,int exclusive_bits,u64 *failed_start, +struct extent_state **cached_state,gfp_t mask) {struct extent_state *state;struct extent_state *prealloc =NULL ;
@@ -917,6 +918,15 @@ search_again: goto again; } +int set_extent_bit (struct extent_io_tree *tree,u64 start,u64 end,int bits, +u64 *failed_start,struct extent_state **cached_state, +gfp_t mask) +{ +return __set_extent_bit (tree, start, end, bits,0 , failed_start, + cached_state, mask); +} + +/** * convert_extent - convert all bits in a given range from one bit to another * @tree: the io tree to search
@@ -1111,14 +1121,14 @@ search_again:int set_extent_dirty (struct extent_io_tree *tree,u64 start,u64 end,gfp_t mask) { -return set_extent_bit (tree, start, end,EXTENT_DIRTY ,0 ,NULL , +return set_extent_bit (tree, start, end,EXTENT_DIRTY ,NULL ,NULL , mask); }int set_extent_bits (struct extent_io_tree *tree,u64 start,u64 end,int bits,gfp_t mask) { -return set_extent_bit (tree, start, end, bits,0 ,NULL , +return set_extent_bit (tree, start, end, bits,NULL ,NULL , mask); }
@@ -1133,7 +1143,7 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, {return set_extent_bit (tree, start, end,EXTENT_DELALLOC |EXTENT_UPTODATE , -0 ,NULL , cached_state, mask); +NULL , cached_state, mask); } int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
@@ -1147,7 +1157,7 @@ int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,int set_extent_new (struct extent_io_tree *tree,u64 start,u64 end,gfp_t mask) { -return set_extent_bit (tree, start, end,EXTENT_NEW ,0 ,NULL , +return set_extent_bit (tree, start, end,EXTENT_NEW ,NULL ,NULL , mask); }
@@ -1155,7 +1165,7 @@ int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state **cached_state, gfp_t mask) {return set_extent_bit (tree, start, end,EXTENT_UPTODATE ,0 , -NULL , cached_state, mask); + cached_state, mask); } static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start,
@@ -1176,9 +1186,9 @@ int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,int err;u64 failed_start;while (1 ) { - err =set_extent_bit (tree, start, end,EXTENT_LOCKED | bits, -EXTENT_LOCKED , &failed_start, - cached_state,GFP_NOFS ); + err =__set_extent_bit (tree, start, end,EXTENT_LOCKED | bits, +EXTENT_LOCKED , &failed_start, + cached_state,GFP_NOFS );if (err == -EEXIST ) {wait_extent_bit (tree, failed_start, end,EXTENT_LOCKED ); start = failed_start;
@@ -1199,8 +1209,8 @@ int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end)int err;u64 failed_start; - err =set_extent_bit (tree, start, end,EXTENT_LOCKED ,EXTENT_LOCKED , - &failed_start,NULL ,GFP_NOFS ); + err =__set_extent_bit (tree, start, end,EXTENT_LOCKED ,EXTENT_LOCKED , + &failed_start,NULL ,GFP_NOFS );if (err == -EEXIST ) {if (failed_start > start) clear_extent_bit(tree, start, failed_start - 1,
fs/btrfs/extent_io.h +1 -1
@@ -209,7 +209,7 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,int set_extent_bits (struct extent_io_tree *tree,u64 start,u64 end,int bits,gfp_t mask);int set_extent_bit (struct extent_io_tree *tree,u64 start,u64 end, -int bits,int exclusive_bits,u64 *failed_start, +int bits,u64 *failed_start,struct extent_state **cached_state,gfp_t mask);int set_extent_uptodate (struct extent_io_tree *tree,u64 start,u64 end,struct extent_state **cached_state,gfp_t mask);
fs/btrfs/inode.c +1 -1
@@ -6233,7 +6233,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,if (writing) { write_bits =EXTENT_DELALLOC |EXTENT_DO_ACCOUNTING ; ret =set_extent_bit (&BTRFS_I (inode)->io_tree, lockstart, lockend, -EXTENT_DELALLOC ,0 ,NULL , &cached_state, +EXTENT_DELALLOC ,NULL , &cached_state,GFP_NOFS );if (ret) { clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
Signature · 1 line
1.7.9
Re: [patch 17/35] btrfs: split extent_state ops
Quoted 4 lines · Jeff Mahoney
set_extent_bitcan do exclusive locking but only when called by lock_extent*,Drop the exclusive bits argument except when called by
lock_extent.
Hi Jeff,
I have to say this is not a good cleanup, any benefits?
thanks,
liubo
Quoted 135 lines
Signed-off-by Jeff Mahoney <[email protected]>--- fs/btrfs/extent_io.c | 36 +++++++++++++++++++++++------------- fs/btrfs/extent_io.h | 2 +- fs/btrfs/inode.c | 2 +- 3 files changed, 25 insertions(+), 15 deletions(-)fs/btrfs/extent_io.c +23
-13@@ -721,9 +721,10 @@ static void uncache_state(struct extent_state **cached_ptr)* [start, end] is inclusive This takes the tree lock. */ -int set_extent_bit (struct extent_io_tree *tree,u64 start,u64 end, -int bits,int exclusive_bits,u64 *failed_start, -struct extent_state **cached_state,gfp_t mask) +static int __must_check +__set_extent_bit (struct extent_io_tree *tree,u64 start,u64 end, +int bits,int exclusive_bits,u64 *failed_start, +struct extent_state **cached_state,gfp_t mask) {struct extent_state *state;struct extent_state *prealloc =NULL ;@@ -917,6 +918,15 @@ search_again: goto again; } +int set_extent_bit (struct extent_io_tree *tree,u64 start,u64 end,int bits, +u64 *failed_start,struct extent_state **cached_state, +gfp_t mask) +{ +return __set_extent_bit (tree, start, end, bits,0 , failed_start, + cached_state, mask); +} + +/** * convert_extent - convert all bits in a given range from one bit to another * @tree: the io tree to search @@ -1111,14 +1121,14 @@ search_again:int set_extent_dirty (struct extent_io_tree *tree,u64 start,u64 end,gfp_t mask) { -return set_extent_bit (tree, start, end,EXTENT_DIRTY ,0 ,NULL , +return set_extent_bit (tree, start, end,EXTENT_DIRTY ,NULL ,NULL , mask); }int set_extent_bits (struct extent_io_tree *tree,u64 start,u64 end,int bits,gfp_t mask) { -return set_extent_bit (tree, start, end, bits,0 ,NULL , +return set_extent_bit (tree, start, end, bits,NULL ,NULL , mask); }@@ -1133,7 +1143,7 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, {return set_extent_bit (tree, start, end,EXTENT_DELALLOC |EXTENT_UPTODATE , -0 ,NULL , cached_state, mask); +NULL , cached_state, mask); } int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,@@ -1147,7 +1157,7 @@ int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,int set_extent_new (struct extent_io_tree *tree,u64 start,u64 end,gfp_t mask) { -return set_extent_bit (tree, start, end,EXTENT_NEW ,0 ,NULL , +return set_extent_bit (tree, start, end,EXTENT_NEW ,NULL ,NULL , mask); }@@ -1155,7 +1165,7 @@ int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state **cached_state, gfp_t mask) {return set_extent_bit (tree, start, end,EXTENT_UPTODATE ,0 , -NULL , cached_state, mask); + cached_state, mask); } static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start,@@ -1176,9 +1186,9 @@ int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,int err;u64 failed_start;while (1 ) { - err =set_extent_bit (tree, start, end,EXTENT_LOCKED | bits, -EXTENT_LOCKED , &failed_start, - cached_state,GFP_NOFS ); + err =__set_extent_bit (tree, start, end,EXTENT_LOCKED | bits, +EXTENT_LOCKED , &failed_start, + cached_state,GFP_NOFS );if (err == -EEXIST ) {wait_extent_bit (tree, failed_start, end,EXTENT_LOCKED ); start = failed_start;@@ -1199,8 +1209,8 @@ int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end)int err;u64 failed_start; - err =set_extent_bit (tree, start, end,EXTENT_LOCKED ,EXTENT_LOCKED , - &failed_start,NULL ,GFP_NOFS ); + err =__set_extent_bit (tree, start, end,EXTENT_LOCKED ,EXTENT_LOCKED , + &failed_start,NULL ,GFP_NOFS );if (err == -EEXIST ) {if (failed_start > start) clear_extent_bit(tree, start, failed_start - 1,fs/btrfs/extent_io.h +1
-1@@ -209,7 +209,7 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,int set_extent_bits (struct extent_io_tree *tree,u64 start,u64 end,int bits,gfp_t mask);int set_extent_bit (struct extent_io_tree *tree,u64 start,u64 end, -int bits,int exclusive_bits,u64 *failed_start, +int bits,u64 *failed_start,struct extent_state **cached_state,gfp_t mask);int set_extent_uptodate (struct extent_io_tree *tree,u64 start,u64 end,struct extent_state **cached_state,gfp_t mask);fs/btrfs/inode.c +1
-1@@ -6233,7 +6233,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,if (writing) { write_bits =EXTENT_DELALLOC |EXTENT_DO_ACCOUNTING ; ret =set_extent_bit (&BTRFS_I (inode)->io_tree, lockstart, lockend, -EXTENT_DELALLOC ,0 ,NULL , &cached_state, +EXTENT_DELALLOC ,NULL , &cached_state,GFP_NOFS );if (ret) { clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
Re: [patch 17/35] btrfs: split extent_state ops
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 11 lines · Liu Bo
Quoted 6 lines · Jeff Mahoney
set_extent_bitcan do exclusive locking but only when called by lock_extent*,Drop the exclusive bits argument except when called by
lock_extent.Hi Jeff,
I have to say this is not a good cleanup, any benefits?
Yeah, it eliminates an argument that's only used by a single caller.
- -Jeff
Quoted 87 lines
Quoted 87 lines
Signed-off-by Jeff Mahoney <[email protected]> ---
fs/btrfs/extent_io.c| 36 +++++++++++++++++++++++-------------fs/btrfs/extent_io.h| 2 +-fs/btrfs/inode.c| 2 +- 3
files changed, 25 insertions(+), 15 deletions(-)fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +0
-00112c02..ffa7cc3 100644 ---
a/fs/btrfs/extent_io.c+++b/fs/btrfs/extent_io.c@@ -721,9 +721,10 @@ static voiduncache_state(struct extent_state **cached_ptr)* [start, end] is inclusive This takes the tree lock. */-int set_extent_bit(struct
extent_io_tree*tree, u64 start, u64
end, - int bits, intexclusive_bits, u64*failed_start, -
structextent_state**cached_state,gfp_tmask) +static int__must_check+__set_extent_bit(structextent_io_tree*tree, u64
start, u64 end, + int bits, intexclusive_bits, u64*failed_start, + structextent_state**cached_state,gfp_t
mask) { structextent_state*state; structextent_state*prealloc = NULL; @@ -917,6 +918,15 @@search_again: goto again; }+int set_extent_bit(struct
extent_io_tree*tree, u64 start, u64
end, int bits, + u64*failed_start, structextent_state
**cached_state, +gfp_tmask) +{ + return__set_extent_bit(tree, start, end, bits, 0, failed_start, + cached_state, mask); +} + + /** *convert_extent- convert all
bits in a given range from one bit to another * @tree: the io
tree to search @@ -1111,14 +1121,14 @@search_again: int set_extent_dirty(structextent_io_tree*tree, u64 start, u64
end,gfp_tmask) { - return set_extent_bit(tree, start, end,EXTENT_DIRTY, 0, NULL, + return set_extent_bit(tree, start, end,EXTENT_DIRTY, NULL, NULL, mask); }int set_extent_bits(struct
extent_io_tree*tree, u64 start, u64
end, int bits,gfp_tmask) { - return set_extent_bit(tree, start,
end, bits, 0, NULL, + return set_extent_bit(tree, start, end,
bits, NULL, NULL, mask); }fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +0
-0@@ -1133,7 +1143,7 @@ int set_extent_delalloc(struct
extent_io_tree*tree, u64 start, u64 end, { return set_extent_bit(tree, start, end,EXTENT_DELALLOC|EXTENT_UPTODATE, - 0, NULL,cached_state, mask); +
NULL,cached_state, mask); }int clear_extent_dirty(struct
extent_io_tree*tree, u64 start, u64 end, @@ -1147,7 +1157,7 @@ int clear_extent_dirty(structextent_io_tree*tree, u64 start, u64 end, int set_extent_new(structextent_io_tree*tree, u64 start, u64 end,gfp_tmask) { - return set_extent_bit(tree, start, end,EXTENT_NEW, 0, NULL, + return set_extent_bit(tree, start, end,EXTENT_NEW, NULL, NULL, mask); }fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +0
-0@@ -1155,7 +1165,7 @@ int set_extent_uptodate(struct
extent_io_tree*tree, u64 start, u64 end, structextent_state**cached_state,gfp_tmask) { return set_extent_bit(tree, start,
end,EXTENT_UPTODATE, 0, - NULL,cached_state, mask); +cached_state, mask); }static int clear_extent_uptodate(struct
extent_io_tree*tree, u64 start, @@ -1176,9 +1186,9 @@ int lock_extent_bits(structextent_io_tree*tree, u64 start, u64 end, int err; u64failed_start; while (1) { - err = set_extent_bit(tree, start,
end,EXTENT_LOCKED| bits, -EXTENT_LOCKED,&failed_start, -cached_state,GFP_NOFS); + err =
__set_extent_bit(tree, start, end,EXTENT_LOCKED| bits, +EXTENT_LOCKED,&failed_start, +cached_state,GFP_NOFS); if (err ==-EEXIST) {wait_extent_bit(tree, failed_start, end, EXTENT_LOCKED); start =failed_start; @@ -1199,8 +1209,8 @@ inttry_lock_extent(struct extent_io_tree *tree, u64 start, u64 end)int err; u64failed_start;fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +0
-1- err = set_extent_bit(tree, start, end, EXTENT_LOCKED,
EXTENT_LOCKED, -&failed_start, NULL,GFP_NOFS); + err =
__set_extent_bit(tree, start, end,EXTENT_LOCKED,EXTENT_LOCKED,fs/btrfs/extent_io.c index renamed from fs/btrfs/extent_io.c +1
-0+ &failed_start, NULL, GFP_NOFS); if (err == -EEXIST) {if (
failed_start> start) clear_extent_bit(tree, start,failed_start- 1, diff --gita/fs/btrfs/extent_io.hb/fs/btrfs/extent_io.hindex 439e183..3a171c2 100644 ---a/fs/btrfs/extent_io.h+++b/fs/btrfs/extent_io.h@@ -209,7 +209,7 @@ int clear_extent_bit(structextent_io_tree*tree, u64 start, u64 end, intset_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, int bits, gfp_t mask); int set_extent_bit(structextent_io_tree*tree, u64 start, u64 end, -
int bits, intexclusive_bits, u64*failed_start, + int bits,
u64*failed_start, structextent_state**cached_state,gfp_tmask); intset_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state **cached_state, gfp_t mask);fs/btrfs/inode.c index renamed from fs/btrfs/inode.c +0
-0
Quoted 10 lines
Quoted 8 lines
d16bf3f..593a2c3 100644 ---
a/fs/btrfs/inode.c+++b/fs/btrfs/inode.c@@ -6233,7 +6233,7 @@ staticssize_tbtrfs_direct_IO(int rw, struct kiocb *iocb, if (writing) {write_bits=EXTENT_DELALLOC|EXTENT_DO_ACCOUNTING; ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, -EXTENT_DELALLOC, 0, NULL,&cached_state, +EXTENT_DELALLOC, NULL,&cached_state,GFP_NOFS); if (ret) { clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
- --
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.18 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQIcBAEBAgAGBQJPao/tAAoJEB57S2MheeWyHZkP/RCG1BbvwnFdjtP4/0MYarUM qrulbycGo/Xqod3hXZcGPPxAlxDNOB+mVGxKdHGbKE4t+uvIB9owD0ypWrQf1LP4 ODhEZUzvk0vZ02GnXDyKn6vY30ux1QiSfEKIzDfoZA5iMTz1+zFKesvBFn0HO3Qd bbDQ9QS0ikAsumWY4wiO7huLDhmeBdRU4gwLWiax1kKuudfxgJ1S3Galg7yGz9t9 zmx6bwkNbJ5UbhR5vAaemMTt+CJ199yTvjppuAOGYxM+WSt9gLCRwVJcCEShJ0fV XAiT4PlF9xpT9EPiwQqZnnT4SgPlR+mhaS28afeROoMcBulc4P/BC82dJX3BtkRC V+If5vJCBiVeR6BOU3bmOpDEj0WzZ/QAHiHXIA/2mUnFT1gtjUh3GKD57Z3NzKvw wXQuCgI7FqDMdUVYckyY1ghWjnHofgbJFtFF8EElaQioFqrzE5UtJrS6CiyRpZ/R RLIld6owKYLD8dhD5718qhBAoZTL3vkZnBy4jSHS7hJkOVwmjedAgwBKtzTaBRiR jE3O9qEM5FIVMzqxsLkA1pGPQd3acB4hh6Vc7SkXSF5NljM9kF0fpeR1Medhm7nm WGkBsDYylxvrMFkOVH1mfxOZ3Pw9wcuUJxVn02DjbaEcWj7TBj03HYdjiwXqiFWB IyqwzSy4+0tebs8U2NaG
=GDqG
-----END PGP SIGNATURE-----
PATCH 18/35 btrfs: btrfs_drop_snapshot should return int
In reply to Jeff MahoneyCommit cb1b69f4 (Btrfs: forced readonly when btrfs_drop_snapshot() fails) made btrfs_drop_snapshot return void because there were no callers checking the return value. That is the wrong order to handle error propogation since the caller will have no idea that an error has occured and continue on as if nothing went wrong.
--- fs/btrfs/ctree.h | 6 +++--- fs/btrfs/extent-tree.c | 4 ++-- fs/btrfs/relocation.c | 3 ++- fs/btrfs/transaction.c | 7 +++++-- 4 files changed, 12 insertions(+), 8 deletions(-)
fs/btrfs/ctree.h +3 -3
@@ -2661,9 +2661,9 @@ static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) }int btrfs_prev_leaf (struct btrfs_root *root,struct btrfs_path *path);int btrfs_leaf_free_space (struct btrfs_root *root,struct extent_buffer *leaf); -void btrfs_drop_snapshot (struct btrfs_root *root, -struct btrfs_block_rsv *block_rsv,int update_ref, -int for_reloc); +int __must_check btrfs_drop_snapshot (struct btrfs_root *root, +struct btrfs_block_rsv *block_rsv, +int update_ref,int for_reloc); int btrfs_drop_subtree(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *node,
fs/btrfs/extent-tree.c +2 -2
@@ -6734,7 +6734,7 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,* also make sure backrefs for the shared block and all lower level * blocks are properly updated. */ -void btrfs_drop_snapshot (struct btrfs_root *root, +int btrfs_drop_snapshot (struct btrfs_root *root,struct btrfs_block_rsv *block_rsv,int update_ref,int for_reloc) {
@@ -6902,7 +6902,7 @@ out_free: out:if (err)btrfs_std_error (root->fs_info, err); -return ; +return err; }/*
fs/btrfs/relocation.c +2 -1
@@ -2272,7 +2272,8 @@ again: }else {list_del_init (&reloc_root->root_list); } -btrfs_drop_snapshot (reloc_root, rc->block_rsv,0 ,1 ); + ret =btrfs_drop_snapshot (reloc_root, rc->block_rsv,0 ,1 ); +BUG_ON (ret <0 ); }if (found) {
fs/btrfs/transaction.c +5 -2
@@ -1387,6 +1387,8 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root)spin_unlock (&fs_info->trans_lock);while (!list_empty (&list)) { +int ret; + root = list_entry(list.next, struct btrfs_root, root_list);list_del (&root->root_list);
@@ -1394,9 +1396,10 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root)if (btrfs_header_backref_rev (root->node) <BTRFS_MIXED_BACKREF_REV ) -btrfs_drop_snapshot (root,NULL ,0 ,0 ); + ret =btrfs_drop_snapshot (root,NULL ,0 ,0 );else -btrfs_drop_snapshot (root,NULL ,1 ,0 ); + ret =btrfs_drop_snapshot (root,NULL ,1 ,0 ); +BUG_ON (ret <0 ); }return 0 ; }
Signature · 1 line
1.7.9
PATCH 19/35 btrfs: Dont BUG_ON errors from btrfs_create_subvol_root()
In reply to Jeff MahoneyThis is called from only one place - create_subvol() which passes errors safely back out to it's caller, btrfs_mksubvol where they are handled.
Additionally, btrfs_create_subvol_root() itself bug's needlessly from error return of btrfs_update_inode(). Since create_subvol() was fixed to catch errors we can bubble this one up too.
--- fs/btrfs/inode.c | 3 +-- fs/btrfs/ioctl.c | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-)
fs/btrfs/inode.c +1 -2
@@ -6734,10 +6734,9 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,btrfs_i_size_write (inode,0 ); err =btrfs_update_inode (trans, new_root, inode); -BUG_ON (err);iput (inode); -return 0 ; +return err; }struct inode *btrfs_alloc_inode (struct super_block *sb)
fs/btrfs/ioctl.c +5 -0
@@ -430,6 +430,11 @@ static noinline int create_subvol(struct btrfs_root *root,btrfs_record_root_in_trans (trans, new_root); ret =btrfs_create_subvol_root (trans, new_root, new_dirid); +if (ret) { +/* We potentially lose an unused inode item here */ + goto fail; + } +/* * insert the directory item */
Signature · 1 line
1.7.9
PATCH 20/35 btrfs: Dont BUG_ON() errors in update_ref_for_cow()
In reply to Jeff MahoneyThe only caller of update_ref_for_cow() is __btrfs_cow_block() which was originally ignoring any return values. update_ref_for_cow() however doesn't look like a candidate to become a void function - there are a few places where errors can occur.
So instead I changed update_ref_for_cow() to bubble all errors up (instead of BUG_ON). __btrfs_cow_block() was then updated to catch and BUG_ON() any errors from update_ref_for_cow(). The end effect is that we have no change in behavior, but about 8 different places where a BUG_ON(ret) was removed.
Obviously a future patch will have to address the BUG_ON() in __btrfs_cow_block().
--- fs/btrfs/ctree.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-)
fs/btrfs/ctree.c +7 -4
@@ -331,7 +331,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,if (btrfs_block_can_be_shared (root, buf)) { ret =btrfs_lookup_extent_info (trans, root, buf->start, buf->len, &refs, &flags); -BUG_ON (ret); +if (ret) +return ret;BUG_ON (refs ==0 ); }else { refs =1 ;
@@ -375,7 +376,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, buf->start, buf->len, new_flags, 0); -BUG_ON (ret); +if (ret) +return ret; } }else {if (flags &BTRFS_BLOCK_FLAG_FULL_BACKREF ) {
@@ -415,7 +417,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, {struct btrfs_disk_key disk_key;struct extent_buffer *cow; -int level; +int level, ret;int last_ref =0 ;int unlock_orig =0 ;u64 parent_start;
@@ -467,7 +469,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, (unsigned long )btrfs_header_fsid (cow), BTRFS_FSID_SIZE); -update_ref_for_cow (trans, root, buf, cow, &last_ref); + ret =update_ref_for_cow (trans, root, buf, cow, &last_ref); +BUG_ON (ret);if (root->ref_cows)btrfs_reloc_cow_block (trans, root, buf, cow);
Signature · 1 line
1.7.9
PATCH 21/35 btrfs: Dont BUG_ON kzalloc error in btrfs_lookup_csums_range()
In reply to Jeff MahoneyUnfortunately it isn't enough to just exit here - the kzalloc() happens in a loop and the allocated items are added to a linked list whose head is passed in from the caller.
To fix the BUG_ON() and also provide the semantic that the list passed in is only modified on success, I create function-local temporary list that we add items too. If no error is met, that list is spliced to the callers at the end of the function. Otherwise the list will be walked and all items freed before the error value is returned.
I did a simple test on this patch by forcing an error at the kzalloc() point and verifying that when this hits (git clone seemed to exercise this), the function throws the proper error. Unfortunately but predictably, we later hit a BUG_ON(ret) type line that still hasn't been fixed up ;)
--- fs/btrfs/file-item.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-)
fs/btrfs/file-item.c +13 -2
@@ -284,6 +284,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,struct btrfs_ordered_sum *sums;struct btrfs_sector_sum *sector_sum;struct btrfs_csum_item *item; +LIST_HEAD (tmplist);unsigned long offset;int ret;size_t size;
@@ -358,7 +359,10 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, MAX_ORDERED_SUM_BYTES(root)); sums =kzalloc (btrfs_ordered_sum_size (root, size),GFP_NOFS ); -BUG_ON (!sums); +if (!sums) { + ret = -ENOMEM ; + goto fail; + } sector_sum = sums->sums; sums->bytenr = start;
@@ -380,12 +384,19 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, offset += csum_size; sector_sum++; } -list_add_tail (&sums->list, list); +list_add_tail (&sums->list, &tmplist); } path->slots[0 ]++; } ret =0 ; fail: +while (ret <0 && !list_empty (&tmplist)) { + sums = list_entry(&tmplist, struct btrfs_ordered_sum, list); +list_del (&sums->list); +kfree (sums); + } +list_splice_tail (&tmplist, list); +btrfs_free_path (path);return ret; }
Signature · 1 line
1.7.9
PATCH 22/35 btrfs: Dont BUG_ON errors in __finish_chunk_alloc()
In reply to Jeff MahoneyAll callers of __finish_chunk_alloc() BUG_ON() return value, so it's trivial for us to always bubble up any errors caught in __finish_chunk_alloc() to be caught there.
--- fs/btrfs/volumes.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
fs/btrfs/volumes.c +6 -4
@@ -3417,16 +3417,18 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans, key.offset = chunk_offset; ret =btrfs_insert_item (trans, chunk_root, &key, chunk, item_size); -BUG_ON (ret); -if (map->type &BTRFS_BLOCK_GROUP_SYSTEM ) { +if (ret ==0 && map->type &BTRFS_BLOCK_GROUP_SYSTEM ) { +/* +* TODO: Cleanup of inserted chunk root in case of +* failure. +*/ ret =btrfs_add_system_chunk (chunk_root, &key, chunk, item_size); -BUG_ON (ret); }kfree (chunk); -return 0 ; +return ret; }/*
Signature · 1 line
1.7.9
PATCH 23/35 btrfs: Go readonly on bad extent refs in update_ref_for_cow()
In reply to Jeff Mahoneyupdate_ref_for_cow() will BUG_ON() after it's call to btrfs_lookup_extent_info() if no existing references are found. Since refs are computed directly from disk, this should be treated as a corruption instead of a logic error.
--- fs/btrfs/ctree.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
fs/btrfs/ctree.c +5 -1
@@ -333,7 +333,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, buf->len, &refs, &flags);if (ret)return ret; -BUG_ON (refs ==0 ); +if (refs ==0 ) { + ret = -EROFS ; +btrfs_std_error (root->fs_info, ret); +return ret; + } }else { refs =1 ; if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID ||
Signature · 1 line
1.7.9
PATCH 24/35 btrfs: Dont BUG_ON errors from update_ref_for_cow()
In reply to Jeff Mahoney__btrfs_cow_block(), the only caller of update_ref_for_cow() will BUG_ON() any error return. Instead, we can go read-only fs as update_ref_for_cow() manipulates disk data in a way which doesn't look like it's easily rolled back.
--- fs/btrfs/ctree.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
fs/btrfs/ctree.c +4 -1
@@ -474,7 +474,10 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, BTRFS_FSID_SIZE); ret =update_ref_for_cow (trans, root, buf, cow, &last_ref); -BUG_ON (ret); +if (ret) { +btrfs_std_error (root->fs_info, ret); +return ret; + }if (root->ref_cows)btrfs_reloc_cow_block (trans, root, buf, cow);
Signature · 1 line
1.7.9
PATCH 25/35 btrfs: Go readonly on tree errors in balance_level
In reply to Jeff Mahoneybalace_level() seems to deal with missing tree nodes by BUG_ON(). Instead, we can easily just set the file system readonly and bubble -EROFS back up the stack.
--- fs/btrfs/ctree.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-)
fs/btrfs/ctree.c +11 -2
@@ -944,7 +944,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,/* promote the child to a root */ child =read_node_slot (root, mid,0 ); -BUG_ON (!child); +if (!child) { + ret = -EROFS ; +btrfs_std_error (root->fs_info, ret); + goto enospc; + } +btrfs_tree_lock (child);btrfs_set_lock_blocking (child); ret =btrfs_cow_block (trans, root, child, mid,0 , &child);
@@ -1042,7 +1047,11 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,* otherwise we would have pulled some pointers from the * right */ -BUG_ON (!left); +if (!left) { + ret = -EROFS ; +btrfs_std_error (root->fs_info, ret); + goto enospc; + } wret =balance_node_right (trans, root, mid, left);if (wret <0 ) { ret = wret;
Signature · 1 line
1.7.9
PATCH 26/35 btrfs: Dont BUG_ON insert errors in btrfs_alloc_dev_extent()
In reply to Jeff MahoneyThe only caller of btrfs_alloc_dev_extent() is __btrfs_alloc_chunk() which already bugs on any error returned. We can remove the BUG_ON's in btrfs_alloc_dev_extent() then since __btrfs_alloc_chunk() will "catch" them anyway.
--- fs/btrfs/volumes.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
fs/btrfs/volumes.c +3 -1
@@ -1075,7 +1075,8 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, key.type =BTRFS_DEV_EXTENT_KEY ; ret =btrfs_insert_empty_item (trans, root, path, &key,sizeof (*extent)); -BUG_ON (ret); +if (ret) + goto out; leaf = path->nodes[0 ]; extent = btrfs_item_ptr(leaf, path->slots[0],
@@ -1090,6 +1091,7 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,btrfs_set_dev_extent_length (leaf, extent, num_bytes);btrfs_mark_buffer_dirty (leaf); +out:btrfs_free_path (path);return ret; }
Signature · 1 line
1.7.9
PATCH 27/35 btrfs: Remove BUG_ON from __btrfs_alloc_chunk()
In reply to Jeff MahoneyWe BUG_ON() error from add_extent_mapping(), but that error looks pretty easy to bubble back up - as far as I can tell there have not been any permanent modifications to fs state at that point.
--- fs/btrfs/volumes.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
fs/btrfs/volumes.c +2 -1
@@ -3327,8 +3327,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,write_lock (&em_tree->lock); ret =add_extent_mapping (em_tree, em);write_unlock (&em_tree->lock); -BUG_ON (ret);free_extent_map (em); +if (ret) + goto error; ret = btrfs_make_block_group(trans, extent_root, 0, type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
Signature · 1 line
1.7.9
PATCH 28/35 btrfs: Remove BUG_ON from __finish_chunk_alloc()
In reply to Jeff Mahoneybtrfs_alloc_chunk() unconditionally BUGs on any error returned from __finish_chunk_alloc() so there's no need for two BUG_ON lines. Remove the one from __finish_chunk_alloc().
--- fs/btrfs/volumes.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
fs/btrfs/volumes.c +3 -1
@@ -3383,7 +3383,8 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans, device = map->stripes[index].dev; device->bytes_used += stripe_size; ret =btrfs_update_device (trans, device); -BUG_ON (ret); +if (ret) + goto out_free; index++; }
@@ -3430,6 +3431,7 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans, item_size); } +out_free:kfree (chunk);return ret; }
Signature · 1 line
1.7.9
PATCH 29/35 btrfs: add varargs to btrfs_error
In reply to Jeff Mahoney btrfs currently handles most errors with BUG_ON. This patch is a work-in- progress but aims to handle most errors other than internal logic errors and ENOMEM more gracefully.
This iteration prevents most crashes but can run into lockups with the page lock on occasion when the timing "works out."
--- fs/btrfs/ctree.h | 12 ++++++++- fs/btrfs/super.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 66 insertions(+), 9 deletions(-)
fs/btrfs/ctree.h +10 -2
@@ -2964,13 +2964,21 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);/* super.c */ int btrfs_parse_options (struct btrfs_root *root,char *options);int btrfs_sync_fs (struct super_block *sb,int wait); +void btrfs_printk (struct btrfs_fs_info *fs_info,const char *fmt, ...);void __btrfs_std_error (struct btrfs_fs_info *fs_info,const char *function, -unsigned int line,int errno); +unsigned int line,int errno,const char *fmt, ...);#define btrfs_std_error (fs_info, errno) \ do { \ if ((errno)) \ - __btrfs_std_error((fs_info), __func__, __LINE__, (errno));\ + __btrfs_std_error((fs_info), __func__, \ + __LINE__, (errno), NULL); \ +} while (0) + +#define btrfs_error(fs_info, errno, fmt, args...) \ +do { \ + __btrfs_std_error((fs_info), __func__, __LINE__, \ + (errno), fmt, ##args); \ } while (0) void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,
fs/btrfs/super.c +56 -7
81 lines not on this page · raw message
Signature · 1 line
1.7.9
PATCH 30/35 btrfs: enhance transaction abort infrastructure
In reply to Jeff Mahoney--- fs/btrfs/ctree.h | 13 +++- fs/btrfs/disk-io.c | 50 ++++++++++++- fs/btrfs/disk-io.h | 4 + fs/btrfs/relocation.c | 14 ++-- fs/btrfs/scrub.c | 8 ++- fs/btrfs/super.c | 74 +++++++++++++++++-- fs/btrfs/transaction.c | 190 +++++++++++++++++++++++++++++++++++++++--------- fs/btrfs/transaction.h | 3 + 8 files changed, 300 insertions(+), 56 deletions(-)
fs/btrfs/ctree.h +12 -1
@@ -2968,6 +2968,16 @@ void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...);void __btrfs_std_error (struct btrfs_fs_info *fs_info,const char *function,unsigned int line,int errno,const char *fmt, ...); +void __btrfs_abort_transaction (struct btrfs_trans_handle *trans, +struct btrfs_root *root,const char *function, +unsigned int line,int errno); + +#define btrfs_abort_transaction (trans, root, errno) \ +do { \ + __btrfs_abort_transaction(trans, root, __func__, \ + __LINE__, errno); \ +} while (0) +#define btrfs_std_error (fs_info, errno) \ do { \ if ((errno)) \
@@ -3024,7 +3034,7 @@ void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,void btrfs_reloc_pre_snapshot (struct btrfs_trans_handle *trans,struct btrfs_pending_snapshot *pending,u64 *bytes_to_reserve); -void btrfs_reloc_post_snapshot (struct btrfs_trans_handle *trans, +int btrfs_reloc_post_snapshot (struct btrfs_trans_handle *trans,struct btrfs_pending_snapshot *pending);/* scrub.c */
@@ -3034,6 +3044,7 @@ void btrfs_scrub_pause(struct btrfs_root *root);void btrfs_scrub_pause_super (struct btrfs_root *root);void btrfs_scrub_continue (struct btrfs_root *root);void btrfs_scrub_continue_super (struct btrfs_root *root); +int __btrfs_scrub_cancel (struct btrfs_fs_info *info);int btrfs_scrub_cancel (struct btrfs_root *root);int btrfs_scrub_cancel_dev (struct btrfs_root *root,struct btrfs_device *dev);int btrfs_scrub_cancel_devid (struct btrfs_root *root,u64 devid);
fs/btrfs/disk-io.c +46 -4
72 lines not on this page · raw message
fs/btrfs/disk-io.h +4 -0
@@ -85,6 +85,10 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info);int btrfs_add_log_tree (struct btrfs_trans_handle *trans,struct btrfs_root *root); +int btrfs_cleanup_transaction (struct btrfs_root *root); +void btrfs_cleanup_one_transaction (struct btrfs_transaction *trans, +struct btrfs_root *root); +void btrfs_abort_devices (struct btrfs_root *root);#ifdef CONFIG_DEBUG_LOCK_ALLOC void btrfs_init_lockdep (void );
fs/btrfs/relocation.c +8 -6
@@ -4410,7 +4410,7 @@ void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans,* called after snapshot is created. migrate block reservation * and create reloc root for the newly created snapshot */ -void btrfs_reloc_post_snapshot (struct btrfs_trans_handle *trans, +int btrfs_reloc_post_snapshot (struct btrfs_trans_handle *trans,struct btrfs_pending_snapshot *pending) {struct btrfs_root *root = pending->root;
@@ -4420,7 +4420,7 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,int ret;if (!root->reloc_root) -return ; +return 0 ; rc = root->fs_info->reloc_ctl; rc->merging_rsv_size += rc->nodes_relocated;
@@ -4429,19 +4429,21 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, ret =btrfs_block_rsv_migrate (&pending->block_rsv, rc->block_rsv, rc->nodes_relocated); -BUG_ON (ret); +if (ret) +return ret; } new_root = pending->snap; reloc_root =create_reloc_root (trans, root->reloc_root, new_root->root_key.objectid); +if (IS_ERR (reloc_root)) +return PTR_ERR (reloc_root); ret =__add_reloc_root (reloc_root);BUG_ON (ret <0 ); new_root->reloc_root = reloc_root; -if (rc->create_reloc_tree) { +if (rc->create_reloc_tree) ret =clone_backref_node (trans, rc, root, reloc_root); -BUG_ON (ret); - } +return ret; }
fs/btrfs/scrub.c +6 -2
@@ -1680,9 +1680,8 @@ void btrfs_scrub_continue_super(struct btrfs_root *root)up_write (&root->fs_info->scrub_super_lock); } -int btrfs_scrub_cancel (struct btrfs_root *root) +int __btrfs_scrub_cancel (struct btrfs_fs_info *fs_info) { -struct btrfs_fs_info *fs_info = root->fs_info;mutex_lock (&fs_info->scrub_lock);if (!atomic_read (&fs_info->scrubs_running)) {
@@ -1703,6 +1702,11 @@ int btrfs_scrub_cancel(struct btrfs_root *root)return 0 ; } +int btrfs_scrub_cancel (struct btrfs_root *root) +{ +return __btrfs_scrub_cancel (root->fs_info); +} +int btrfs_scrub_cancel_dev (struct btrfs_root *root,struct btrfs_device *dev) {struct btrfs_fs_info *fs_info = root->fs_info;
fs/btrfs/super.c +66 -8
121 lines not on this page · raw message
fs/btrfs/transaction.c +155 -35
410 lines not on this page · raw message
fs/btrfs/transaction.h +3 -0
@@ -43,6 +43,7 @@ struct btrfs_transaction {wait_queue_head_t commit_wait;struct list_head pending_snapshots;struct btrfs_delayed_ref_root delayed_refs; +int aborted; };struct btrfs_trans_handle {
@@ -55,6 +56,7 @@ struct btrfs_trans_handle {struct btrfs_transaction *transaction;struct btrfs_block_rsv *block_rsv;struct btrfs_block_rsv *orig_rsv; +int aborted; };struct btrfs_pending_snapshot {
@@ -114,4 +116,5 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, struct extent_io_tree *dirty_pages, int mark);int btrfs_transaction_blocked (struct btrfs_fs_info *info);int btrfs_transaction_in_commit (struct btrfs_fs_info *info); +void put_transaction (struct btrfs_transaction *transaction);#endif
Signature · 1 line
1.7.9
PATCH 32/35 btrfs: Fix busyloop in transaction_kthread()
In reply to Jeff MahoneyWhen a filesystem got aborted due do error, transaction_kthread() will busyloop. Fix it by going to sleep in that case as well. Maybe we should just stop transaction_kthread() when filesystem is aborted but that would be more complex.
--- fs/btrfs/disk-io.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
fs/btrfs/disk-io.c +7 -2
@@ -1640,8 +1640,10 @@ static int transaction_kthread(void *arg)u64 transid;unsigned long now;unsigned long delay; +bool cannot_commit; do { + cannot_commit = false; delay = HZ * 30; vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); mutex_lock(&root->fs_info->transaction_kthread_mutex);
@@ -1665,8 +1667,10 @@ static int transaction_kthread(void *arg)/* If the file system is aborted, this will always fail. */ trans =btrfs_join_transaction (root); -if (IS_ERR (trans)) +if (IS_ERR (trans)) { + cannot_commit = true; goto sleep; + }if (transid == trans->transid) {btrfs_commit_transaction (trans, root); }else {
@@ -1679,7 +1683,8 @@ sleep:if (!try_to_freeze ()) {set_current_state (TASK_INTERRUPTIBLE );if (!kthread_should_stop () && - !btrfs_transaction_blocked (root->fs_info)) + (!btrfs_transaction_blocked (root->fs_info) || + cannot_commit))schedule_timeout (delay);__set_current_state (TASK_RUNNING ); }
Signature · 1 line
1.7.9
PATCH 33/35 btrfs: handle errors when excluding super extents
In reply to Jeff MahoneySome images produced by btrfs-image cause a mount crash in rmap block when excluding superblock extents. Handle the errors gracefully.
--- fs/btrfs/extent-tree.c | 19 ++++++++++++++++--- fs/btrfs/volumes.c | 20 +++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-)
fs/btrfs/extent-tree.c +16 -3
@@ -250,10 +250,17 @@ static int exclude_super_stripes(struct btrfs_root *root,for (i =0 ; i <BTRFS_SUPER_MIRROR_MAX ; i++) { bytenr =btrfs_sb_offset (i); +if (bytenr <= cache->key.objectid + cache->key.offset) +break ; + logical =NULL ; ret =btrfs_rmap_block (&root->fs_info->mapping_tree, cache->key.objectid, bytenr,0 , &logical, &nr, &stripe_len); -BUG_ON (ret);/* -ENOMEM */ +if (ret <0 ) { +kfree (logical); +free_excluded_extents (root, cache); + goto out; + }while (nr--) { cache->bytes_super += stripe_len;
@@ -264,7 +271,9 @@ static int exclude_super_stripes(struct btrfs_root *root,kfree (logical); } -return 0 ; + +out: +return ret; } static struct btrfs_caching_control *
@@ -7665,7 +7674,11 @@ int btrfs_read_block_groups(struct btrfs_root *root)* info has super bytes accounted for, otherwise we'll think * we have more space than we actually do. */ -exclude_super_stripes (root, cache); + ret =exclude_super_stripes (root, cache); +if (ret <0 ) { +kfree (cache); + goto error; + }/* * check for two cases, either we are full, and therefore
fs/btrfs/volumes.c +17 -3
@@ -3911,12 +3911,22 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,u64 length;u64 stripe_nr;int i, j, nr =0 ; +int ret =0 ;read_lock (&em_tree->lock); em =lookup_extent_mapping (em_tree, chunk_start,1 );read_unlock (&em_tree->lock); -BUG_ON (!em || em->start != chunk_start); +if (!em) +return -ENOENT ; + +if (em->start != chunk_start) { +printk (KERN_DEBUG "btrfs: rmap em->start %llu != %llu\n" , + em->start, chunk_start); + ret = -EINVAL ; + goto out_error; + } + map = (struct map_lookup *)em->bdev; length = em->len;
@@ -3926,7 +3936,10 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,do_div (length, map->num_stripes); buf =kzalloc (sizeof (u64) * map->num_stripes,GFP_NOFS ); -BUG_ON (!buf);/* -ENOMEM */ +if (!buf) { + ret = -ENOMEM ; + goto out_error; + }for (i =0 ; i < map->num_stripes; i++) {if (devid && map->stripes[i].dev->devid != devid)
@@ -3960,8 +3973,9 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, *naddrs = nr; *stripe_len = map->stripe_len; +out_error:free_extent_map (em); -return 0 ; +return ret; }static void btrfs_end_bio (struct bio *bio,int err)
Signature · 1 line
1.7.9
Re: [patch 33/35] btrfs: handle errors when excluding super extents
fs/btrfs/extent-tree.c static int exclude_super_stripes(struct btrfs_root *root, · line 254
Quoted 8 lines · Jeff Mahoney
fs/btrfs/extent-tree.c +2
-0@@ -250,10 +250,17 @@ static int exclude_super_stripes(struct btrfs_root *root,for (i =0 ; i <BTRFS_SUPER_MIRROR_MAX ; i++) { bytenr =btrfs_sb_offset (i); +if (bytenr <= cache->key.objectid + cache->key.offset) +break ;
The condition is wrong. Exclude superblock if it's inside the block group:
if (cache->key.objectid + cache->key.offset <= bytenr)
break;
if (bytenr < cache->key.objectid)
continue;break if the remaining sb's are too far and skip to next one otherwise.
Quoted 13 lines
fs/btrfs/extent-tree.c +6
-1+ logical =NULL ; ret =btrfs_rmap_block (&root->fs_info->mapping_tree, cache->key.objectid, bytenr,0 , &logical, &nr, &stripe_len); -BUG_ON (ret);/* -ENOMEM */ +if (ret <0 ) { +kfree (logical); +free_excluded_extents (root, cache); + goto out; + }while (nr--) { cache->bytes_super += stripe_len;
PATCH 34/35 btrfs: enhance superblock sanity checks
In reply to Jeff MahoneyValidate checksum algorithm during mount and prevent BUG_ON later in btrfs_super_csum_size.
--- fs/btrfs/disk-io.c | 23 ++++++++++++++++++----- 1 files changed, 18 insertions(+), 5 deletions(-)
fs/btrfs/disk-io.c +18 -5
@@ -48,7 +48,7 @@static struct extent_io_ops btree_extent_io_ops;static void end_workqueue_fn (struct btrfs_work *work);static void free_fs_root (struct btrfs_root *root); -static void btrfs_check_super_valid (struct btrfs_fs_info *fs_info, +static int btrfs_check_super_valid (struct btrfs_fs_info *fs_info,int read_only);static void btrfs_destroy_ordered_operations (struct btrfs_root *root);static void btrfs_destroy_ordered_extents (struct btrfs_root *root);
@@ -2135,7 +2135,12 @@ int open_ctree(struct super_block *sb,/* check FS state, whether FS is broken. */ fs_info->fs_state |=btrfs_super_flags (disk_super); -btrfs_check_super_valid (fs_info, sb->s_flags &MS_RDONLY ); + ret =btrfs_check_super_valid (fs_info, sb->s_flags &MS_RDONLY ); +if (ret) { +printk (KERN_ERR "btrfs: superblock contains fatal errors\n" ); + err = ret; + goto fail_alloc; + }/* * run through our array of backup supers and setup
@@ -3324,15 +3329,23 @@ out:return 0 ; } -static void btrfs_check_super_valid (struct btrfs_fs_info *fs_info, +static int btrfs_check_super_valid (struct btrfs_fs_info *fs_info,int read_only) { +if (btrfs_super_csum_type (fs_info->super_copy) >=ARRAY_SIZE (btrfs_csum_sizes)) { +printk (KERN_ERR "btrfs: unsupported checksum algorithm\n" ); +return -EINVAL ; + } +if (read_only) -return ; +return 0 ; -if (fs_info->fs_state &BTRFS_SUPER_FLAG_ERROR ) +if (fs_info->fs_state &BTRFS_SUPER_FLAG_ERROR ) {printk (KERN_WARNING "warning: mount fs with errors, " "running btrfsck is recommended\n" ); + } + +return 0 ; }int btrfs_error_commit_super (struct btrfs_root *root)
Signature · 1 line
1.7.9
PATCH 35/35 btrfs: disallow unequal data/metadata blocksize for mixed block groups
In reply to Jeff MahoneyWith support for bigger metadata blocks, we must avoid mounting a filesystem with different block size for mixed block groups, this causes corruption (found by xfstests/083).
--- fs/btrfs/disk-io.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
fs/btrfs/disk-io.c +8 -0
@@ -2302,6 +2302,14 @@ int open_ctree(struct super_block *sb, goto fail_sb_buffer; } +if ((features &BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS ) && + (leafsize != nodesize && sectorsize != nodesize)) { +printk (KERN_WARNING "btrfs: unequal leaf/node/sector sizes " +"are not allowed for mixed block groups on %s\n" , + sb->s_id); + goto fail_sb_buffer; + } +mutex_lock (&fs_info->chunk_mutex); ret =btrfs_read_sys_array (tree_root);mutex_unlock (&fs_info->chunk_mutex);
Signature · 1 line
1.7.9
Re: [patch 35/35] btrfs: disallow unequal data/metadata blocksize for mixed block groups
Quoted 14 lines · Jeff Mahoney
With support for bigger metadata blocks, we must avoid mounting a filesystem with different block size for mixed block groups, this causes corruption (found by xfstests/083).
Signed-off-by David Sterba <[email protected]>--- fs/btrfs/disk-io.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)fs/btrfs/disk-io.c +0
-0
fs/btrfs/disk-io.c int open_ctree(struct super_block *sb, · line 2306
Quoted 5 lines
fs/btrfs/disk-io.c +2
-0@@ -2302,6 +2302,14 @@ int open_ctree(struct super_block *sb, goto fail_sb_buffer; } +if ((features &BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS ) && + (leafsize != nodesize && sectorsize != nodesize)) {
Dave, Shouldn't this be like this (you want all three sizes to be equal in mixed mode, don't you?):
if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
(leafsize != nodesize || sectorsize != nodesize)) {Quoted 9 lines
fs/btrfs/disk-io.c +6
-0+printk (KERN_WARNING "btrfs: unequal leaf/node/sector sizes " +"are not allowed for mixed block groups on %s\n" , + sb->s_id); + goto fail_sb_buffer; + } +mutex_lock (&fs_info->chunk_mutex); ret =btrfs_read_sys_array (tree_root);mutex_unlock (&fs_info->chunk_mutex);
Re: [patch 35/35] btrfs: disallow unequal data/metadata blocksize for mixed block groups
Quoted 6 lines · Stefan Behrens
Quoted 6 lines
fs/btrfs/disk-io.c +0
-0@@ -2302,6 +2302,14 @@ int open_ctree(struct super_block *sb, goto fail_sb_buffer; }
Quoted 7 lines
fs/btrfs/disk-io.c int open_ctree(struct super_block *sb, · line 2306
Quoted 2 lines
fs/btrfs/disk-io.c +2
-0+if ((features &BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS ) && + (leafsize != nodesize && sectorsize != nodesize)) {Dave, Shouldn't this be like this (you want all three sizes to be equal in mixed mode, don't you?):
if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) && (leafsize != nodesize || sectorsize != nodesize)) {
Yes, you're right, thanks for catching it.
david