diff options
| -rw-r--r-- | MAINTAINERS | 8 | ||||
| -rw-r--r-- | fs/btrfs/async-thread.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/compression.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/ctree.c | 21 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 23 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 104 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.h | 2 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 41 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.c | 93 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.h | 2 | ||||
| -rw-r--r-- | fs/btrfs/extent_map.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 25 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 6 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 350 | ||||
| -rw-r--r-- | fs/btrfs/volumes.c | 38 | ||||
| -rw-r--r-- | fs/btrfs/xattr.c | 14 |
20 files changed, 426 insertions, 318 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index d992d407197b..8a7b0b36e8b4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1021,6 +1021,14 @@ M: mb@bu3sch.de | |||
| 1021 | W: http://bu3sch.de/btgpio.php | 1021 | W: http://bu3sch.de/btgpio.php |
| 1022 | S: Maintained | 1022 | S: Maintained |
| 1023 | 1023 | ||
| 1024 | BTRFS FILE SYSTEM | ||
| 1025 | P: Chris Mason | ||
| 1026 | M: chris.mason@oracle.com | ||
| 1027 | L: linux-btrfs@vger.kernel.org | ||
| 1028 | W: http://btrfs.wiki.kernel.org/ | ||
| 1029 | T: git kernel.org:/pub/scm/linux/kernel/git/mason/btrfs-unstable.git | ||
| 1030 | S: Maintained | ||
| 1031 | |||
| 1024 | BTTV VIDEO4LINUX DRIVER | 1032 | BTTV VIDEO4LINUX DRIVER |
| 1025 | P: Mauro Carvalho Chehab | 1033 | P: Mauro Carvalho Chehab |
| 1026 | M: mchehab@infradead.org | 1034 | M: mchehab@infradead.org |
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index 8e2fec05dbe0..d5f4e94f2ca2 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/version.h> | ||
| 20 | #include <linux/kthread.h> | 19 | #include <linux/kthread.h> |
| 21 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 22 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index ee848d8585d9..ab07627084f1 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/swap.h> | 32 | #include <linux/swap.h> |
| 33 | #include <linux/writeback.h> | 33 | #include <linux/writeback.h> |
| 34 | #include <linux/bit_spinlock.h> | 34 | #include <linux/bit_spinlock.h> |
| 35 | #include <linux/version.h> | ||
| 36 | #include <linux/pagevec.h> | 35 | #include <linux/pagevec.h> |
| 37 | #include "compat.h" | 36 | #include "compat.h" |
| 38 | #include "ctree.h" | 37 | #include "ctree.h" |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 9e46c0776816..2603ee539b7a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -1210,8 +1210,7 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1210 | struct btrfs_disk_key disk_key; | 1210 | struct btrfs_disk_key disk_key; |
| 1211 | u32 nritems; | 1211 | u32 nritems; |
| 1212 | u64 search; | 1212 | u64 search; |
| 1213 | u64 lowest_read; | 1213 | u64 target; |
| 1214 | u64 highest_read; | ||
| 1215 | u64 nread = 0; | 1214 | u64 nread = 0; |
| 1216 | int direction = path->reada; | 1215 | int direction = path->reada; |
| 1217 | struct extent_buffer *eb; | 1216 | struct extent_buffer *eb; |
| @@ -1235,8 +1234,7 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1235 | return; | 1234 | return; |
| 1236 | } | 1235 | } |
| 1237 | 1236 | ||
| 1238 | highest_read = search; | 1237 | target = search; |
| 1239 | lowest_read = search; | ||
| 1240 | 1238 | ||
| 1241 | nritems = btrfs_header_nritems(node); | 1239 | nritems = btrfs_header_nritems(node); |
| 1242 | nr = slot; | 1240 | nr = slot; |
| @@ -1256,24 +1254,15 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1256 | break; | 1254 | break; |
| 1257 | } | 1255 | } |
| 1258 | search = btrfs_node_blockptr(node, nr); | 1256 | search = btrfs_node_blockptr(node, nr); |
| 1259 | if ((search >= lowest_read && search <= highest_read) || | 1257 | if ((search <= target && target - search <= 65536) || |
| 1260 | (search < lowest_read && lowest_read - search <= 16384) || | 1258 | (search > target && search - target <= 65536)) { |
| 1261 | (search > highest_read && search - highest_read <= 16384)) { | ||
| 1262 | readahead_tree_block(root, search, blocksize, | 1259 | readahead_tree_block(root, search, blocksize, |
| 1263 | btrfs_node_ptr_generation(node, nr)); | 1260 | btrfs_node_ptr_generation(node, nr)); |
| 1264 | nread += blocksize; | 1261 | nread += blocksize; |
| 1265 | } | 1262 | } |
| 1266 | nscan++; | 1263 | nscan++; |
| 1267 | if (path->reada < 2 && (nread > (64 * 1024) || nscan > 32)) | 1264 | if ((nread > 65536 || nscan > 32)) |
| 1268 | break; | 1265 | break; |
| 1269 | |||
| 1270 | if (nread > (256 * 1024) || nscan > 128) | ||
| 1271 | break; | ||
| 1272 | |||
| 1273 | if (search < lowest_read) | ||
| 1274 | lowest_read = search; | ||
| 1275 | if (search > highest_read) | ||
| 1276 | highest_read = search; | ||
| 1277 | } | 1266 | } |
| 1278 | } | 1267 | } |
| 1279 | 1268 | ||
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index eee060f88113..de103a8a815e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -454,17 +454,11 @@ struct btrfs_timespec { | |||
| 454 | __le32 nsec; | 454 | __le32 nsec; |
| 455 | } __attribute__ ((__packed__)); | 455 | } __attribute__ ((__packed__)); |
| 456 | 456 | ||
| 457 | typedef enum { | 457 | enum btrfs_compression_type { |
| 458 | BTRFS_COMPRESS_NONE = 0, | 458 | BTRFS_COMPRESS_NONE = 0, |
| 459 | BTRFS_COMPRESS_ZLIB = 1, | 459 | BTRFS_COMPRESS_ZLIB = 1, |
| 460 | BTRFS_COMPRESS_LAST = 2, | 460 | BTRFS_COMPRESS_LAST = 2, |
| 461 | } btrfs_compression_type; | 461 | }; |
| 462 | |||
| 463 | /* we don't understand any encryption methods right now */ | ||
| 464 | typedef enum { | ||
| 465 | BTRFS_ENCRYPTION_NONE = 0, | ||
| 466 | BTRFS_ENCRYPTION_LAST = 1, | ||
| 467 | } btrfs_encryption_type; | ||
| 468 | 462 | ||
| 469 | struct btrfs_inode_item { | 463 | struct btrfs_inode_item { |
| 470 | /* nfs style generation number */ | 464 | /* nfs style generation number */ |
| @@ -701,9 +695,7 @@ struct btrfs_fs_info { | |||
| 701 | struct btrfs_transaction *running_transaction; | 695 | struct btrfs_transaction *running_transaction; |
| 702 | wait_queue_head_t transaction_throttle; | 696 | wait_queue_head_t transaction_throttle; |
| 703 | wait_queue_head_t transaction_wait; | 697 | wait_queue_head_t transaction_wait; |
| 704 | |||
| 705 | wait_queue_head_t async_submit_wait; | 698 | wait_queue_head_t async_submit_wait; |
| 706 | wait_queue_head_t tree_log_wait; | ||
| 707 | 699 | ||
| 708 | struct btrfs_super_block super_copy; | 700 | struct btrfs_super_block super_copy; |
| 709 | struct btrfs_super_block super_for_commit; | 701 | struct btrfs_super_block super_for_commit; |
| @@ -730,10 +722,6 @@ struct btrfs_fs_info { | |||
| 730 | atomic_t async_submit_draining; | 722 | atomic_t async_submit_draining; |
| 731 | atomic_t nr_async_bios; | 723 | atomic_t nr_async_bios; |
| 732 | atomic_t async_delalloc_pages; | 724 | atomic_t async_delalloc_pages; |
| 733 | atomic_t tree_log_writers; | ||
| 734 | atomic_t tree_log_commit; | ||
| 735 | unsigned long tree_log_batch; | ||
| 736 | u64 tree_log_transid; | ||
| 737 | 725 | ||
| 738 | /* | 726 | /* |
| 739 | * this is used by the balancing code to wait for all the pending | 727 | * this is used by the balancing code to wait for all the pending |
| @@ -833,7 +821,14 @@ struct btrfs_root { | |||
| 833 | struct kobject root_kobj; | 821 | struct kobject root_kobj; |
| 834 | struct completion kobj_unregister; | 822 | struct completion kobj_unregister; |
| 835 | struct mutex objectid_mutex; | 823 | struct mutex objectid_mutex; |
| 824 | |||
| 836 | struct mutex log_mutex; | 825 | struct mutex log_mutex; |
| 826 | wait_queue_head_t log_writer_wait; | ||
| 827 | wait_queue_head_t log_commit_wait[2]; | ||
| 828 | atomic_t log_writers; | ||
| 829 | atomic_t log_commit[2]; | ||
| 830 | unsigned long log_transid; | ||
| 831 | unsigned long log_batch; | ||
| 837 | 832 | ||
| 838 | u64 objectid; | 833 | u64 objectid; |
| 839 | u64 last_trans; | 834 | u64 last_trans; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 81a313874ae5..7feac5a475e9 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/version.h> | ||
| 20 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
| 21 | #include <linux/blkdev.h> | 20 | #include <linux/blkdev.h> |
| 22 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
| @@ -850,6 +849,14 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 850 | spin_lock_init(&root->list_lock); | 849 | spin_lock_init(&root->list_lock); |
| 851 | mutex_init(&root->objectid_mutex); | 850 | mutex_init(&root->objectid_mutex); |
| 852 | mutex_init(&root->log_mutex); | 851 | mutex_init(&root->log_mutex); |
| 852 | init_waitqueue_head(&root->log_writer_wait); | ||
| 853 | init_waitqueue_head(&root->log_commit_wait[0]); | ||
| 854 | init_waitqueue_head(&root->log_commit_wait[1]); | ||
| 855 | atomic_set(&root->log_commit[0], 0); | ||
| 856 | atomic_set(&root->log_commit[1], 0); | ||
| 857 | atomic_set(&root->log_writers, 0); | ||
| 858 | root->log_batch = 0; | ||
| 859 | root->log_transid = 0; | ||
| 853 | extent_io_tree_init(&root->dirty_log_pages, | 860 | extent_io_tree_init(&root->dirty_log_pages, |
| 854 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 861 | fs_info->btree_inode->i_mapping, GFP_NOFS); |
| 855 | 862 | ||
| @@ -934,15 +941,16 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 934 | return 0; | 941 | return 0; |
| 935 | } | 942 | } |
| 936 | 943 | ||
| 937 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | 944 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, |
| 938 | struct btrfs_fs_info *fs_info) | 945 | struct btrfs_fs_info *fs_info) |
| 939 | { | 946 | { |
| 940 | struct btrfs_root *root; | 947 | struct btrfs_root *root; |
| 941 | struct btrfs_root *tree_root = fs_info->tree_root; | 948 | struct btrfs_root *tree_root = fs_info->tree_root; |
| 949 | struct extent_buffer *leaf; | ||
| 942 | 950 | ||
| 943 | root = kzalloc(sizeof(*root), GFP_NOFS); | 951 | root = kzalloc(sizeof(*root), GFP_NOFS); |
| 944 | if (!root) | 952 | if (!root) |
| 945 | return -ENOMEM; | 953 | return ERR_PTR(-ENOMEM); |
| 946 | 954 | ||
| 947 | __setup_root(tree_root->nodesize, tree_root->leafsize, | 955 | __setup_root(tree_root->nodesize, tree_root->leafsize, |
| 948 | tree_root->sectorsize, tree_root->stripesize, | 956 | tree_root->sectorsize, tree_root->stripesize, |
| @@ -951,12 +959,23 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 951 | root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; | 959 | root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; |
| 952 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; | 960 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; |
| 953 | root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; | 961 | root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; |
| 962 | /* | ||
| 963 | * log trees do not get reference counted because they go away | ||
| 964 | * before a real commit is actually done. They do store pointers | ||
| 965 | * to file data extents, and those reference counts still get | ||
| 966 | * updated (along with back refs to the log tree). | ||
| 967 | */ | ||
| 954 | root->ref_cows = 0; | 968 | root->ref_cows = 0; |
| 955 | 969 | ||
| 956 | root->node = btrfs_alloc_free_block(trans, root, root->leafsize, | 970 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
| 957 | 0, BTRFS_TREE_LOG_OBJECTID, | 971 | 0, BTRFS_TREE_LOG_OBJECTID, |
| 958 | trans->transid, 0, 0, 0); | 972 | trans->transid, 0, 0, 0); |
| 973 | if (IS_ERR(leaf)) { | ||
| 974 | kfree(root); | ||
| 975 | return ERR_CAST(leaf); | ||
| 976 | } | ||
| 959 | 977 | ||
| 978 | root->node = leaf; | ||
| 960 | btrfs_set_header_nritems(root->node, 0); | 979 | btrfs_set_header_nritems(root->node, 0); |
| 961 | btrfs_set_header_level(root->node, 0); | 980 | btrfs_set_header_level(root->node, 0); |
| 962 | btrfs_set_header_bytenr(root->node, root->node->start); | 981 | btrfs_set_header_bytenr(root->node, root->node->start); |
| @@ -968,7 +987,48 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 968 | BTRFS_FSID_SIZE); | 987 | BTRFS_FSID_SIZE); |
| 969 | btrfs_mark_buffer_dirty(root->node); | 988 | btrfs_mark_buffer_dirty(root->node); |
| 970 | btrfs_tree_unlock(root->node); | 989 | btrfs_tree_unlock(root->node); |
| 971 | fs_info->log_root_tree = root; | 990 | return root; |
| 991 | } | ||
| 992 | |||
| 993 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | ||
| 994 | struct btrfs_fs_info *fs_info) | ||
| 995 | { | ||
| 996 | struct btrfs_root *log_root; | ||
| 997 | |||
| 998 | log_root = alloc_log_tree(trans, fs_info); | ||
| 999 | if (IS_ERR(log_root)) | ||
| 1000 | return PTR_ERR(log_root); | ||
| 1001 | WARN_ON(fs_info->log_root_tree); | ||
| 1002 | fs_info->log_root_tree = log_root; | ||
| 1003 | return 0; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | ||
| 1007 | struct btrfs_root *root) | ||
| 1008 | { | ||
| 1009 | struct btrfs_root *log_root; | ||
| 1010 | struct btrfs_inode_item *inode_item; | ||
| 1011 | |||
| 1012 | log_root = alloc_log_tree(trans, root->fs_info); | ||
| 1013 | if (IS_ERR(log_root)) | ||
| 1014 | return PTR_ERR(log_root); | ||
| 1015 | |||
| 1016 | log_root->last_trans = trans->transid; | ||
| 1017 | log_root->root_key.offset = root->root_key.objectid; | ||
| 1018 | |||
| 1019 | inode_item = &log_root->root_item.inode; | ||
| 1020 | inode_item->generation = cpu_to_le64(1); | ||
| 1021 | inode_item->size = cpu_to_le64(3); | ||
| 1022 | inode_item->nlink = cpu_to_le32(1); | ||
| 1023 | inode_item->nbytes = cpu_to_le64(root->leafsize); | ||
| 1024 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | ||
| 1025 | |||
| 1026 | btrfs_set_root_bytenr(&log_root->root_item, log_root->node->start); | ||
| 1027 | btrfs_set_root_generation(&log_root->root_item, trans->transid); | ||
| 1028 | |||
| 1029 | WARN_ON(root->log_root); | ||
| 1030 | root->log_root = log_root; | ||
| 1031 | root->log_transid = 0; | ||
| 972 | return 0; | 1032 | return 0; |
| 973 | } | 1033 | } |
| 974 | 1034 | ||
| @@ -1136,7 +1196,6 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1136 | { | 1196 | { |
| 1137 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; | 1197 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; |
| 1138 | int ret = 0; | 1198 | int ret = 0; |
| 1139 | struct list_head *cur; | ||
| 1140 | struct btrfs_device *device; | 1199 | struct btrfs_device *device; |
| 1141 | struct backing_dev_info *bdi; | 1200 | struct backing_dev_info *bdi; |
| 1142 | #if 0 | 1201 | #if 0 |
| @@ -1144,8 +1203,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1144 | btrfs_congested_async(info, 0)) | 1203 | btrfs_congested_async(info, 0)) |
| 1145 | return 1; | 1204 | return 1; |
| 1146 | #endif | 1205 | #endif |
| 1147 | list_for_each(cur, &info->fs_devices->devices) { | 1206 | list_for_each_entry(device, &info->fs_devices->devices, dev_list) { |
| 1148 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1149 | if (!device->bdev) | 1207 | if (!device->bdev) |
| 1150 | continue; | 1208 | continue; |
| 1151 | bdi = blk_get_backing_dev_info(device->bdev); | 1209 | bdi = blk_get_backing_dev_info(device->bdev); |
| @@ -1163,13 +1221,11 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1163 | */ | 1221 | */ |
| 1164 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | 1222 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) |
| 1165 | { | 1223 | { |
| 1166 | struct list_head *cur; | ||
| 1167 | struct btrfs_device *device; | 1224 | struct btrfs_device *device; |
| 1168 | struct btrfs_fs_info *info; | 1225 | struct btrfs_fs_info *info; |
| 1169 | 1226 | ||
| 1170 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; | 1227 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; |
| 1171 | list_for_each(cur, &info->fs_devices->devices) { | 1228 | list_for_each_entry(device, &info->fs_devices->devices, dev_list) { |
| 1172 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1173 | if (!device->bdev) | 1229 | if (!device->bdev) |
| 1174 | continue; | 1230 | continue; |
| 1175 | 1231 | ||
| @@ -1535,10 +1591,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1535 | init_waitqueue_head(&fs_info->transaction_throttle); | 1591 | init_waitqueue_head(&fs_info->transaction_throttle); |
| 1536 | init_waitqueue_head(&fs_info->transaction_wait); | 1592 | init_waitqueue_head(&fs_info->transaction_wait); |
| 1537 | init_waitqueue_head(&fs_info->async_submit_wait); | 1593 | init_waitqueue_head(&fs_info->async_submit_wait); |
| 1538 | init_waitqueue_head(&fs_info->tree_log_wait); | ||
| 1539 | atomic_set(&fs_info->tree_log_commit, 0); | ||
| 1540 | atomic_set(&fs_info->tree_log_writers, 0); | ||
| 1541 | fs_info->tree_log_transid = 0; | ||
| 1542 | 1594 | ||
| 1543 | __setup_root(4096, 4096, 4096, 4096, tree_root, | 1595 | __setup_root(4096, 4096, 4096, 4096, tree_root, |
| 1544 | fs_info, BTRFS_ROOT_TREE_OBJECTID); | 1596 | fs_info, BTRFS_ROOT_TREE_OBJECTID); |
| @@ -1740,13 +1792,13 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1740 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; | 1792 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; |
| 1741 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, | 1793 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, |
| 1742 | "btrfs-cleaner"); | 1794 | "btrfs-cleaner"); |
| 1743 | if (!fs_info->cleaner_kthread) | 1795 | if (IS_ERR(fs_info->cleaner_kthread)) |
| 1744 | goto fail_csum_root; | 1796 | goto fail_csum_root; |
| 1745 | 1797 | ||
| 1746 | fs_info->transaction_kthread = kthread_run(transaction_kthread, | 1798 | fs_info->transaction_kthread = kthread_run(transaction_kthread, |
| 1747 | tree_root, | 1799 | tree_root, |
| 1748 | "btrfs-transaction"); | 1800 | "btrfs-transaction"); |
| 1749 | if (!fs_info->transaction_kthread) | 1801 | if (IS_ERR(fs_info->transaction_kthread)) |
| 1750 | goto fail_cleaner; | 1802 | goto fail_cleaner; |
| 1751 | 1803 | ||
| 1752 | if (btrfs_super_log_root(disk_super) != 0) { | 1804 | if (btrfs_super_log_root(disk_super) != 0) { |
| @@ -1828,13 +1880,14 @@ fail_sb_buffer: | |||
| 1828 | fail_iput: | 1880 | fail_iput: |
| 1829 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 1881 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
| 1830 | iput(fs_info->btree_inode); | 1882 | iput(fs_info->btree_inode); |
| 1831 | fail: | 1883 | |
| 1832 | btrfs_close_devices(fs_info->fs_devices); | 1884 | btrfs_close_devices(fs_info->fs_devices); |
| 1833 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 1885 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |
| 1886 | bdi_destroy(&fs_info->bdi); | ||
| 1834 | 1887 | ||
| 1888 | fail: | ||
| 1835 | kfree(extent_root); | 1889 | kfree(extent_root); |
| 1836 | kfree(tree_root); | 1890 | kfree(tree_root); |
| 1837 | bdi_destroy(&fs_info->bdi); | ||
| 1838 | kfree(fs_info); | 1891 | kfree(fs_info); |
| 1839 | kfree(chunk_root); | 1892 | kfree(chunk_root); |
| 1840 | kfree(dev_root); | 1893 | kfree(dev_root); |
| @@ -1995,7 +2048,6 @@ static int write_dev_supers(struct btrfs_device *device, | |||
| 1995 | 2048 | ||
| 1996 | int write_all_supers(struct btrfs_root *root, int max_mirrors) | 2049 | int write_all_supers(struct btrfs_root *root, int max_mirrors) |
| 1997 | { | 2050 | { |
| 1998 | struct list_head *cur; | ||
| 1999 | struct list_head *head = &root->fs_info->fs_devices->devices; | 2051 | struct list_head *head = &root->fs_info->fs_devices->devices; |
| 2000 | struct btrfs_device *dev; | 2052 | struct btrfs_device *dev; |
| 2001 | struct btrfs_super_block *sb; | 2053 | struct btrfs_super_block *sb; |
| @@ -2011,8 +2063,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
| 2011 | 2063 | ||
| 2012 | sb = &root->fs_info->super_for_commit; | 2064 | sb = &root->fs_info->super_for_commit; |
| 2013 | dev_item = &sb->dev_item; | 2065 | dev_item = &sb->dev_item; |
| 2014 | list_for_each(cur, head) { | 2066 | list_for_each_entry(dev, head, dev_list) { |
| 2015 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 2016 | if (!dev->bdev) { | 2067 | if (!dev->bdev) { |
| 2017 | total_errors++; | 2068 | total_errors++; |
| 2018 | continue; | 2069 | continue; |
| @@ -2045,8 +2096,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
| 2045 | } | 2096 | } |
| 2046 | 2097 | ||
| 2047 | total_errors = 0; | 2098 | total_errors = 0; |
| 2048 | list_for_each(cur, head) { | 2099 | list_for_each_entry(dev, head, dev_list) { |
| 2049 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 2050 | if (!dev->bdev) | 2100 | if (!dev->bdev) |
| 2051 | continue; | 2101 | continue; |
| 2052 | if (!dev->in_fs_metadata || !dev->writeable) | 2102 | if (!dev->in_fs_metadata || !dev->writeable) |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index c0ff404c31b7..494a56eb2986 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
| @@ -98,5 +98,7 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 98 | struct btrfs_fs_info *fs_info); | 98 | struct btrfs_fs_info *fs_info); |
| 99 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | 99 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, |
| 100 | struct btrfs_fs_info *fs_info); | 100 | struct btrfs_fs_info *fs_info); |
| 101 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | ||
| 102 | struct btrfs_root *root); | ||
| 101 | int btree_lock_page_hook(struct page *page); | 103 | int btree_lock_page_hook(struct page *page); |
| 102 | #endif | 104 | #endif |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 293da650873f..3b26f0980946 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/pagemap.h> | 19 | #include <linux/pagemap.h> |
| 20 | #include <linux/writeback.h> | 20 | #include <linux/writeback.h> |
| 21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
| 22 | #include <linux/version.h> | ||
| 23 | #include "compat.h" | 22 | #include "compat.h" |
| 24 | #include "hash.h" | 23 | #include "hash.h" |
| 25 | #include "crc32c.h" | 24 | #include "crc32c.h" |
| @@ -30,7 +29,6 @@ | |||
| 30 | #include "volumes.h" | 29 | #include "volumes.h" |
| 31 | #include "locking.h" | 30 | #include "locking.h" |
| 32 | #include "ref-cache.h" | 31 | #include "ref-cache.h" |
| 33 | #include "compat.h" | ||
| 34 | 32 | ||
| 35 | #define PENDING_EXTENT_INSERT 0 | 33 | #define PENDING_EXTENT_INSERT 0 |
| 36 | #define PENDING_EXTENT_DELETE 1 | 34 | #define PENDING_EXTENT_DELETE 1 |
| @@ -326,10 +324,8 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | |||
| 326 | u64 flags) | 324 | u64 flags) |
| 327 | { | 325 | { |
| 328 | struct list_head *head = &info->space_info; | 326 | struct list_head *head = &info->space_info; |
| 329 | struct list_head *cur; | ||
| 330 | struct btrfs_space_info *found; | 327 | struct btrfs_space_info *found; |
| 331 | list_for_each(cur, head) { | 328 | list_for_each_entry(found, head, list) { |
| 332 | found = list_entry(cur, struct btrfs_space_info, list); | ||
| 333 | if (found->flags == flags) | 329 | if (found->flags == flags) |
| 334 | return found; | 330 | return found; |
| 335 | } | 331 | } |
| @@ -2159,7 +2155,8 @@ again: | |||
| 2159 | ret = find_first_extent_bit(&info->extent_ins, search, &start, | 2155 | ret = find_first_extent_bit(&info->extent_ins, search, &start, |
| 2160 | &end, EXTENT_WRITEBACK); | 2156 | &end, EXTENT_WRITEBACK); |
| 2161 | if (ret) { | 2157 | if (ret) { |
| 2162 | if (skipped && all && !num_inserts) { | 2158 | if (skipped && all && !num_inserts && |
| 2159 | list_empty(&update_list)) { | ||
| 2163 | skipped = 0; | 2160 | skipped = 0; |
| 2164 | search = 0; | 2161 | search = 0; |
| 2165 | continue; | 2162 | continue; |
| @@ -2547,6 +2544,7 @@ again: | |||
| 2547 | if (ret) { | 2544 | if (ret) { |
| 2548 | if (all && skipped && !nr) { | 2545 | if (all && skipped && !nr) { |
| 2549 | search = 0; | 2546 | search = 0; |
| 2547 | skipped = 0; | ||
| 2550 | continue; | 2548 | continue; |
| 2551 | } | 2549 | } |
| 2552 | mutex_unlock(&info->extent_ins_mutex); | 2550 | mutex_unlock(&info->extent_ins_mutex); |
| @@ -2700,13 +2698,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
| 2700 | /* if metadata always pin */ | 2698 | /* if metadata always pin */ |
| 2701 | if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID) { | 2699 | if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID) { |
| 2702 | if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { | 2700 | if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { |
| 2703 | struct btrfs_block_group_cache *cache; | 2701 | mutex_lock(&root->fs_info->pinned_mutex); |
| 2704 | 2702 | btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); | |
| 2705 | /* btrfs_free_reserved_extent */ | 2703 | mutex_unlock(&root->fs_info->pinned_mutex); |
| 2706 | cache = btrfs_lookup_block_group(root->fs_info, bytenr); | ||
| 2707 | BUG_ON(!cache); | ||
| 2708 | btrfs_add_free_space(cache, bytenr, num_bytes); | ||
| 2709 | put_block_group(cache); | ||
| 2710 | update_reserved_extents(root, bytenr, num_bytes, 0); | 2704 | update_reserved_extents(root, bytenr, num_bytes, 0); |
| 2711 | return 0; | 2705 | return 0; |
| 2712 | } | 2706 | } |
| @@ -3014,7 +3008,6 @@ loop_check: | |||
| 3014 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes) | 3008 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes) |
| 3015 | { | 3009 | { |
| 3016 | struct btrfs_block_group_cache *cache; | 3010 | struct btrfs_block_group_cache *cache; |
| 3017 | struct list_head *l; | ||
| 3018 | 3011 | ||
| 3019 | printk(KERN_INFO "space_info has %llu free, is %sfull\n", | 3012 | printk(KERN_INFO "space_info has %llu free, is %sfull\n", |
| 3020 | (unsigned long long)(info->total_bytes - info->bytes_used - | 3013 | (unsigned long long)(info->total_bytes - info->bytes_used - |
| @@ -3022,8 +3015,7 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes) | |||
| 3022 | (info->full) ? "" : "not "); | 3015 | (info->full) ? "" : "not "); |
| 3023 | 3016 | ||
| 3024 | down_read(&info->groups_sem); | 3017 | down_read(&info->groups_sem); |
| 3025 | list_for_each(l, &info->block_groups) { | 3018 | list_for_each_entry(cache, &info->block_groups, list) { |
| 3026 | cache = list_entry(l, struct btrfs_block_group_cache, list); | ||
| 3027 | spin_lock(&cache->lock); | 3019 | spin_lock(&cache->lock); |
| 3028 | printk(KERN_INFO "block group %llu has %llu bytes, %llu used " | 3020 | printk(KERN_INFO "block group %llu has %llu bytes, %llu used " |
| 3029 | "%llu pinned %llu reserved\n", | 3021 | "%llu pinned %llu reserved\n", |
| @@ -4444,7 +4436,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, | |||
| 4444 | u64 lock_end = 0; | 4436 | u64 lock_end = 0; |
| 4445 | u64 num_bytes; | 4437 | u64 num_bytes; |
| 4446 | u64 ext_offset; | 4438 | u64 ext_offset; |
| 4447 | u64 first_pos; | 4439 | u64 search_end = (u64)-1; |
| 4448 | u32 nritems; | 4440 | u32 nritems; |
| 4449 | int nr_scaned = 0; | 4441 | int nr_scaned = 0; |
| 4450 | int extent_locked = 0; | 4442 | int extent_locked = 0; |
| @@ -4452,7 +4444,6 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, | |||
| 4452 | int ret; | 4444 | int ret; |
| 4453 | 4445 | ||
| 4454 | memcpy(&key, leaf_key, sizeof(key)); | 4446 | memcpy(&key, leaf_key, sizeof(key)); |
| 4455 | first_pos = INT_LIMIT(loff_t) - extent_key->offset; | ||
| 4456 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { | 4447 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { |
| 4457 | if (key.objectid < ref_path->owner_objectid || | 4448 | if (key.objectid < ref_path->owner_objectid || |
| 4458 | (key.objectid == ref_path->owner_objectid && | 4449 | (key.objectid == ref_path->owner_objectid && |
| @@ -4501,7 +4492,7 @@ next: | |||
| 4501 | if ((key.objectid > ref_path->owner_objectid) || | 4492 | if ((key.objectid > ref_path->owner_objectid) || |
| 4502 | (key.objectid == ref_path->owner_objectid && | 4493 | (key.objectid == ref_path->owner_objectid && |
| 4503 | key.type > BTRFS_EXTENT_DATA_KEY) || | 4494 | key.type > BTRFS_EXTENT_DATA_KEY) || |
| 4504 | (key.offset >= first_pos + extent_key->offset)) | 4495 | key.offset >= search_end) |
| 4505 | break; | 4496 | break; |
| 4506 | } | 4497 | } |
| 4507 | 4498 | ||
| @@ -4534,8 +4525,10 @@ next: | |||
| 4534 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); | 4525 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); |
| 4535 | ext_offset = btrfs_file_extent_offset(leaf, fi); | 4526 | ext_offset = btrfs_file_extent_offset(leaf, fi); |
| 4536 | 4527 | ||
| 4537 | if (first_pos > key.offset - ext_offset) | 4528 | if (search_end == (u64)-1) { |
| 4538 | first_pos = key.offset - ext_offset; | 4529 | search_end = key.offset - ext_offset + |
| 4530 | btrfs_file_extent_ram_bytes(leaf, fi); | ||
| 4531 | } | ||
| 4539 | 4532 | ||
| 4540 | if (!extent_locked) { | 4533 | if (!extent_locked) { |
| 4541 | lock_start = key.offset; | 4534 | lock_start = key.offset; |
| @@ -4724,7 +4717,7 @@ next: | |||
| 4724 | } | 4717 | } |
| 4725 | skip: | 4718 | skip: |
| 4726 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS && | 4719 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS && |
| 4727 | key.offset >= first_pos + extent_key->offset) | 4720 | key.offset >= search_end) |
| 4728 | break; | 4721 | break; |
| 4729 | 4722 | ||
| 4730 | cond_resched(); | 4723 | cond_resched(); |
| @@ -5957,9 +5950,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
| 5957 | path = btrfs_alloc_path(); | 5950 | path = btrfs_alloc_path(); |
| 5958 | BUG_ON(!path); | 5951 | BUG_ON(!path); |
| 5959 | 5952 | ||
| 5960 | btrfs_remove_free_space_cache(block_group); | 5953 | spin_lock(&root->fs_info->block_group_cache_lock); |
| 5961 | rb_erase(&block_group->cache_node, | 5954 | rb_erase(&block_group->cache_node, |
| 5962 | &root->fs_info->block_group_cache_tree); | 5955 | &root->fs_info->block_group_cache_tree); |
| 5956 | spin_unlock(&root->fs_info->block_group_cache_lock); | ||
| 5957 | btrfs_remove_free_space_cache(block_group); | ||
| 5963 | down_write(&block_group->space_info->groups_sem); | 5958 | down_write(&block_group->space_info->groups_sem); |
| 5964 | list_del(&block_group->list); | 5959 | list_del(&block_group->list); |
| 5965 | up_write(&block_group->space_info->groups_sem); | 5960 | up_write(&block_group->space_info->groups_sem); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index e086d407f1fa..a3b0676403f7 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | #include <linux/spinlock.h> | 9 | #include <linux/spinlock.h> |
| 10 | #include <linux/blkdev.h> | 10 | #include <linux/blkdev.h> |
| 11 | #include <linux/swap.h> | 11 | #include <linux/swap.h> |
| 12 | #include <linux/version.h> | ||
| 13 | #include <linux/writeback.h> | 12 | #include <linux/writeback.h> |
| 14 | #include <linux/pagevec.h> | 13 | #include <linux/pagevec.h> |
| 15 | #include "extent_io.h" | 14 | #include "extent_io.h" |
| @@ -2855,6 +2854,98 @@ out: | |||
| 2855 | return sector; | 2854 | return sector; |
| 2856 | } | 2855 | } |
| 2857 | 2856 | ||
| 2857 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
| 2858 | __u64 start, __u64 len, get_extent_t *get_extent) | ||
| 2859 | { | ||
| 2860 | int ret; | ||
| 2861 | u64 off = start; | ||
| 2862 | u64 max = start + len; | ||
| 2863 | u32 flags = 0; | ||
| 2864 | u64 disko = 0; | ||
| 2865 | struct extent_map *em = NULL; | ||
| 2866 | int end = 0; | ||
| 2867 | u64 em_start = 0, em_len = 0; | ||
| 2868 | unsigned long emflags; | ||
| 2869 | ret = 0; | ||
| 2870 | |||
| 2871 | if (len == 0) | ||
| 2872 | return -EINVAL; | ||
| 2873 | |||
| 2874 | lock_extent(&BTRFS_I(inode)->io_tree, start, start + len, | ||
| 2875 | GFP_NOFS); | ||
| 2876 | em = get_extent(inode, NULL, 0, off, max - off, 0); | ||
| 2877 | if (!em) | ||
| 2878 | goto out; | ||
| 2879 | if (IS_ERR(em)) { | ||
| 2880 | ret = PTR_ERR(em); | ||
| 2881 | goto out; | ||
| 2882 | } | ||
| 2883 | while (!end) { | ||
| 2884 | off = em->start + em->len; | ||
| 2885 | if (off >= max) | ||
| 2886 | end = 1; | ||
| 2887 | |||
| 2888 | em_start = em->start; | ||
| 2889 | em_len = em->len; | ||
| 2890 | |||
| 2891 | disko = 0; | ||
| 2892 | flags = 0; | ||
| 2893 | |||
| 2894 | switch (em->block_start) { | ||
| 2895 | case EXTENT_MAP_LAST_BYTE: | ||
| 2896 | end = 1; | ||
| 2897 | flags |= FIEMAP_EXTENT_LAST; | ||
| 2898 | break; | ||
| 2899 | case EXTENT_MAP_HOLE: | ||
| 2900 | flags |= FIEMAP_EXTENT_UNWRITTEN; | ||
| 2901 | break; | ||
| 2902 | case EXTENT_MAP_INLINE: | ||
| 2903 | flags |= (FIEMAP_EXTENT_DATA_INLINE | | ||
| 2904 | FIEMAP_EXTENT_NOT_ALIGNED); | ||
| 2905 | break; | ||
| 2906 | case EXTENT_MAP_DELALLOC: | ||
| 2907 | flags |= (FIEMAP_EXTENT_DELALLOC | | ||
| 2908 | FIEMAP_EXTENT_UNKNOWN); | ||
| 2909 | break; | ||
| 2910 | default: | ||
| 2911 | disko = em->block_start; | ||
| 2912 | break; | ||
| 2913 | } | ||
| 2914 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) | ||
| 2915 | flags |= FIEMAP_EXTENT_ENCODED; | ||
| 2916 | |||
| 2917 | emflags = em->flags; | ||
| 2918 | free_extent_map(em); | ||
| 2919 | em = NULL; | ||
| 2920 | |||
| 2921 | if (!end) { | ||
| 2922 | em = get_extent(inode, NULL, 0, off, max - off, 0); | ||
| 2923 | if (!em) | ||
| 2924 | goto out; | ||
| 2925 | if (IS_ERR(em)) { | ||
| 2926 | ret = PTR_ERR(em); | ||
| 2927 | goto out; | ||
| 2928 | } | ||
| 2929 | emflags = em->flags; | ||
| 2930 | } | ||
| 2931 | if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { | ||
| 2932 | flags |= FIEMAP_EXTENT_LAST; | ||
| 2933 | end = 1; | ||
| 2934 | } | ||
| 2935 | |||
| 2936 | ret = fiemap_fill_next_extent(fieinfo, em_start, disko, | ||
| 2937 | em_len, flags); | ||
| 2938 | if (ret) | ||
| 2939 | goto out_free; | ||
| 2940 | } | ||
| 2941 | out_free: | ||
| 2942 | free_extent_map(em); | ||
| 2943 | out: | ||
| 2944 | unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len, | ||
| 2945 | GFP_NOFS); | ||
| 2946 | return ret; | ||
| 2947 | } | ||
| 2948 | |||
| 2858 | static inline struct page *extent_buffer_page(struct extent_buffer *eb, | 2949 | static inline struct page *extent_buffer_page(struct extent_buffer *eb, |
| 2859 | unsigned long i) | 2950 | unsigned long i) |
| 2860 | { | 2951 | { |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index c5b483a79137..e80c6d96b318 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
| @@ -193,6 +193,8 @@ int extent_commit_write(struct extent_io_tree *tree, | |||
| 193 | unsigned from, unsigned to); | 193 | unsigned from, unsigned to); |
| 194 | sector_t extent_bmap(struct address_space *mapping, sector_t iblock, | 194 | sector_t extent_bmap(struct address_space *mapping, sector_t iblock, |
| 195 | get_extent_t *get_extent); | 195 | get_extent_t *get_extent); |
| 196 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
| 197 | __u64 start, __u64 len, get_extent_t *get_extent); | ||
| 196 | int set_range_dirty(struct extent_io_tree *tree, u64 start, u64 end); | 198 | int set_range_dirty(struct extent_io_tree *tree, u64 start, u64 end); |
| 197 | int set_state_private(struct extent_io_tree *tree, u64 start, u64 private); | 199 | int set_state_private(struct extent_io_tree *tree, u64 start, u64 private); |
| 198 | int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); | 200 | int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 4a83e33ada32..50da69da20ce 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | #include <linux/slab.h> | 3 | #include <linux/slab.h> |
| 4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
| 6 | #include <linux/version.h> | ||
| 7 | #include <linux/hardirq.h> | 6 | #include <linux/hardirq.h> |
| 8 | #include "extent_map.h" | 7 | #include "extent_map.h" |
| 9 | 8 | ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 90268334145e..3e8023efaff7 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <linux/writeback.h> | 29 | #include <linux/writeback.h> |
| 30 | #include <linux/statfs.h> | 30 | #include <linux/statfs.h> |
| 31 | #include <linux/compat.h> | 31 | #include <linux/compat.h> |
| 32 | #include <linux/version.h> | ||
| 33 | #include "ctree.h" | 32 | #include "ctree.h" |
| 34 | #include "disk-io.h" | 33 | #include "disk-io.h" |
| 35 | #include "transaction.h" | 34 | #include "transaction.h" |
| @@ -1215,10 +1214,10 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1215 | } | 1214 | } |
| 1216 | mutex_unlock(&root->fs_info->trans_mutex); | 1215 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1217 | 1216 | ||
| 1218 | root->fs_info->tree_log_batch++; | 1217 | root->log_batch++; |
| 1219 | filemap_fdatawrite(inode->i_mapping); | 1218 | filemap_fdatawrite(inode->i_mapping); |
| 1220 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 1219 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
| 1221 | root->fs_info->tree_log_batch++; | 1220 | root->log_batch++; |
| 1222 | 1221 | ||
| 1223 | /* | 1222 | /* |
| 1224 | * ok we haven't committed the transaction yet, lets do a commit | 1223 | * ok we haven't committed the transaction yet, lets do a commit |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8adfe059ab41..288c2cdc7543 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <linux/statfs.h> | 34 | #include <linux/statfs.h> |
| 35 | #include <linux/compat.h> | 35 | #include <linux/compat.h> |
| 36 | #include <linux/bit_spinlock.h> | 36 | #include <linux/bit_spinlock.h> |
| 37 | #include <linux/version.h> | ||
| 38 | #include <linux/xattr.h> | 37 | #include <linux/xattr.h> |
| 39 | #include <linux/posix_acl.h> | 38 | #include <linux/posix_acl.h> |
| 40 | #include <linux/falloc.h> | 39 | #include <linux/falloc.h> |
| @@ -1324,12 +1323,11 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, | |||
| 1324 | struct inode *inode, u64 file_offset, | 1323 | struct inode *inode, u64 file_offset, |
| 1325 | struct list_head *list) | 1324 | struct list_head *list) |
| 1326 | { | 1325 | { |
| 1327 | struct list_head *cur; | ||
| 1328 | struct btrfs_ordered_sum *sum; | 1326 | struct btrfs_ordered_sum *sum; |
| 1329 | 1327 | ||
| 1330 | btrfs_set_trans_block_group(trans, inode); | 1328 | btrfs_set_trans_block_group(trans, inode); |
| 1331 | list_for_each(cur, list) { | 1329 | |
| 1332 | sum = list_entry(cur, struct btrfs_ordered_sum, list); | 1330 | list_for_each_entry(sum, list, list) { |
| 1333 | btrfs_csum_file_blocks(trans, | 1331 | btrfs_csum_file_blocks(trans, |
| 1334 | BTRFS_I(inode)->root->fs_info->csum_root, sum); | 1332 | BTRFS_I(inode)->root->fs_info->csum_root, sum); |
| 1335 | } | 1333 | } |
| @@ -4158,9 +4156,10 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
| 4158 | return -EINVAL; | 4156 | return -EINVAL; |
| 4159 | } | 4157 | } |
| 4160 | 4158 | ||
| 4161 | static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock) | 4159 | static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
| 4160 | __u64 start, __u64 len) | ||
| 4162 | { | 4161 | { |
| 4163 | return extent_bmap(mapping, iblock, btrfs_get_extent); | 4162 | return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent); |
| 4164 | } | 4163 | } |
| 4165 | 4164 | ||
| 4166 | int btrfs_readpage(struct file *file, struct page *page) | 4165 | int btrfs_readpage(struct file *file, struct page *page) |
| @@ -4987,13 +4986,24 @@ static struct extent_io_ops btrfs_extent_io_ops = { | |||
| 4987 | .clear_bit_hook = btrfs_clear_bit_hook, | 4986 | .clear_bit_hook = btrfs_clear_bit_hook, |
| 4988 | }; | 4987 | }; |
| 4989 | 4988 | ||
| 4989 | /* | ||
| 4990 | * btrfs doesn't support the bmap operation because swapfiles | ||
| 4991 | * use bmap to make a mapping of extents in the file. They assume | ||
| 4992 | * these extents won't change over the life of the file and they | ||
| 4993 | * use the bmap result to do IO directly to the drive. | ||
| 4994 | * | ||
| 4995 | * the btrfs bmap call would return logical addresses that aren't | ||
| 4996 | * suitable for IO and they also will change frequently as COW | ||
| 4997 | * operations happen. So, swapfile + btrfs == corruption. | ||
| 4998 | * | ||
| 4999 | * For now we're avoiding this by dropping bmap. | ||
| 5000 | */ | ||
| 4990 | static struct address_space_operations btrfs_aops = { | 5001 | static struct address_space_operations btrfs_aops = { |
| 4991 | .readpage = btrfs_readpage, | 5002 | .readpage = btrfs_readpage, |
| 4992 | .writepage = btrfs_writepage, | 5003 | .writepage = btrfs_writepage, |
| 4993 | .writepages = btrfs_writepages, | 5004 | .writepages = btrfs_writepages, |
| 4994 | .readpages = btrfs_readpages, | 5005 | .readpages = btrfs_readpages, |
| 4995 | .sync_page = block_sync_page, | 5006 | .sync_page = block_sync_page, |
| 4996 | .bmap = btrfs_bmap, | ||
| 4997 | .direct_IO = btrfs_direct_IO, | 5007 | .direct_IO = btrfs_direct_IO, |
| 4998 | .invalidatepage = btrfs_invalidatepage, | 5008 | .invalidatepage = btrfs_invalidatepage, |
| 4999 | .releasepage = btrfs_releasepage, | 5009 | .releasepage = btrfs_releasepage, |
| @@ -5017,6 +5027,7 @@ static struct inode_operations btrfs_file_inode_operations = { | |||
| 5017 | .removexattr = btrfs_removexattr, | 5027 | .removexattr = btrfs_removexattr, |
| 5018 | .permission = btrfs_permission, | 5028 | .permission = btrfs_permission, |
| 5019 | .fallocate = btrfs_fallocate, | 5029 | .fallocate = btrfs_fallocate, |
| 5030 | .fiemap = btrfs_fiemap, | ||
| 5020 | }; | 5031 | }; |
| 5021 | static struct inode_operations btrfs_special_inode_operations = { | 5032 | static struct inode_operations btrfs_special_inode_operations = { |
| 5022 | .getattr = btrfs_getattr, | 5033 | .getattr = btrfs_getattr, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index c2aa33e3feb5..988fdc8b49eb 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <linux/compat.h> | 38 | #include <linux/compat.h> |
| 39 | #include <linux/bit_spinlock.h> | 39 | #include <linux/bit_spinlock.h> |
| 40 | #include <linux/security.h> | 40 | #include <linux/security.h> |
| 41 | #include <linux/version.h> | ||
| 42 | #include <linux/xattr.h> | 41 | #include <linux/xattr.h> |
| 43 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
| 44 | #include "compat.h" | 43 | #include "compat.h" |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index a20940170274..77c2411a5f0f 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
| @@ -613,7 +613,6 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | |||
| 613 | struct btrfs_sector_sum *sector_sums; | 613 | struct btrfs_sector_sum *sector_sums; |
| 614 | struct btrfs_ordered_extent *ordered; | 614 | struct btrfs_ordered_extent *ordered; |
| 615 | struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; | 615 | struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; |
| 616 | struct list_head *cur; | ||
| 617 | unsigned long num_sectors; | 616 | unsigned long num_sectors; |
| 618 | unsigned long i; | 617 | unsigned long i; |
| 619 | u32 sectorsize = BTRFS_I(inode)->root->sectorsize; | 618 | u32 sectorsize = BTRFS_I(inode)->root->sectorsize; |
| @@ -624,8 +623,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | |||
| 624 | return 1; | 623 | return 1; |
| 625 | 624 | ||
| 626 | mutex_lock(&tree->mutex); | 625 | mutex_lock(&tree->mutex); |
| 627 | list_for_each_prev(cur, &ordered->list) { | 626 | list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { |
| 628 | ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list); | ||
| 629 | if (disk_bytenr >= ordered_sum->bytenr) { | 627 | if (disk_bytenr >= ordered_sum->bytenr) { |
| 630 | num_sectors = ordered_sum->len / sectorsize; | 628 | num_sectors = ordered_sum->len / sectorsize; |
| 631 | sector_sums = ordered_sum->sums; | 629 | sector_sums = ordered_sum->sums; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index db9fb3bc1e33..f3fd7e2cbc38 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <linux/ctype.h> | 37 | #include <linux/ctype.h> |
| 38 | #include <linux/namei.h> | 38 | #include <linux/namei.h> |
| 39 | #include <linux/miscdevice.h> | 39 | #include <linux/miscdevice.h> |
| 40 | #include <linux/version.h> | ||
| 41 | #include <linux/magic.h> | 40 | #include <linux/magic.h> |
| 42 | #include "compat.h" | 41 | #include "compat.h" |
| 43 | #include "ctree.h" | 42 | #include "ctree.h" |
| @@ -583,17 +582,18 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | |||
| 583 | struct btrfs_ioctl_vol_args *vol; | 582 | struct btrfs_ioctl_vol_args *vol; |
| 584 | struct btrfs_fs_devices *fs_devices; | 583 | struct btrfs_fs_devices *fs_devices; |
| 585 | int ret = -ENOTTY; | 584 | int ret = -ENOTTY; |
| 586 | int len; | ||
| 587 | 585 | ||
| 588 | if (!capable(CAP_SYS_ADMIN)) | 586 | if (!capable(CAP_SYS_ADMIN)) |
| 589 | return -EPERM; | 587 | return -EPERM; |
| 590 | 588 | ||
| 591 | vol = kmalloc(sizeof(*vol), GFP_KERNEL); | 589 | vol = kmalloc(sizeof(*vol), GFP_KERNEL); |
| 590 | if (!vol) | ||
| 591 | return -ENOMEM; | ||
| 592 | |||
| 592 | if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { | 593 | if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { |
| 593 | ret = -EFAULT; | 594 | ret = -EFAULT; |
| 594 | goto out; | 595 | goto out; |
| 595 | } | 596 | } |
| 596 | len = strnlen(vol->name, BTRFS_PATH_NAME_MAX); | ||
| 597 | 597 | ||
| 598 | switch (cmd) { | 598 | switch (cmd) { |
| 599 | case BTRFS_IOC_SCAN_DEV: | 599 | case BTRFS_IOC_SCAN_DEV: |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 8a08f9443340..919172de5c9a 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -852,11 +852,9 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, | |||
| 852 | { | 852 | { |
| 853 | struct btrfs_pending_snapshot *pending; | 853 | struct btrfs_pending_snapshot *pending; |
| 854 | struct list_head *head = &trans->transaction->pending_snapshots; | 854 | struct list_head *head = &trans->transaction->pending_snapshots; |
| 855 | struct list_head *cur; | ||
| 856 | int ret; | 855 | int ret; |
| 857 | 856 | ||
| 858 | list_for_each(cur, head) { | 857 | list_for_each_entry(pending, head, list) { |
| 859 | pending = list_entry(cur, struct btrfs_pending_snapshot, list); | ||
| 860 | ret = create_pending_snapshot(trans, fs_info, pending); | 858 | ret = create_pending_snapshot(trans, fs_info, pending); |
| 861 | BUG_ON(ret); | 859 | BUG_ON(ret); |
| 862 | } | 860 | } |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index d81cda2e077c..4f26f3ed0c87 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -78,104 +78,6 @@ static int link_to_fixup_dir(struct btrfs_trans_handle *trans, | |||
| 78 | */ | 78 | */ |
| 79 | 79 | ||
| 80 | /* | 80 | /* |
| 81 | * btrfs_add_log_tree adds a new per-subvolume log tree into the | ||
| 82 | * tree of log tree roots. This must be called with a tree log transaction | ||
| 83 | * running (see start_log_trans). | ||
| 84 | */ | ||
| 85 | static int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | ||
| 86 | struct btrfs_root *root) | ||
| 87 | { | ||
| 88 | struct btrfs_key key; | ||
| 89 | struct btrfs_root_item root_item; | ||
| 90 | struct btrfs_inode_item *inode_item; | ||
| 91 | struct extent_buffer *leaf; | ||
| 92 | struct btrfs_root *new_root = root; | ||
| 93 | int ret; | ||
| 94 | u64 objectid = root->root_key.objectid; | ||
| 95 | |||
| 96 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, | ||
| 97 | BTRFS_TREE_LOG_OBJECTID, | ||
| 98 | trans->transid, 0, 0, 0); | ||
| 99 | if (IS_ERR(leaf)) { | ||
| 100 | ret = PTR_ERR(leaf); | ||
| 101 | return ret; | ||
| 102 | } | ||
| 103 | |||
| 104 | btrfs_set_header_nritems(leaf, 0); | ||
| 105 | btrfs_set_header_level(leaf, 0); | ||
| 106 | btrfs_set_header_bytenr(leaf, leaf->start); | ||
| 107 | btrfs_set_header_generation(leaf, trans->transid); | ||
| 108 | btrfs_set_header_owner(leaf, BTRFS_TREE_LOG_OBJECTID); | ||
| 109 | |||
| 110 | write_extent_buffer(leaf, root->fs_info->fsid, | ||
| 111 | (unsigned long)btrfs_header_fsid(leaf), | ||
| 112 | BTRFS_FSID_SIZE); | ||
| 113 | btrfs_mark_buffer_dirty(leaf); | ||
| 114 | |||
| 115 | inode_item = &root_item.inode; | ||
| 116 | memset(inode_item, 0, sizeof(*inode_item)); | ||
| 117 | inode_item->generation = cpu_to_le64(1); | ||
| 118 | inode_item->size = cpu_to_le64(3); | ||
| 119 | inode_item->nlink = cpu_to_le32(1); | ||
| 120 | inode_item->nbytes = cpu_to_le64(root->leafsize); | ||
| 121 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | ||
| 122 | |||
| 123 | btrfs_set_root_bytenr(&root_item, leaf->start); | ||
| 124 | btrfs_set_root_generation(&root_item, trans->transid); | ||
| 125 | btrfs_set_root_level(&root_item, 0); | ||
| 126 | btrfs_set_root_refs(&root_item, 0); | ||
| 127 | btrfs_set_root_used(&root_item, 0); | ||
| 128 | |||
| 129 | memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); | ||
| 130 | root_item.drop_level = 0; | ||
| 131 | |||
| 132 | btrfs_tree_unlock(leaf); | ||
| 133 | free_extent_buffer(leaf); | ||
| 134 | leaf = NULL; | ||
| 135 | |||
| 136 | btrfs_set_root_dirid(&root_item, 0); | ||
| 137 | |||
| 138 | key.objectid = BTRFS_TREE_LOG_OBJECTID; | ||
| 139 | key.offset = objectid; | ||
| 140 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | ||
| 141 | ret = btrfs_insert_root(trans, root->fs_info->log_root_tree, &key, | ||
| 142 | &root_item); | ||
| 143 | if (ret) | ||
| 144 | goto fail; | ||
| 145 | |||
| 146 | new_root = btrfs_read_fs_root_no_radix(root->fs_info->log_root_tree, | ||
| 147 | &key); | ||
| 148 | BUG_ON(!new_root); | ||
| 149 | |||
| 150 | WARN_ON(root->log_root); | ||
| 151 | root->log_root = new_root; | ||
| 152 | |||
| 153 | /* | ||
| 154 | * log trees do not get reference counted because they go away | ||
| 155 | * before a real commit is actually done. They do store pointers | ||
| 156 | * to file data extents, and those reference counts still get | ||
| 157 | * updated (along with back refs to the log tree). | ||
| 158 | */ | ||
| 159 | new_root->ref_cows = 0; | ||
| 160 | new_root->last_trans = trans->transid; | ||
| 161 | |||
| 162 | /* | ||
| 163 | * we need to make sure the root block for this new tree | ||
| 164 | * is marked as dirty in the dirty_log_pages tree. This | ||
| 165 | * is how it gets flushed down to disk at tree log commit time. | ||
| 166 | * | ||
| 167 | * the tree logging mutex keeps others from coming in and changing | ||
| 168 | * the new_root->node, so we can safely access it here | ||
| 169 | */ | ||
| 170 | set_extent_dirty(&new_root->dirty_log_pages, new_root->node->start, | ||
| 171 | new_root->node->start + new_root->node->len - 1, | ||
| 172 | GFP_NOFS); | ||
| 173 | |||
| 174 | fail: | ||
| 175 | return ret; | ||
| 176 | } | ||
| 177 | |||
| 178 | /* | ||
| 179 | * start a sub transaction and setup the log tree | 81 | * start a sub transaction and setup the log tree |
| 180 | * this increments the log tree writer count to make the people | 82 | * this increments the log tree writer count to make the people |
| 181 | * syncing the tree wait for us to finish | 83 | * syncing the tree wait for us to finish |
| @@ -184,6 +86,14 @@ static int start_log_trans(struct btrfs_trans_handle *trans, | |||
| 184 | struct btrfs_root *root) | 86 | struct btrfs_root *root) |
| 185 | { | 87 | { |
| 186 | int ret; | 88 | int ret; |
| 89 | |||
| 90 | mutex_lock(&root->log_mutex); | ||
| 91 | if (root->log_root) { | ||
| 92 | root->log_batch++; | ||
| 93 | atomic_inc(&root->log_writers); | ||
| 94 | mutex_unlock(&root->log_mutex); | ||
| 95 | return 0; | ||
| 96 | } | ||
| 187 | mutex_lock(&root->fs_info->tree_log_mutex); | 97 | mutex_lock(&root->fs_info->tree_log_mutex); |
| 188 | if (!root->fs_info->log_root_tree) { | 98 | if (!root->fs_info->log_root_tree) { |
| 189 | ret = btrfs_init_log_root_tree(trans, root->fs_info); | 99 | ret = btrfs_init_log_root_tree(trans, root->fs_info); |
| @@ -193,9 +103,10 @@ static int start_log_trans(struct btrfs_trans_handle *trans, | |||
| 193 | ret = btrfs_add_log_tree(trans, root); | 103 | ret = btrfs_add_log_tree(trans, root); |
| 194 | BUG_ON(ret); | 104 | BUG_ON(ret); |
| 195 | } | 105 | } |
| 196 | atomic_inc(&root->fs_info->tree_log_writers); | ||
| 197 | root->fs_info->tree_log_batch++; | ||
| 198 | mutex_unlock(&root->fs_info->tree_log_mutex); | 106 | mutex_unlock(&root->fs_info->tree_log_mutex); |
| 107 | root->log_batch++; | ||
| 108 | atomic_inc(&root->log_writers); | ||
| 109 | mutex_unlock(&root->log_mutex); | ||
| 199 | return 0; | 110 | return 0; |
| 200 | } | 111 | } |
| 201 | 112 | ||
| @@ -212,13 +123,12 @@ static int join_running_log_trans(struct btrfs_root *root) | |||
| 212 | if (!root->log_root) | 123 | if (!root->log_root) |
| 213 | return -ENOENT; | 124 | return -ENOENT; |
| 214 | 125 | ||
| 215 | mutex_lock(&root->fs_info->tree_log_mutex); | 126 | mutex_lock(&root->log_mutex); |
| 216 | if (root->log_root) { | 127 | if (root->log_root) { |
| 217 | ret = 0; | 128 | ret = 0; |
| 218 | atomic_inc(&root->fs_info->tree_log_writers); | 129 | atomic_inc(&root->log_writers); |
| 219 | root->fs_info->tree_log_batch++; | ||
| 220 | } | 130 | } |
| 221 | mutex_unlock(&root->fs_info->tree_log_mutex); | 131 | mutex_unlock(&root->log_mutex); |
| 222 | return ret; | 132 | return ret; |
| 223 | } | 133 | } |
| 224 | 134 | ||
| @@ -228,10 +138,11 @@ static int join_running_log_trans(struct btrfs_root *root) | |||
| 228 | */ | 138 | */ |
| 229 | static int end_log_trans(struct btrfs_root *root) | 139 | static int end_log_trans(struct btrfs_root *root) |
| 230 | { | 140 | { |
| 231 | atomic_dec(&root->fs_info->tree_log_writers); | 141 | if (atomic_dec_and_test(&root->log_writers)) { |
| 232 | smp_mb(); | 142 | smp_mb(); |
| 233 | if (waitqueue_active(&root->fs_info->tree_log_wait)) | 143 | if (waitqueue_active(&root->log_writer_wait)) |
| 234 | wake_up(&root->fs_info->tree_log_wait); | 144 | wake_up(&root->log_writer_wait); |
| 145 | } | ||
| 235 | return 0; | 146 | return 0; |
| 236 | } | 147 | } |
| 237 | 148 | ||
| @@ -1902,26 +1813,65 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, | |||
| 1902 | } | 1813 | } |
| 1903 | } | 1814 | } |
| 1904 | btrfs_free_path(path); | 1815 | btrfs_free_path(path); |
| 1905 | if (wc->free) | ||
| 1906 | free_extent_buffer(log->node); | ||
| 1907 | return ret; | 1816 | return ret; |
| 1908 | } | 1817 | } |
| 1909 | 1818 | ||
| 1910 | static int wait_log_commit(struct btrfs_root *log) | 1819 | /* |
| 1820 | * helper function to update the item for a given subvolumes log root | ||
| 1821 | * in the tree of log roots | ||
| 1822 | */ | ||
| 1823 | static int update_log_root(struct btrfs_trans_handle *trans, | ||
| 1824 | struct btrfs_root *log) | ||
| 1825 | { | ||
| 1826 | int ret; | ||
| 1827 | |||
| 1828 | if (log->log_transid == 1) { | ||
| 1829 | /* insert root item on the first sync */ | ||
| 1830 | ret = btrfs_insert_root(trans, log->fs_info->log_root_tree, | ||
| 1831 | &log->root_key, &log->root_item); | ||
| 1832 | } else { | ||
| 1833 | ret = btrfs_update_root(trans, log->fs_info->log_root_tree, | ||
| 1834 | &log->root_key, &log->root_item); | ||
| 1835 | } | ||
| 1836 | return ret; | ||
| 1837 | } | ||
| 1838 | |||
| 1839 | static int wait_log_commit(struct btrfs_root *root, unsigned long transid) | ||
| 1911 | { | 1840 | { |
| 1912 | DEFINE_WAIT(wait); | 1841 | DEFINE_WAIT(wait); |
| 1913 | u64 transid = log->fs_info->tree_log_transid; | 1842 | int index = transid % 2; |
| 1914 | 1843 | ||
| 1844 | /* | ||
| 1845 | * we only allow two pending log transactions at a time, | ||
| 1846 | * so we know that if ours is more than 2 older than the | ||
| 1847 | * current transaction, we're done | ||
| 1848 | */ | ||
| 1915 | do { | 1849 | do { |
| 1916 | prepare_to_wait(&log->fs_info->tree_log_wait, &wait, | 1850 | prepare_to_wait(&root->log_commit_wait[index], |
| 1917 | TASK_UNINTERRUPTIBLE); | 1851 | &wait, TASK_UNINTERRUPTIBLE); |
| 1918 | mutex_unlock(&log->fs_info->tree_log_mutex); | 1852 | mutex_unlock(&root->log_mutex); |
| 1919 | if (atomic_read(&log->fs_info->tree_log_commit)) | 1853 | if (root->log_transid < transid + 2 && |
| 1854 | atomic_read(&root->log_commit[index])) | ||
| 1920 | schedule(); | 1855 | schedule(); |
| 1921 | finish_wait(&log->fs_info->tree_log_wait, &wait); | 1856 | finish_wait(&root->log_commit_wait[index], &wait); |
| 1922 | mutex_lock(&log->fs_info->tree_log_mutex); | 1857 | mutex_lock(&root->log_mutex); |
| 1923 | } while (transid == log->fs_info->tree_log_transid && | 1858 | } while (root->log_transid < transid + 2 && |
| 1924 | atomic_read(&log->fs_info->tree_log_commit)); | 1859 | atomic_read(&root->log_commit[index])); |
| 1860 | return 0; | ||
| 1861 | } | ||
| 1862 | |||
| 1863 | static int wait_for_writer(struct btrfs_root *root) | ||
| 1864 | { | ||
| 1865 | DEFINE_WAIT(wait); | ||
| 1866 | while (atomic_read(&root->log_writers)) { | ||
| 1867 | prepare_to_wait(&root->log_writer_wait, | ||
| 1868 | &wait, TASK_UNINTERRUPTIBLE); | ||
| 1869 | mutex_unlock(&root->log_mutex); | ||
| 1870 | if (atomic_read(&root->log_writers)) | ||
| 1871 | schedule(); | ||
| 1872 | mutex_lock(&root->log_mutex); | ||
| 1873 | finish_wait(&root->log_writer_wait, &wait); | ||
| 1874 | } | ||
| 1925 | return 0; | 1875 | return 0; |
| 1926 | } | 1876 | } |
| 1927 | 1877 | ||
| @@ -1933,57 +1883,114 @@ static int wait_log_commit(struct btrfs_root *log) | |||
| 1933 | int btrfs_sync_log(struct btrfs_trans_handle *trans, | 1883 | int btrfs_sync_log(struct btrfs_trans_handle *trans, |
| 1934 | struct btrfs_root *root) | 1884 | struct btrfs_root *root) |
| 1935 | { | 1885 | { |
| 1886 | int index1; | ||
| 1887 | int index2; | ||
| 1936 | int ret; | 1888 | int ret; |
| 1937 | unsigned long batch; | ||
| 1938 | struct btrfs_root *log = root->log_root; | 1889 | struct btrfs_root *log = root->log_root; |
| 1890 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; | ||
| 1939 | 1891 | ||
| 1940 | mutex_lock(&log->fs_info->tree_log_mutex); | 1892 | mutex_lock(&root->log_mutex); |
| 1941 | if (atomic_read(&log->fs_info->tree_log_commit)) { | 1893 | index1 = root->log_transid % 2; |
| 1942 | wait_log_commit(log); | 1894 | if (atomic_read(&root->log_commit[index1])) { |
| 1943 | goto out; | 1895 | wait_log_commit(root, root->log_transid); |
| 1896 | mutex_unlock(&root->log_mutex); | ||
| 1897 | return 0; | ||
| 1944 | } | 1898 | } |
| 1945 | atomic_set(&log->fs_info->tree_log_commit, 1); | 1899 | atomic_set(&root->log_commit[index1], 1); |
| 1900 | |||
| 1901 | /* wait for previous tree log sync to complete */ | ||
| 1902 | if (atomic_read(&root->log_commit[(index1 + 1) % 2])) | ||
| 1903 | wait_log_commit(root, root->log_transid - 1); | ||
| 1946 | 1904 | ||
| 1947 | while (1) { | 1905 | while (1) { |
| 1948 | batch = log->fs_info->tree_log_batch; | 1906 | unsigned long batch = root->log_batch; |
| 1949 | mutex_unlock(&log->fs_info->tree_log_mutex); | 1907 | mutex_unlock(&root->log_mutex); |
| 1950 | schedule_timeout_uninterruptible(1); | 1908 | schedule_timeout_uninterruptible(1); |
| 1951 | mutex_lock(&log->fs_info->tree_log_mutex); | 1909 | mutex_lock(&root->log_mutex); |
| 1952 | 1910 | wait_for_writer(root); | |
| 1953 | while (atomic_read(&log->fs_info->tree_log_writers)) { | 1911 | if (batch == root->log_batch) |
| 1954 | DEFINE_WAIT(wait); | ||
| 1955 | prepare_to_wait(&log->fs_info->tree_log_wait, &wait, | ||
| 1956 | TASK_UNINTERRUPTIBLE); | ||
| 1957 | mutex_unlock(&log->fs_info->tree_log_mutex); | ||
| 1958 | if (atomic_read(&log->fs_info->tree_log_writers)) | ||
| 1959 | schedule(); | ||
| 1960 | mutex_lock(&log->fs_info->tree_log_mutex); | ||
| 1961 | finish_wait(&log->fs_info->tree_log_wait, &wait); | ||
| 1962 | } | ||
| 1963 | if (batch == log->fs_info->tree_log_batch) | ||
| 1964 | break; | 1912 | break; |
| 1965 | } | 1913 | } |
| 1966 | 1914 | ||
| 1967 | ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); | 1915 | ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); |
| 1968 | BUG_ON(ret); | 1916 | BUG_ON(ret); |
| 1969 | ret = btrfs_write_and_wait_marked_extents(root->fs_info->log_root_tree, | 1917 | |
| 1970 | &root->fs_info->log_root_tree->dirty_log_pages); | 1918 | btrfs_set_root_bytenr(&log->root_item, log->node->start); |
| 1919 | btrfs_set_root_generation(&log->root_item, trans->transid); | ||
| 1920 | btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); | ||
| 1921 | |||
| 1922 | root->log_batch = 0; | ||
| 1923 | root->log_transid++; | ||
| 1924 | log->log_transid = root->log_transid; | ||
| 1925 | smp_mb(); | ||
| 1926 | /* | ||
| 1927 | * log tree has been flushed to disk, new modifications of | ||
| 1928 | * the log will be written to new positions. so it's safe to | ||
| 1929 | * allow log writers to go in. | ||
| 1930 | */ | ||
| 1931 | mutex_unlock(&root->log_mutex); | ||
| 1932 | |||
| 1933 | mutex_lock(&log_root_tree->log_mutex); | ||
| 1934 | log_root_tree->log_batch++; | ||
| 1935 | atomic_inc(&log_root_tree->log_writers); | ||
| 1936 | mutex_unlock(&log_root_tree->log_mutex); | ||
| 1937 | |||
| 1938 | ret = update_log_root(trans, log); | ||
| 1939 | BUG_ON(ret); | ||
| 1940 | |||
| 1941 | mutex_lock(&log_root_tree->log_mutex); | ||
| 1942 | if (atomic_dec_and_test(&log_root_tree->log_writers)) { | ||
| 1943 | smp_mb(); | ||
| 1944 | if (waitqueue_active(&log_root_tree->log_writer_wait)) | ||
| 1945 | wake_up(&log_root_tree->log_writer_wait); | ||
| 1946 | } | ||
| 1947 | |||
| 1948 | index2 = log_root_tree->log_transid % 2; | ||
| 1949 | if (atomic_read(&log_root_tree->log_commit[index2])) { | ||
| 1950 | wait_log_commit(log_root_tree, log_root_tree->log_transid); | ||
| 1951 | mutex_unlock(&log_root_tree->log_mutex); | ||
| 1952 | goto out; | ||
| 1953 | } | ||
| 1954 | atomic_set(&log_root_tree->log_commit[index2], 1); | ||
| 1955 | |||
| 1956 | if (atomic_read(&log_root_tree->log_commit[(index2 + 1) % 2])) | ||
| 1957 | wait_log_commit(log_root_tree, log_root_tree->log_transid - 1); | ||
| 1958 | |||
| 1959 | wait_for_writer(log_root_tree); | ||
| 1960 | |||
| 1961 | ret = btrfs_write_and_wait_marked_extents(log_root_tree, | ||
| 1962 | &log_root_tree->dirty_log_pages); | ||
| 1971 | BUG_ON(ret); | 1963 | BUG_ON(ret); |
| 1972 | 1964 | ||
| 1973 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, | 1965 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, |
| 1974 | log->fs_info->log_root_tree->node->start); | 1966 | log_root_tree->node->start); |
| 1975 | btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, | 1967 | btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, |
| 1976 | btrfs_header_level(log->fs_info->log_root_tree->node)); | 1968 | btrfs_header_level(log_root_tree->node)); |
| 1969 | |||
| 1970 | log_root_tree->log_batch = 0; | ||
| 1971 | log_root_tree->log_transid++; | ||
| 1972 | smp_mb(); | ||
| 1973 | |||
| 1974 | mutex_unlock(&log_root_tree->log_mutex); | ||
| 1975 | |||
| 1976 | /* | ||
| 1977 | * nobody else is going to jump in and write the the ctree | ||
| 1978 | * super here because the log_commit atomic below is protecting | ||
| 1979 | * us. We must be called with a transaction handle pinning | ||
| 1980 | * the running transaction open, so a full commit can't hop | ||
| 1981 | * in and cause problems either. | ||
| 1982 | */ | ||
| 1983 | write_ctree_super(trans, root->fs_info->tree_root, 2); | ||
| 1977 | 1984 | ||
| 1978 | write_ctree_super(trans, log->fs_info->tree_root, 2); | 1985 | atomic_set(&log_root_tree->log_commit[index2], 0); |
| 1979 | log->fs_info->tree_log_transid++; | ||
| 1980 | log->fs_info->tree_log_batch = 0; | ||
| 1981 | atomic_set(&log->fs_info->tree_log_commit, 0); | ||
| 1982 | smp_mb(); | 1986 | smp_mb(); |
| 1983 | if (waitqueue_active(&log->fs_info->tree_log_wait)) | 1987 | if (waitqueue_active(&log_root_tree->log_commit_wait[index2])) |
| 1984 | wake_up(&log->fs_info->tree_log_wait); | 1988 | wake_up(&log_root_tree->log_commit_wait[index2]); |
| 1985 | out: | 1989 | out: |
| 1986 | mutex_unlock(&log->fs_info->tree_log_mutex); | 1990 | atomic_set(&root->log_commit[index1], 0); |
| 1991 | smp_mb(); | ||
| 1992 | if (waitqueue_active(&root->log_commit_wait[index1])) | ||
| 1993 | wake_up(&root->log_commit_wait[index1]); | ||
| 1987 | return 0; | 1994 | return 0; |
| 1988 | } | 1995 | } |
| 1989 | 1996 | ||
| @@ -2019,38 +2026,18 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root) | |||
| 2019 | start, end, GFP_NOFS); | 2026 | start, end, GFP_NOFS); |
| 2020 | } | 2027 | } |
| 2021 | 2028 | ||
| 2022 | log = root->log_root; | 2029 | if (log->log_transid > 0) { |
| 2023 | ret = btrfs_del_root(trans, root->fs_info->log_root_tree, | 2030 | ret = btrfs_del_root(trans, root->fs_info->log_root_tree, |
| 2024 | &log->root_key); | 2031 | &log->root_key); |
| 2025 | BUG_ON(ret); | 2032 | BUG_ON(ret); |
| 2033 | } | ||
| 2026 | root->log_root = NULL; | 2034 | root->log_root = NULL; |
| 2027 | kfree(root->log_root); | 2035 | free_extent_buffer(log->node); |
| 2036 | kfree(log); | ||
| 2028 | return 0; | 2037 | return 0; |
| 2029 | } | 2038 | } |
| 2030 | 2039 | ||
| 2031 | /* | 2040 | /* |
| 2032 | * helper function to update the item for a given subvolumes log root | ||
| 2033 | * in the tree of log roots | ||
| 2034 | */ | ||
| 2035 | static int update_log_root(struct btrfs_trans_handle *trans, | ||
| 2036 | struct btrfs_root *log) | ||
| 2037 | { | ||
| 2038 | u64 bytenr = btrfs_root_bytenr(&log->root_item); | ||
| 2039 | int ret; | ||
| 2040 | |||
| 2041 | if (log->node->start == bytenr) | ||
| 2042 | return 0; | ||
| 2043 | |||
| 2044 | btrfs_set_root_bytenr(&log->root_item, log->node->start); | ||
| 2045 | btrfs_set_root_generation(&log->root_item, trans->transid); | ||
| 2046 | btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); | ||
| 2047 | ret = btrfs_update_root(trans, log->fs_info->log_root_tree, | ||
| 2048 | &log->root_key, &log->root_item); | ||
| 2049 | BUG_ON(ret); | ||
| 2050 | return ret; | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | /* | ||
| 2054 | * If both a file and directory are logged, and unlinks or renames are | 2041 | * If both a file and directory are logged, and unlinks or renames are |
| 2055 | * mixed in, we have a few interesting corners: | 2042 | * mixed in, we have a few interesting corners: |
| 2056 | * | 2043 | * |
| @@ -2711,11 +2698,6 @@ next_slot: | |||
| 2711 | 2698 | ||
| 2712 | btrfs_free_path(path); | 2699 | btrfs_free_path(path); |
| 2713 | btrfs_free_path(dst_path); | 2700 | btrfs_free_path(dst_path); |
| 2714 | |||
| 2715 | mutex_lock(&root->fs_info->tree_log_mutex); | ||
| 2716 | ret = update_log_root(trans, log); | ||
| 2717 | BUG_ON(ret); | ||
| 2718 | mutex_unlock(&root->fs_info->tree_log_mutex); | ||
| 2719 | out: | 2701 | out: |
| 2720 | return 0; | 2702 | return 0; |
| 2721 | } | 2703 | } |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 3451e1cca2b5..fd0bedb07a64 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <linux/buffer_head.h> | 20 | #include <linux/buffer_head.h> |
| 21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
| 22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
| 23 | #include <linux/version.h> | ||
| 24 | #include <asm/div64.h> | 23 | #include <asm/div64.h> |
| 25 | #include "compat.h" | 24 | #include "compat.h" |
| 26 | #include "ctree.h" | 25 | #include "ctree.h" |
| @@ -104,10 +103,8 @@ static noinline struct btrfs_device *__find_device(struct list_head *head, | |||
| 104 | u64 devid, u8 *uuid) | 103 | u64 devid, u8 *uuid) |
| 105 | { | 104 | { |
| 106 | struct btrfs_device *dev; | 105 | struct btrfs_device *dev; |
| 107 | struct list_head *cur; | ||
| 108 | 106 | ||
| 109 | list_for_each(cur, head) { | 107 | list_for_each_entry(dev, head, dev_list) { |
| 110 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 111 | if (dev->devid == devid && | 108 | if (dev->devid == devid && |
| 112 | (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) { | 109 | (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) { |
| 113 | return dev; | 110 | return dev; |
| @@ -118,11 +115,9 @@ static noinline struct btrfs_device *__find_device(struct list_head *head, | |||
| 118 | 115 | ||
| 119 | static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) | 116 | static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) |
| 120 | { | 117 | { |
| 121 | struct list_head *cur; | ||
| 122 | struct btrfs_fs_devices *fs_devices; | 118 | struct btrfs_fs_devices *fs_devices; |
| 123 | 119 | ||
| 124 | list_for_each(cur, &fs_uuids) { | 120 | list_for_each_entry(fs_devices, &fs_uuids, list) { |
| 125 | fs_devices = list_entry(cur, struct btrfs_fs_devices, list); | ||
| 126 | if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) | 121 | if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) |
| 127 | return fs_devices; | 122 | return fs_devices; |
| 128 | } | 123 | } |
| @@ -345,14 +340,11 @@ error: | |||
| 345 | 340 | ||
| 346 | int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) | 341 | int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) |
| 347 | { | 342 | { |
| 348 | struct list_head *tmp; | 343 | struct btrfs_device *device, *next; |
| 349 | struct list_head *cur; | ||
| 350 | struct btrfs_device *device; | ||
| 351 | 344 | ||
| 352 | mutex_lock(&uuid_mutex); | 345 | mutex_lock(&uuid_mutex); |
| 353 | again: | 346 | again: |
| 354 | list_for_each_safe(cur, tmp, &fs_devices->devices) { | 347 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { |
| 355 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 356 | if (device->in_fs_metadata) | 348 | if (device->in_fs_metadata) |
| 357 | continue; | 349 | continue; |
| 358 | 350 | ||
| @@ -383,14 +375,12 @@ again: | |||
| 383 | 375 | ||
| 384 | static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | 376 | static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
| 385 | { | 377 | { |
| 386 | struct list_head *cur; | ||
| 387 | struct btrfs_device *device; | 378 | struct btrfs_device *device; |
| 388 | 379 | ||
| 389 | if (--fs_devices->opened > 0) | 380 | if (--fs_devices->opened > 0) |
| 390 | return 0; | 381 | return 0; |
| 391 | 382 | ||
| 392 | list_for_each(cur, &fs_devices->devices) { | 383 | list_for_each_entry(device, &fs_devices->devices, dev_list) { |
| 393 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 394 | if (device->bdev) { | 384 | if (device->bdev) { |
| 395 | close_bdev_exclusive(device->bdev, device->mode); | 385 | close_bdev_exclusive(device->bdev, device->mode); |
| 396 | fs_devices->open_devices--; | 386 | fs_devices->open_devices--; |
| @@ -439,7 +429,6 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
| 439 | { | 429 | { |
| 440 | struct block_device *bdev; | 430 | struct block_device *bdev; |
| 441 | struct list_head *head = &fs_devices->devices; | 431 | struct list_head *head = &fs_devices->devices; |
| 442 | struct list_head *cur; | ||
| 443 | struct btrfs_device *device; | 432 | struct btrfs_device *device; |
| 444 | struct block_device *latest_bdev = NULL; | 433 | struct block_device *latest_bdev = NULL; |
| 445 | struct buffer_head *bh; | 434 | struct buffer_head *bh; |
| @@ -450,8 +439,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
| 450 | int seeding = 1; | 439 | int seeding = 1; |
| 451 | int ret = 0; | 440 | int ret = 0; |
| 452 | 441 | ||
| 453 | list_for_each(cur, head) { | 442 | list_for_each_entry(device, head, dev_list) { |
| 454 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 455 | if (device->bdev) | 443 | if (device->bdev) |
| 456 | continue; | 444 | continue; |
| 457 | if (!device->name) | 445 | if (!device->name) |
| @@ -578,7 +566,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
| 578 | *(unsigned long long *)disk_super->fsid, | 566 | *(unsigned long long *)disk_super->fsid, |
| 579 | *(unsigned long long *)(disk_super->fsid + 8)); | 567 | *(unsigned long long *)(disk_super->fsid + 8)); |
| 580 | } | 568 | } |
| 581 | printk(KERN_INFO "devid %llu transid %llu %s\n", | 569 | printk(KERN_CONT "devid %llu transid %llu %s\n", |
| 582 | (unsigned long long)devid, (unsigned long long)transid, path); | 570 | (unsigned long long)devid, (unsigned long long)transid, path); |
| 583 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); | 571 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); |
| 584 | 572 | ||
| @@ -1017,14 +1005,12 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
| 1017 | } | 1005 | } |
| 1018 | 1006 | ||
| 1019 | if (strcmp(device_path, "missing") == 0) { | 1007 | if (strcmp(device_path, "missing") == 0) { |
| 1020 | struct list_head *cur; | ||
| 1021 | struct list_head *devices; | 1008 | struct list_head *devices; |
| 1022 | struct btrfs_device *tmp; | 1009 | struct btrfs_device *tmp; |
| 1023 | 1010 | ||
| 1024 | device = NULL; | 1011 | device = NULL; |
| 1025 | devices = &root->fs_info->fs_devices->devices; | 1012 | devices = &root->fs_info->fs_devices->devices; |
| 1026 | list_for_each(cur, devices) { | 1013 | list_for_each_entry(tmp, devices, dev_list) { |
| 1027 | tmp = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1028 | if (tmp->in_fs_metadata && !tmp->bdev) { | 1014 | if (tmp->in_fs_metadata && !tmp->bdev) { |
| 1029 | device = tmp; | 1015 | device = tmp; |
| 1030 | break; | 1016 | break; |
| @@ -1280,7 +1266,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
| 1280 | struct btrfs_trans_handle *trans; | 1266 | struct btrfs_trans_handle *trans; |
| 1281 | struct btrfs_device *device; | 1267 | struct btrfs_device *device; |
| 1282 | struct block_device *bdev; | 1268 | struct block_device *bdev; |
| 1283 | struct list_head *cur; | ||
| 1284 | struct list_head *devices; | 1269 | struct list_head *devices; |
| 1285 | struct super_block *sb = root->fs_info->sb; | 1270 | struct super_block *sb = root->fs_info->sb; |
| 1286 | u64 total_bytes; | 1271 | u64 total_bytes; |
| @@ -1304,8 +1289,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
| 1304 | mutex_lock(&root->fs_info->volume_mutex); | 1289 | mutex_lock(&root->fs_info->volume_mutex); |
| 1305 | 1290 | ||
| 1306 | devices = &root->fs_info->fs_devices->devices; | 1291 | devices = &root->fs_info->fs_devices->devices; |
| 1307 | list_for_each(cur, devices) { | 1292 | list_for_each_entry(device, devices, dev_list) { |
| 1308 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1309 | if (device->bdev == bdev) { | 1293 | if (device->bdev == bdev) { |
| 1310 | ret = -EEXIST; | 1294 | ret = -EEXIST; |
| 1311 | goto error; | 1295 | goto error; |
| @@ -1704,7 +1688,6 @@ static u64 div_factor(u64 num, int factor) | |||
| 1704 | int btrfs_balance(struct btrfs_root *dev_root) | 1688 | int btrfs_balance(struct btrfs_root *dev_root) |
| 1705 | { | 1689 | { |
| 1706 | int ret; | 1690 | int ret; |
| 1707 | struct list_head *cur; | ||
| 1708 | struct list_head *devices = &dev_root->fs_info->fs_devices->devices; | 1691 | struct list_head *devices = &dev_root->fs_info->fs_devices->devices; |
| 1709 | struct btrfs_device *device; | 1692 | struct btrfs_device *device; |
| 1710 | u64 old_size; | 1693 | u64 old_size; |
| @@ -1723,8 +1706,7 @@ int btrfs_balance(struct btrfs_root *dev_root) | |||
| 1723 | dev_root = dev_root->fs_info->dev_root; | 1706 | dev_root = dev_root->fs_info->dev_root; |
| 1724 | 1707 | ||
| 1725 | /* step one make some room on all the devices */ | 1708 | /* step one make some room on all the devices */ |
| 1726 | list_for_each(cur, devices) { | 1709 | list_for_each_entry(device, devices, dev_list) { |
| 1727 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1728 | old_size = device->total_bytes; | 1710 | old_size = device->total_bytes; |
| 1729 | size_to_free = div_factor(old_size, 1); | 1711 | size_to_free = div_factor(old_size, 1); |
| 1730 | size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); | 1712 | size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 7f332e270894..b4fa5f4b6ad1 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
| @@ -45,9 +45,12 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | |||
| 45 | /* lookup the xattr by name */ | 45 | /* lookup the xattr by name */ |
| 46 | di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, | 46 | di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, |
| 47 | strlen(name), 0); | 47 | strlen(name), 0); |
| 48 | if (!di || IS_ERR(di)) { | 48 | if (!di) { |
| 49 | ret = -ENODATA; | 49 | ret = -ENODATA; |
| 50 | goto out; | 50 | goto out; |
| 51 | } else if (IS_ERR(di)) { | ||
| 52 | ret = PTR_ERR(di); | ||
| 53 | goto out; | ||
| 51 | } | 54 | } |
| 52 | 55 | ||
| 53 | leaf = path->nodes[0]; | 56 | leaf = path->nodes[0]; |
| @@ -62,6 +65,14 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | |||
| 62 | ret = -ERANGE; | 65 | ret = -ERANGE; |
| 63 | goto out; | 66 | goto out; |
| 64 | } | 67 | } |
| 68 | |||
| 69 | /* | ||
| 70 | * The way things are packed into the leaf is like this | ||
| 71 | * |struct btrfs_dir_item|name|data| | ||
| 72 | * where name is the xattr name, so security.foo, and data is the | ||
| 73 | * content of the xattr. data_ptr points to the location in memory | ||
| 74 | * where the data starts in the in memory leaf | ||
| 75 | */ | ||
| 65 | data_ptr = (unsigned long)((char *)(di + 1) + | 76 | data_ptr = (unsigned long)((char *)(di + 1) + |
| 66 | btrfs_dir_name_len(leaf, di)); | 77 | btrfs_dir_name_len(leaf, di)); |
| 67 | read_extent_buffer(leaf, buffer, data_ptr, | 78 | read_extent_buffer(leaf, buffer, data_ptr, |
| @@ -176,7 +187,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 176 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 187 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| 177 | if (ret < 0) | 188 | if (ret < 0) |
| 178 | goto err; | 189 | goto err; |
| 179 | ret = 0; | ||
| 180 | advance = 0; | 190 | advance = 0; |
| 181 | while (1) { | 191 | while (1) { |
| 182 | leaf = path->nodes[0]; | 192 | leaf = path->nodes[0]; |
