summaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c39
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/btrfs/extent-tree.c2
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/btrfs/ioctl.c4
-rw-r--r--fs/btrfs/super.c16
6 files changed, 44 insertions, 21 deletions
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);
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/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,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 90c23eb..1c8b019 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);
@@ -4295,7 +4296,6 @@ out:
}
if (err) {
free_extent_map(em);
- WARN_ON(1);
return ERR_PTR(err);
}
return em;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 5e94ea6..2624b53 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;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3536bdb..2ff7cd2 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;
@@ -502,8 +502,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = -EBUSY;
goto error_close_devices;
}
@@ -517,8 +516,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
error = btrfs_fill_super(s, fs_devices, data,
flags & MS_SILENT ? 1 : 0);
if (error) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
goto error_free_subvol_name;
}
@@ -535,15 +533,13 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
mutex_unlock(&s->s_root->d_inode->i_mutex);
if (IS_ERR(root)) {
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = PTR_ERR(root);
goto error_free_subvol_name;
}
if (!root->d_inode) {
dput(root);
- up_write(&s->s_umount);
- deactivate_super(s);
+ deactivate_locked_super(s);
error = -ENXIO;
goto error_free_subvol_name;
}
OpenPOWER on IntegriCloud