aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2014-05-19 23:47:56 -0400
committerChris Mason <clm@fb.com>2014-06-09 20:20:55 -0400
commitd4452bc526c431a882cc6ba854619e166cb7dfe4 (patch)
tree4cf699991791873af81041f3b40faca3d8155d8c /fs
parent2a10840945a86dfa2356bce526ae78cd4c1a356e (diff)
Btrfs: break up __btrfs_write_out_cache to cut down stack usage
__btrfs_write_out_cache was one of our stack pigs. This breaks it up into helper functions and slims it down to 194 bytes. Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/free-space-cache.c308
1 files changed, 191 insertions, 117 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index a6bd654dcd47..372b05ff1943 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -851,90 +851,44 @@ out:
851 return ret; 851 return ret;
852} 852}
853 853
854/** 854static noinline_for_stack
855 * __btrfs_write_out_cache - write out cached info to an inode 855int write_cache_extent_entries(struct io_ctl *io_ctl,
856 * @root - the root the inode belongs to 856 struct btrfs_free_space_ctl *ctl,
857 * @ctl - the free space cache we are going to write out 857 struct btrfs_block_group_cache *block_group,
858 * @block_group - the block_group for this cache if it belongs to a block_group 858 int *entries, int *bitmaps,
859 * @trans - the trans handle 859 struct list_head *bitmap_list)
860 * @path - the path to use
861 * @offset - the offset for the key we'll insert
862 *
863 * This function writes out a free space cache struct to disk for quick recovery
864 * on mount. This will return 0 if it was successfull in writing the cache out,
865 * and -1 if it was not.
866 */
867static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
868 struct btrfs_free_space_ctl *ctl,
869 struct btrfs_block_group_cache *block_group,
870 struct btrfs_trans_handle *trans,
871 struct btrfs_path *path, u64 offset)
872{ 860{
873 struct btrfs_free_space_header *header;
874 struct extent_buffer *leaf;
875 struct rb_node *node;
876 struct list_head *pos, *n;
877 struct extent_state *cached_state = NULL;
878 struct btrfs_free_cluster *cluster = NULL;
879 struct extent_io_tree *unpin = NULL;
880 struct io_ctl io_ctl;
881 struct list_head bitmap_list;
882 struct btrfs_key key;
883 u64 start, extent_start, extent_end, len;
884 int entries = 0;
885 int bitmaps = 0;
886 int ret; 861 int ret;
887 int err = -1; 862 struct btrfs_free_cluster *cluster = NULL;
888 863 struct rb_node *node = rb_first(&ctl->free_space_offset);
889 INIT_LIST_HEAD(&bitmap_list);
890
891 if (!i_size_read(inode))
892 return -1;
893
894 ret = io_ctl_init(&io_ctl, inode, root);
895 if (ret)
896 return -1;
897 864
898 /* Get the cluster for this block_group if it exists */ 865 /* Get the cluster for this block_group if it exists */
899 if (block_group && !list_empty(&block_group->cluster_list)) 866 if (block_group && !list_empty(&block_group->cluster_list)) {
900 cluster = list_entry(block_group->cluster_list.next, 867 cluster = list_entry(block_group->cluster_list.next,
901 struct btrfs_free_cluster, 868 struct btrfs_free_cluster,
902 block_group_list); 869 block_group_list);
870 }
903 871
904 /* Lock all pages first so we can lock the extent safely. */
905 io_ctl_prepare_pages(&io_ctl, inode, 0);
906
907 lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
908 0, &cached_state);
909
910 node = rb_first(&ctl->free_space_offset);
911 if (!node && cluster) { 872 if (!node && cluster) {
912 node = rb_first(&cluster->root); 873 node = rb_first(&cluster->root);
913 cluster = NULL; 874 cluster = NULL;
914 } 875 }
915 876
916 /* Make sure we can fit our crcs into the first page */
917 if (io_ctl.check_crcs &&
918 (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE)
919 goto out_nospc;
920
921 io_ctl_set_generation(&io_ctl, trans->transid);
922
923 /* Write out the extent entries */ 877 /* Write out the extent entries */
924 while (node) { 878 while (node) {
925 struct btrfs_free_space *e; 879 struct btrfs_free_space *e;
926 880
927 e = rb_entry(node, struct btrfs_free_space, offset_index); 881 e = rb_entry(node, struct btrfs_free_space, offset_index);
928 entries++; 882 *entries += 1;
929 883
930 ret = io_ctl_add_entry(&io_ctl, e->offset, e->bytes, 884 ret = io_ctl_add_entry(io_ctl, e->offset, e->bytes,
931 e->bitmap); 885 e->bitmap);
932 if (ret) 886 if (ret)
933 goto out_nospc; 887 goto fail;
934 888
935 if (e->bitmap) { 889 if (e->bitmap) {
936 list_add_tail(&e->list, &bitmap_list); 890 list_add_tail(&e->list, bitmap_list);
937 bitmaps++; 891 *bitmaps += 1;
938 } 892 }
939 node = rb_next(node); 893 node = rb_next(node);
940 if (!node && cluster) { 894 if (!node && cluster) {
@@ -942,13 +896,84 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
942 cluster = NULL; 896 cluster = NULL;
943 } 897 }
944 } 898 }
899 return 0;
900fail:
901 return -ENOSPC;
902}
903
904static noinline_for_stack int
905update_cache_item(struct btrfs_trans_handle *trans,
906 struct btrfs_root *root,
907 struct inode *inode,
908 struct btrfs_path *path, u64 offset,
909 int entries, int bitmaps)
910{
911 struct btrfs_key key;
912 struct btrfs_free_space_header *header;
913 struct extent_buffer *leaf;
914 int ret;
915
916 key.objectid = BTRFS_FREE_SPACE_OBJECTID;
917 key.offset = offset;
918 key.type = 0;
919
920 ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
921 if (ret < 0) {
922 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1,
923 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL,
924 GFP_NOFS);
925 goto fail;
926 }
927 leaf = path->nodes[0];
928 if (ret > 0) {
929 struct btrfs_key found_key;
930 ASSERT(path->slots[0]);
931 path->slots[0]--;
932 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
933 if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID ||
934 found_key.offset != offset) {
935 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0,
936 inode->i_size - 1,
937 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0,
938 NULL, GFP_NOFS);
939 btrfs_release_path(path);
940 goto fail;
941 }
942 }
943
944 BTRFS_I(inode)->generation = trans->transid;
945 header = btrfs_item_ptr(leaf, path->slots[0],
946 struct btrfs_free_space_header);
947 btrfs_set_free_space_entries(leaf, header, entries);
948 btrfs_set_free_space_bitmaps(leaf, header, bitmaps);
949 btrfs_set_free_space_generation(leaf, header, trans->transid);
950 btrfs_mark_buffer_dirty(leaf);
951 btrfs_release_path(path);
952
953 return 0;
954
955fail:
956 return -1;
957}
958
959static noinline_for_stack int
960add_ioctl_entries(struct btrfs_root *root,
961 struct inode *inode,
962 struct btrfs_block_group_cache *block_group,
963 struct io_ctl *io_ctl,
964 struct extent_state **cached_state,
965 struct list_head *bitmap_list,
966 int *entries)
967{
968 u64 start, extent_start, extent_end, len;
969 struct list_head *pos, *n;
970 struct extent_io_tree *unpin = NULL;
971 int ret;
945 972
946 /* 973 /*
947 * We want to add any pinned extents to our free space cache 974 * We want to add any pinned extents to our free space cache
948 * so we don't leak the space 975 * so we don't leak the space
949 */ 976 *
950
951 /*
952 * We shouldn't have switched the pinned extents yet so this is the 977 * We shouldn't have switched the pinned extents yet so this is the
953 * right one 978 * right one
954 */ 979 */
@@ -977,8 +1002,8 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
977 block_group->key.offset, extent_end + 1); 1002 block_group->key.offset, extent_end + 1);
978 len = extent_end - extent_start; 1003 len = extent_end - extent_start;
979 1004
980 entries++; 1005 *entries += 1;
981 ret = io_ctl_add_entry(&io_ctl, extent_start, len, NULL); 1006 ret = io_ctl_add_entry(io_ctl, extent_start, len, NULL);
982 if (ret) 1007 if (ret)
983 goto out_nospc; 1008 goto out_nospc;
984 1009
@@ -986,74 +1011,129 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
986 } 1011 }
987 1012
988 /* Write out the bitmaps */ 1013 /* Write out the bitmaps */
989 list_for_each_safe(pos, n, &bitmap_list) { 1014 list_for_each_safe(pos, n, bitmap_list) {
990 struct btrfs_free_space *entry = 1015 struct btrfs_free_space *entry =
991 list_entry(pos, struct btrfs_free_space, list); 1016 list_entry(pos, struct btrfs_free_space, list);
992 1017
993 ret = io_ctl_add_bitmap(&io_ctl, entry->bitmap); 1018 ret = io_ctl_add_bitmap(io_ctl, entry->bitmap);
994 if (ret) 1019 if (ret)
995 goto out_nospc; 1020 goto out_nospc;
996 list_del_init(&entry->list); 1021 list_del_init(&entry->list);
997 } 1022 }
998 1023
999 /* Zero out the rest of the pages just to make sure */ 1024 /* Zero out the rest of the pages just to make sure */
1000 io_ctl_zero_remaining_pages(&io_ctl); 1025 io_ctl_zero_remaining_pages(io_ctl);
1001 1026
1002 ret = btrfs_dirty_pages(root, inode, io_ctl.pages, io_ctl.num_pages, 1027 ret = btrfs_dirty_pages(root, inode, io_ctl->pages, io_ctl->num_pages,
1003 0, i_size_read(inode), &cached_state); 1028 0, i_size_read(inode), cached_state);
1004 io_ctl_drop_pages(&io_ctl); 1029 io_ctl_drop_pages(io_ctl);
1005 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, 1030 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
1006 i_size_read(inode) - 1, &cached_state, GFP_NOFS); 1031 i_size_read(inode) - 1, cached_state, GFP_NOFS);
1007 1032
1008 if (ret) 1033 if (ret)
1009 goto out; 1034 goto fail;
1010 1035
1011 ret = btrfs_wait_ordered_range(inode, 0, (u64)-1); 1036 ret = btrfs_wait_ordered_range(inode, 0, (u64)-1);
1012 if (ret) { 1037 if (ret) {
1013 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1, 1038 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1,
1014 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL, 1039 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL,
1015 GFP_NOFS); 1040 GFP_NOFS);
1016 goto out; 1041 goto fail;
1017 } 1042 }
1043 return 0;
1018 1044
1019 key.objectid = BTRFS_FREE_SPACE_OBJECTID; 1045fail:
1020 key.offset = offset; 1046 return -1;
1021 key.type = 0;
1022 1047
1023 ret = btrfs_search_slot(trans, root, &key, path, 0, 1); 1048out_nospc:
1024 if (ret < 0) { 1049 return -ENOSPC;
1025 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1, 1050}
1026 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL, 1051
1027 GFP_NOFS); 1052static void noinline_for_stack
1028 goto out; 1053cleanup_write_cache_enospc(struct inode *inode,
1029 } 1054 struct io_ctl *io_ctl,
1030 leaf = path->nodes[0]; 1055 struct extent_state **cached_state,
1031 if (ret > 0) { 1056 struct list_head *bitmap_list)
1032 struct btrfs_key found_key; 1057{
1033 ASSERT(path->slots[0]); 1058 struct list_head *pos, *n;
1034 path->slots[0]--; 1059 list_for_each_safe(pos, n, bitmap_list) {
1035 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 1060 struct btrfs_free_space *entry =
1036 if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID || 1061 list_entry(pos, struct btrfs_free_space, list);
1037 found_key.offset != offset) { 1062 list_del_init(&entry->list);
1038 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0,
1039 inode->i_size - 1,
1040 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0,
1041 NULL, GFP_NOFS);
1042 btrfs_release_path(path);
1043 goto out;
1044 }
1045 } 1063 }
1064 io_ctl_drop_pages(io_ctl);
1065 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
1066 i_size_read(inode) - 1, cached_state,
1067 GFP_NOFS);
1068}
1046 1069
1047 BTRFS_I(inode)->generation = trans->transid; 1070/**
1048 header = btrfs_item_ptr(leaf, path->slots[0], 1071 * __btrfs_write_out_cache - write out cached info to an inode
1049 struct btrfs_free_space_header); 1072 * @root - the root the inode belongs to
1050 btrfs_set_free_space_entries(leaf, header, entries); 1073 * @ctl - the free space cache we are going to write out
1051 btrfs_set_free_space_bitmaps(leaf, header, bitmaps); 1074 * @block_group - the block_group for this cache if it belongs to a block_group
1052 btrfs_set_free_space_generation(leaf, header, trans->transid); 1075 * @trans - the trans handle
1053 btrfs_mark_buffer_dirty(leaf); 1076 * @path - the path to use
1054 btrfs_release_path(path); 1077 * @offset - the offset for the key we'll insert
1078 *
1079 * This function writes out a free space cache struct to disk for quick recovery
1080 * on mount. This will return 0 if it was successfull in writing the cache out,
1081 * and -1 if it was not.
1082 */
1083static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
1084 struct btrfs_free_space_ctl *ctl,
1085 struct btrfs_block_group_cache *block_group,
1086 struct btrfs_trans_handle *trans,
1087 struct btrfs_path *path, u64 offset)
1088{
1089 struct extent_state *cached_state = NULL;
1090 struct io_ctl io_ctl;
1091 struct list_head bitmap_list;
1092 int entries = 0;
1093 int bitmaps = 0;
1094 int ret;
1095 int err = -1;
1096
1097 INIT_LIST_HEAD(&bitmap_list);
1098
1099 if (!i_size_read(inode))
1100 return -1;
1101
1102 ret = io_ctl_init(&io_ctl, inode, root);
1103 if (ret)
1104 return -1;
1105
1106 /* Lock all pages first so we can lock the extent safely. */
1107 io_ctl_prepare_pages(&io_ctl, inode, 0);
1108
1109 lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
1110 0, &cached_state);
1111
1112
1113 /* Make sure we can fit our crcs into the first page */
1114 if (io_ctl.check_crcs &&
1115 (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE)
1116 goto out_nospc;
1117
1118 io_ctl_set_generation(&io_ctl, trans->transid);
1119
1120 ret = write_cache_extent_entries(&io_ctl, ctl,
1121 block_group, &entries, &bitmaps,
1122 &bitmap_list);
1123 if (ret)
1124 goto out_nospc;
1125
1126 ret = add_ioctl_entries(root, inode, block_group, &io_ctl,
1127 &cached_state, &bitmap_list, &entries);
1128
1129 if (ret == -ENOSPC)
1130 goto out_nospc;
1131 else if (ret)
1132 goto out;
1133
1134 err = update_cache_item(trans, root, inode, path, offset,
1135 entries, bitmaps);
1055 1136
1056 err = 0;
1057out: 1137out:
1058 io_ctl_free(&io_ctl); 1138 io_ctl_free(&io_ctl);
1059 if (err) { 1139 if (err) {
@@ -1064,14 +1144,8 @@ out:
1064 return err; 1144 return err;
1065 1145
1066out_nospc: 1146out_nospc:
1067 list_for_each_safe(pos, n, &bitmap_list) { 1147
1068 struct btrfs_free_space *entry = 1148 cleanup_write_cache_enospc(inode, &io_ctl, &cached_state, &bitmap_list);
1069 list_entry(pos, struct btrfs_free_space, list);
1070 list_del_init(&entry->list);
1071 }
1072 io_ctl_drop_pages(&io_ctl);
1073 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
1074 i_size_read(inode) - 1, &cached_state, GFP_NOFS);
1075 goto out; 1149 goto out;
1076} 1150}
1077 1151