From 2757495c906113896b378bf084708846273c87b2 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 14 May 2009 13:10:02 -0400 Subject: Btrfs: init inode ordered_data_close flag properly This flag is used to decide when we need to send a given file through the ordered code to make sure it is fully written before a transaction commits. It was not being properly set to zero when the inode was being setup. Signed-off-by: Chris Mason diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 90c23eb..22450bd 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3122,6 +3122,7 @@ static noinline void init_btrfs_i(struct inode *inode) bi->flags = 0; bi->index_cnt = (u64)-1; bi->last_unlink_trans = 0; + bi->ordered_data_close = 0; extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); extent_io_tree_init(&BTRFS_I(inode)->io_tree, inode->i_mapping, GFP_NOFS); -- cgit v0.10.2 From 76a05b35a320e8c968d0fec8f512a1acae227309 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 14 May 2009 13:24:30 -0400 Subject: Btrfs: Don't loop forever on metadata IO failures When a btrfs metadata read fails, the first thing we try to do is find a good copy on another mirror of the block. If this fails, read_tree_block() ends up returning a buffer that isn't up to date. The btrfs btree reading code was reworked to drop locks and repeat the search when IO was done, but the changes didn't add a check for failed reads. The end result was looping forever on buffers that were never going to become up to date. Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index a99f1c2..fedf8b9 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1469,6 +1469,7 @@ read_block_for_search(struct btrfs_trans_handle *trans, u32 blocksize; struct extent_buffer *b = *eb_ret; struct extent_buffer *tmp; + int ret; blocknr = btrfs_node_blockptr(b, slot); gen = btrfs_node_ptr_generation(b, slot); @@ -1476,6 +1477,10 @@ read_block_for_search(struct btrfs_trans_handle *trans, tmp = btrfs_find_tree_block(root, blocknr, blocksize); if (tmp && btrfs_buffer_uptodate(tmp, gen)) { + /* + * we found an up to date block without sleeping, return + * right away + */ *eb_ret = tmp; return 0; } @@ -1483,7 +1488,9 @@ read_block_for_search(struct btrfs_trans_handle *trans, /* * reduce lock contention at high levels * of the btree by dropping locks before - * we read. + * we read. Don't release the lock on the current + * level because we need to walk this node to figure + * out which blocks to read. */ btrfs_unlock_up_safe(p, level + 1); btrfs_set_path_blocking(p); @@ -1494,10 +1501,21 @@ read_block_for_search(struct btrfs_trans_handle *trans, reada_for_search(root, p, level, slot, key->objectid); btrfs_release_path(NULL, p); + + ret = -EAGAIN; tmp = read_tree_block(root, blocknr, blocksize, gen); - if (tmp) + if (tmp) { + /* + * If the read above didn't mark this buffer up to date, + * it will never end up being up to date. Set ret to EIO now + * and give up so that our caller doesn't loop forever + * on our EAGAINs. + */ + if (!btrfs_buffer_uptodate(tmp, 0)) + ret = -EIO; free_extent_buffer(tmp); - return -EAGAIN; + } + return ret; } /* @@ -1696,6 +1714,9 @@ cow_done: if (ret == -EAGAIN) goto again; + if (ret == -EIO) + goto done; + if (!p->skip_locking) { int lret; @@ -1738,6 +1759,8 @@ done: */ if (!p->leave_spinning) btrfs_set_path_blocking(p); + if (ret < 0) + btrfs_release_path(root, p); return ret; } @@ -4212,6 +4235,11 @@ again: if (ret == -EAGAIN) goto again; + if (ret < 0) { + btrfs_release_path(root, path); + goto done; + } + if (!path->skip_locking) { ret = btrfs_try_spin_lock(next); if (!ret) { @@ -4246,6 +4274,11 @@ again: if (ret == -EAGAIN) goto again; + if (ret < 0) { + btrfs_release_path(root, path); + goto done; + } + if (!path->skip_locking) { btrfs_assert_tree_locked(path->nodes[level]); ret = btrfs_try_spin_lock(next); -- cgit v0.10.2 From cc7b0c9b701a079016183f3546b4d720194b367f Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 14 May 2009 13:31:21 -0400 Subject: Btrfs: remove some WARN_ONs in the IO failure path These debugging WARN_ONs make too much console noise during regular IO failures. An IO failure will still generate a number of messages as we verify checksums etc, but these two are not needed. Signed-off-by: Chris Mason diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0ff16d3..4b0ea0b 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -848,8 +848,6 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, if (ret == 0) set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); - else - WARN_ON(1); return buf; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 22450bd..1c8b019 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4296,7 +4296,6 @@ out: } if (err) { free_extent_map(em); - WARN_ON(1); return ERR_PTR(err); } return em; -- cgit v0.10.2 From 5d847a8ed970d17e2734ff9e07a74fe36cceb24e Mon Sep 17 00:00:00 2001 From: Li Hong Date: Thu, 14 May 2009 13:52:21 -0400 Subject: Btrfs: remove outdated comment in btrfs_ioctl_resize() In Li Zefan's commit dae7b665cf6d6e6e733f1c9c16cf55547dd37e33, a combination call of kmalloc() and copy_from_user() is replaced by memdup_user(). So btrfs_ioctl_resize() doesn't use GFP_NOFS any more. Signed-off-by: Li Hong Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 48762aa..db84aa4 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -437,10 +437,6 @@ out_unlock: return 0; } -/* - * Called inside transaction, so use GFP_NOFS - */ - static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) { u64 new_size; -- cgit v0.10.2 From 6b65c5c61bf86086817a5ed786c8f45755ac83b3 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 14 May 2009 13:52:21 -0400 Subject: Btrfs: make show_options result match actual option names The notreelog and flushoncommit mount options were being printed slightly differently. Signed-off-by: Sage Weil Signed-off-by: Chris Mason diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index bf0e84c..e99510b 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -436,9 +436,9 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) if (btrfs_test_opt(root, SSD)) seq_puts(seq, ",ssd"); if (btrfs_test_opt(root, NOTREELOG)) - seq_puts(seq, ",no-treelog"); + seq_puts(seq, ",notreelog"); if (btrfs_test_opt(root, FLUSHONCOMMIT)) - seq_puts(seq, ",flush-on-commit"); + seq_puts(seq, ",flushoncommit"); if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) seq_puts(seq, ",noacl"); return 0; -- cgit v0.10.2 From 9f55684c2d9869e8cc53595a3fee679958511cfb Mon Sep 17 00:00:00 2001 From: Sankar P Date: Thu, 14 May 2009 13:52:22 -0400 Subject: Btrfs: Spelling fix in btrfs_lookup_first_block_group comments Signed-off-by: Sankar P Signed-off-by: Chris Mason diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e496644..3e2c7c7 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -312,7 +312,7 @@ btrfs_lookup_first_block_group(struct btrfs_fs_info *info, u64 bytenr) } /* - * return the block group that contains teh given bytenr + * return the block group that contains the given bytenr */ struct btrfs_block_group_cache *btrfs_lookup_block_group( struct btrfs_fs_info *info, -- cgit v0.10.2