Btrfs: Optimize allocations as we need to mix data and metadata into one group
[safe/jmp/linux-2.6] / fs / btrfs / tree-defrag.c
1 /*
2  * Copyright (C) 2007 Oracle.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18
19 #include <linux/sched.h>
20 #include "ctree.h"
21 #include "disk-io.h"
22 #include "print-tree.h"
23 #include "transaction.h"
24
25 static void reada_defrag(struct btrfs_root *root,
26                          struct extent_buffer *node)
27 {
28         int i;
29         u32 nritems;
30         u64 bytenr;
31         u32 blocksize;
32         int ret;
33
34         blocksize = btrfs_level_size(root, btrfs_header_level(node) - 1);
35         nritems = btrfs_header_nritems(node);
36         for (i = 0; i < nritems; i++) {
37                 bytenr = btrfs_node_blockptr(node, i);
38                 ret = readahead_tree_block(root, bytenr, blocksize);
39                 if (ret)
40                         break;
41         }
42 }
43
44 static int defrag_walk_down(struct btrfs_trans_handle *trans,
45                             struct btrfs_root *root,
46                             struct btrfs_path *path, int *level,
47                             int cache_only, u64 *last_ret)
48 {
49         struct extent_buffer *next;
50         struct extent_buffer *cur;
51         u64 bytenr;
52         int ret = 0;
53         int is_extent = 0;
54
55         WARN_ON(*level < 0);
56         WARN_ON(*level >= BTRFS_MAX_LEVEL);
57
58         if (root->fs_info->extent_root == root)
59                 is_extent = 1;
60
61         if (*level == 1 && cache_only && path->nodes[1] &&
62             !btrfs_buffer_defrag(path->nodes[1])) {
63                 goto out;
64         }
65         while(*level > 0) {
66                 WARN_ON(*level < 0);
67                 WARN_ON(*level >= BTRFS_MAX_LEVEL);
68                 cur = path->nodes[*level];
69
70                 if (!cache_only && *level > 1 && path->slots[*level] == 0)
71                         reada_defrag(root, cur);
72
73                 if (btrfs_header_level(cur) != *level)
74                         WARN_ON(1);
75
76                 if (path->slots[*level] >=
77                     btrfs_header_nritems(cur))
78                         break;
79
80                 if (*level == 1) {
81                         ret = btrfs_realloc_node(trans, root,
82                                                  path->nodes[*level],
83                                                  path->slots[*level],
84                                                  cache_only, last_ret,
85                                                  &root->defrag_progress);
86                         if (is_extent)
87                                 btrfs_extent_post_op(trans, root);
88
89                         break;
90                 }
91                 bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
92
93                 if (cache_only) {
94                         next = btrfs_find_tree_block(root, bytenr,
95                                            btrfs_level_size(root, *level - 1));
96                         if (!next || !btrfs_buffer_uptodate(next) ||
97                             !btrfs_buffer_defrag(next)) {
98                                 free_extent_buffer(next);
99                                 path->slots[*level]++;
100                                 continue;
101                         }
102                 } else {
103                         next = read_tree_block(root, bytenr,
104                                        btrfs_level_size(root, *level - 1));
105                 }
106                 ret = btrfs_cow_block(trans, root, next, path->nodes[*level],
107                                       path->slots[*level], &next);
108                 BUG_ON(ret);
109                 if (is_extent)
110                         btrfs_extent_post_op(trans, root);
111
112                 WARN_ON(*level <= 0);
113                 if (path->nodes[*level-1])
114                         free_extent_buffer(path->nodes[*level-1]);
115                 path->nodes[*level-1] = next;
116                 *level = btrfs_header_level(next);
117                 path->slots[*level] = 0;
118         }
119         WARN_ON(*level < 0);
120         WARN_ON(*level >= BTRFS_MAX_LEVEL);
121
122         btrfs_clear_buffer_defrag(path->nodes[*level]);
123 out:
124         free_extent_buffer(path->nodes[*level]);
125         path->nodes[*level] = NULL;
126         *level += 1;
127         WARN_ON(ret && ret != -EAGAIN);
128         return ret;
129 }
130
131 static int defrag_walk_up(struct btrfs_trans_handle *trans,
132                           struct btrfs_root *root,
133                           struct btrfs_path *path, int *level,
134                           int cache_only)
135 {
136         int i;
137         int slot;
138         struct extent_buffer *node;
139
140         for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
141                 slot = path->slots[i];
142                 if (slot < btrfs_header_nritems(path->nodes[i]) - 1) {
143                         path->slots[i]++;
144                         *level = i;
145                         node = path->nodes[i];
146                         WARN_ON(i == 0);
147                         btrfs_node_key_to_cpu(node, &root->defrag_progress,
148                                               path->slots[i]);
149                         root->defrag_level = i;
150                         return 0;
151                 } else {
152                         btrfs_clear_buffer_defrag(path->nodes[*level]);
153                         free_extent_buffer(path->nodes[*level]);
154                         path->nodes[*level] = NULL;
155                         *level = i + 1;
156                 }
157         }
158         return 1;
159 }
160
161 int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
162                         struct btrfs_root *root, int cache_only)
163 {
164         struct btrfs_path *path = NULL;
165         struct extent_buffer *tmp;
166         int ret = 0;
167         int wret;
168         int level;
169         int orig_level;
170         int i;
171         int is_extent = 0;
172         u64 last_ret = 0;
173
174         if (root->fs_info->extent_root == root)
175                 is_extent = 1;
176
177         if (root->ref_cows == 0 && !is_extent)
178                 goto out;
179
180         path = btrfs_alloc_path();
181         if (!path)
182                 return -ENOMEM;
183
184         level = btrfs_header_level(root->node);
185         orig_level = level;
186
187         if (level == 0) {
188                 goto out;
189         }
190         if (root->defrag_progress.objectid == 0) {
191                 extent_buffer_get(root->node);
192                 ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp);
193                 BUG_ON(ret);
194                 path->nodes[level] = root->node;
195                 path->slots[level] = 0;
196                 if (is_extent)
197                         btrfs_extent_post_op(trans, root);
198         } else {
199                 level = root->defrag_level;
200                 path->lowest_level = level;
201                 wret = btrfs_search_slot(trans, root, &root->defrag_progress,
202                                          path, 0, 1);
203
204                 if (is_extent)
205                         btrfs_extent_post_op(trans, root);
206
207                 if (wret < 0) {
208                         ret = wret;
209                         goto out;
210                 }
211
212                 while(level > 0 && !path->nodes[level])
213                         level--;
214
215                 if (!path->nodes[level]) {
216                         ret = 0;
217                         goto out;
218                 }
219         }
220
221         while(1) {
222                 wret = defrag_walk_down(trans, root, path, &level, cache_only,
223                                         &last_ret);
224                 if (wret > 0)
225                         break;
226                 if (wret < 0)
227                         ret = wret;
228
229                 wret = defrag_walk_up(trans, root, path, &level, cache_only);
230                 if (wret > 0)
231                         break;
232                 if (wret < 0)
233                         ret = wret;
234                 else
235                         ret = -EAGAIN;
236                 break;
237         }
238         for (i = 0; i <= orig_level; i++) {
239                 if (path->nodes[i]) {
240                         free_extent_buffer(path->nodes[i]);
241                         path->nodes[i] = NULL;
242                 }
243         }
244 out:
245         if (path)
246                 btrfs_free_path(path);
247         if (ret != -EAGAIN) {
248                 memset(&root->defrag_progress, 0,
249                        sizeof(root->defrag_progress));
250         }
251         return ret;
252 }