diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-16 11:06:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-16 11:06:55 -0400 |
| commit | e64df3ebe8262c8203d1fe4f541e0241c3112c01 (patch) | |
| tree | 86511b00e8626a08089bb169fe5a64c542925762 | |
| parent | 53b95d6341c142a02538e41bdf1405ef8888bf8b (diff) | |
| parent | 8d875f95da43c6a8f18f77869f2ef26e9594fecc (diff) | |
Merge branch 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs updates from Chris Mason:
"These are all fixes I'd like to get out to a broader audience.
The biggest of the bunch is Mark's quota fix, which is also in the
SUSE kernel, and makes our subvolume quotas dramatically more
accurate.
I've been running xfstests with these against your current git
overnight, but I'm queueing up longer tests as well"
* 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
btrfs: disable strict file flushes for renames and truncates
Btrfs: fix csum tree corruption, duplicate and outdated checksums
Btrfs: Fix memory corruption by ulist_add_merge() on 32bit arch
Btrfs: fix compressed write corruption on enospc
btrfs: correctly handle return from ulist_add
btrfs: qgroup: account shared subtrees during snapshot delete
Btrfs: read lock extent buffer while walking backrefs
Btrfs: __btrfs_mod_ref should always use no_quota
btrfs: adjust statfs calculations according to raid profiles
| -rw-r--r-- | fs/btrfs/backref.c | 14 | ||||
| -rw-r--r-- | fs/btrfs/btrfs_inode.h | 6 | ||||
| -rw-r--r-- | fs/btrfs/ctree.c | 20 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 4 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 32 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 285 | ||||
| -rw-r--r-- | fs/btrfs/file-item.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 26 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 59 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.c | 123 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.h | 5 | ||||
| -rw-r--r-- | fs/btrfs/qgroup.c | 169 | ||||
| -rw-r--r-- | fs/btrfs/qgroup.h | 1 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 51 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 33 | ||||
| -rw-r--r-- | fs/btrfs/transaction.h | 1 | ||||
| -rw-r--r-- | fs/btrfs/ulist.h | 15 |
17 files changed, 541 insertions, 305 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index e25564bfcb46..54a201dac7f9 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
| @@ -276,9 +276,8 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
| 276 | } | 276 | } |
| 277 | if (ret > 0) | 277 | if (ret > 0) |
| 278 | goto next; | 278 | goto next; |
| 279 | ret = ulist_add_merge(parents, eb->start, | 279 | ret = ulist_add_merge_ptr(parents, eb->start, |
| 280 | (uintptr_t)eie, | 280 | eie, (void **)&old, GFP_NOFS); |
| 281 | (u64 *)&old, GFP_NOFS); | ||
| 282 | if (ret < 0) | 281 | if (ret < 0) |
| 283 | break; | 282 | break; |
| 284 | if (!ret && extent_item_pos) { | 283 | if (!ret && extent_item_pos) { |
| @@ -1001,16 +1000,19 @@ again: | |||
| 1001 | ret = -EIO; | 1000 | ret = -EIO; |
| 1002 | goto out; | 1001 | goto out; |
| 1003 | } | 1002 | } |
| 1003 | btrfs_tree_read_lock(eb); | ||
| 1004 | btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); | ||
| 1004 | ret = find_extent_in_eb(eb, bytenr, | 1005 | ret = find_extent_in_eb(eb, bytenr, |
| 1005 | *extent_item_pos, &eie); | 1006 | *extent_item_pos, &eie); |
| 1007 | btrfs_tree_read_unlock_blocking(eb); | ||
| 1006 | free_extent_buffer(eb); | 1008 | free_extent_buffer(eb); |
| 1007 | if (ret < 0) | 1009 | if (ret < 0) |
| 1008 | goto out; | 1010 | goto out; |
| 1009 | ref->inode_list = eie; | 1011 | ref->inode_list = eie; |
| 1010 | } | 1012 | } |
| 1011 | ret = ulist_add_merge(refs, ref->parent, | 1013 | ret = ulist_add_merge_ptr(refs, ref->parent, |
| 1012 | (uintptr_t)ref->inode_list, | 1014 | ref->inode_list, |
| 1013 | (u64 *)&eie, GFP_NOFS); | 1015 | (void **)&eie, GFP_NOFS); |
| 1014 | if (ret < 0) | 1016 | if (ret < 0) |
| 1015 | goto out; | 1017 | goto out; |
| 1016 | if (!ret && extent_item_pos) { | 1018 | if (!ret && extent_item_pos) { |
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 4794923c410c..43527fd78825 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
| @@ -84,12 +84,6 @@ struct btrfs_inode { | |||
| 84 | */ | 84 | */ |
| 85 | struct list_head delalloc_inodes; | 85 | struct list_head delalloc_inodes; |
| 86 | 86 | ||
| 87 | /* | ||
| 88 | * list for tracking inodes that must be sent to disk before a | ||
| 89 | * rename or truncate commit | ||
| 90 | */ | ||
| 91 | struct list_head ordered_operations; | ||
| 92 | |||
| 93 | /* node for the red-black tree that links inodes in subvolume root */ | 87 | /* node for the red-black tree that links inodes in subvolume root */ |
| 94 | struct rb_node rb_node; | 88 | struct rb_node rb_node; |
| 95 | 89 | ||
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index aeab453b8e24..44ee5d2e52a4 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -280,9 +280,9 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
| 280 | 280 | ||
| 281 | WARN_ON(btrfs_header_generation(buf) > trans->transid); | 281 | WARN_ON(btrfs_header_generation(buf) > trans->transid); |
| 282 | if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) | 282 | if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) |
| 283 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); | 283 | ret = btrfs_inc_ref(trans, root, cow, 1); |
| 284 | else | 284 | else |
| 285 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); | 285 | ret = btrfs_inc_ref(trans, root, cow, 0); |
| 286 | 286 | ||
| 287 | if (ret) | 287 | if (ret) |
| 288 | return ret; | 288 | return ret; |
| @@ -1035,14 +1035,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
| 1035 | if ((owner == root->root_key.objectid || | 1035 | if ((owner == root->root_key.objectid || |
| 1036 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && | 1036 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && |
| 1037 | !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { | 1037 | !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { |
| 1038 | ret = btrfs_inc_ref(trans, root, buf, 1, 1); | 1038 | ret = btrfs_inc_ref(trans, root, buf, 1); |
| 1039 | BUG_ON(ret); /* -ENOMEM */ | 1039 | BUG_ON(ret); /* -ENOMEM */ |
| 1040 | 1040 | ||
| 1041 | if (root->root_key.objectid == | 1041 | if (root->root_key.objectid == |
| 1042 | BTRFS_TREE_RELOC_OBJECTID) { | 1042 | BTRFS_TREE_RELOC_OBJECTID) { |
| 1043 | ret = btrfs_dec_ref(trans, root, buf, 0, 1); | 1043 | ret = btrfs_dec_ref(trans, root, buf, 0); |
| 1044 | BUG_ON(ret); /* -ENOMEM */ | 1044 | BUG_ON(ret); /* -ENOMEM */ |
| 1045 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); | 1045 | ret = btrfs_inc_ref(trans, root, cow, 1); |
| 1046 | BUG_ON(ret); /* -ENOMEM */ | 1046 | BUG_ON(ret); /* -ENOMEM */ |
| 1047 | } | 1047 | } |
| 1048 | new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; | 1048 | new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; |
| @@ -1050,9 +1050,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
| 1050 | 1050 | ||
| 1051 | if (root->root_key.objectid == | 1051 | if (root->root_key.objectid == |
| 1052 | BTRFS_TREE_RELOC_OBJECTID) | 1052 | BTRFS_TREE_RELOC_OBJECTID) |
| 1053 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); | 1053 | ret = btrfs_inc_ref(trans, root, cow, 1); |
| 1054 | else | 1054 | else |
| 1055 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); | 1055 | ret = btrfs_inc_ref(trans, root, cow, 0); |
| 1056 | BUG_ON(ret); /* -ENOMEM */ | 1056 | BUG_ON(ret); /* -ENOMEM */ |
| 1057 | } | 1057 | } |
| 1058 | if (new_flags != 0) { | 1058 | if (new_flags != 0) { |
| @@ -1069,11 +1069,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
| 1069 | if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { | 1069 | if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { |
| 1070 | if (root->root_key.objectid == | 1070 | if (root->root_key.objectid == |
| 1071 | BTRFS_TREE_RELOC_OBJECTID) | 1071 | BTRFS_TREE_RELOC_OBJECTID) |
| 1072 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); | 1072 | ret = btrfs_inc_ref(trans, root, cow, 1); |
| 1073 | else | 1073 | else |
| 1074 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); | 1074 | ret = btrfs_inc_ref(trans, root, cow, 0); |
| 1075 | BUG_ON(ret); /* -ENOMEM */ | 1075 | BUG_ON(ret); /* -ENOMEM */ |
| 1076 | ret = btrfs_dec_ref(trans, root, buf, 1, 1); | 1076 | ret = btrfs_dec_ref(trans, root, buf, 1); |
| 1077 | BUG_ON(ret); /* -ENOMEM */ | 1077 | BUG_ON(ret); /* -ENOMEM */ |
| 1078 | } | 1078 | } |
| 1079 | clean_tree_block(trans, root, buf); | 1079 | clean_tree_block(trans, root, buf); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index be91397f4e92..8e29b614fe93 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -3326,9 +3326,9 @@ int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes, | |||
| 3326 | u64 min_alloc_size, u64 empty_size, u64 hint_byte, | 3326 | u64 min_alloc_size, u64 empty_size, u64 hint_byte, |
| 3327 | struct btrfs_key *ins, int is_data, int delalloc); | 3327 | struct btrfs_key *ins, int is_data, int delalloc); |
| 3328 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3328 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
| 3329 | struct extent_buffer *buf, int full_backref, int no_quota); | 3329 | struct extent_buffer *buf, int full_backref); |
| 3330 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3330 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
| 3331 | struct extent_buffer *buf, int full_backref, int no_quota); | 3331 | struct extent_buffer *buf, int full_backref); |
| 3332 | int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, | 3332 | int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, |
| 3333 | struct btrfs_root *root, | 3333 | struct btrfs_root *root, |
| 3334 | u64 bytenr, u64 num_bytes, u64 flags, | 3334 | u64 bytenr, u64 num_bytes, u64 flags, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 08e65e9cf2aa..d0ed9e664f7d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -60,8 +60,6 @@ static void end_workqueue_fn(struct btrfs_work *work); | |||
| 60 | static void free_fs_root(struct btrfs_root *root); | 60 | static void free_fs_root(struct btrfs_root *root); |
| 61 | static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, | 61 | static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, |
| 62 | int read_only); | 62 | int read_only); |
| 63 | static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t, | ||
| 64 | struct btrfs_root *root); | ||
| 65< | |||
