aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/btrfs/ordered-data.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c97
1 files changed, 91 insertions, 6 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index e56c72bc5add..a1c940425307 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -141,7 +141,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree,
141 u64 file_offset) 141 u64 file_offset)
142{ 142{
143 struct rb_root *root = &tree->tree; 143 struct rb_root *root = &tree->tree;
144 struct rb_node *prev; 144 struct rb_node *prev = NULL;
145 struct rb_node *ret; 145 struct rb_node *ret;
146 struct btrfs_ordered_extent *entry; 146 struct btrfs_ordered_extent *entry;
147 147
@@ -172,7 +172,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree,
172 */ 172 */
173static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, 173static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
174 u64 start, u64 len, u64 disk_len, 174 u64 start, u64 len, u64 disk_len,
175 int type, int dio) 175 int type, int dio, int compress_type)
176{ 176{
177 struct btrfs_ordered_inode_tree *tree; 177 struct btrfs_ordered_inode_tree *tree;
178 struct rb_node *node; 178 struct rb_node *node;
@@ -189,6 +189,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
189 entry->disk_len = disk_len; 189 entry->disk_len = disk_len;
190 entry->bytes_left = len; 190 entry->bytes_left = len;
191 entry->inode = inode; 191 entry->inode = inode;
192 entry->compress_type = compress_type;
192 if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) 193 if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE)
193 set_bit(type, &entry->flags); 194 set_bit(type, &entry->flags);
194 195
@@ -201,6 +202,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
201 INIT_LIST_HEAD(&entry->list); 202 INIT_LIST_HEAD(&entry->list);
202 INIT_LIST_HEAD(&entry->root_extent_list); 203 INIT_LIST_HEAD(&entry->root_extent_list);
203 204
205 trace_btrfs_ordered_extent_add(inode, entry);
206
204 spin_lock(&tree->lock); 207 spin_lock(&tree->lock);
205 node = tree_insert(&tree->tree, file_offset, 208 node = tree_insert(&tree->tree, file_offset,
206 &entry->rb_node); 209 &entry->rb_node);
@@ -220,14 +223,25 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
220 u64 start, u64 len, u64 disk_len, int type) 223 u64 start, u64 len, u64 disk_len, int type)
221{ 224{
222 return __btrfs_add_ordered_extent(inode, file_offset, start, len, 225 return __btrfs_add_ordered_extent(inode, file_offset, start, len,
223 disk_len, type, 0); 226 disk_len, type, 0,
227 BTRFS_COMPRESS_NONE);
224} 228}
225 229
226int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, 230int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset,
227 u64 start, u64 len, u64 disk_len, int type) 231 u64 start, u64 len, u64 disk_len, int type)
228{ 232{
229 return __btrfs_add_ordered_extent(inode, file_offset, start, len, 233 return __btrfs_add_ordered_extent(inode, file_offset, start, len,
230 disk_len, type, 1); 234 disk_len, type, 1,
235 BTRFS_COMPRESS_NONE);
236}
237
238int btrfs_add_ordered_extent_compress(struct inode *inode, u64 file_offset,
239 u64 start, u64 len, u64 disk_len,
240 int type, int compress_type)
241{
242 return __btrfs_add_ordered_extent(inode, file_offset, start, len,
243 disk_len, type, 0,
244 compress_type);
231} 245}
232 246
233/* 247/*
@@ -250,6 +264,73 @@ int btrfs_add_ordered_sum(struct inode *inode,
250 264
251/* 265/*
252 * this is used to account for finished IO across a given range 266 * this is used to account for finished IO across a given range
267 * of the file. The IO may span ordered extents. If
268 * a given ordered_extent is completely done, 1 is returned, otherwise
269 * 0.
270 *
271 * test_and_set_bit on a flag in the struct btrfs_ordered_extent is used
272 * to make sure this function only returns 1 once for a given ordered extent.
273 *
274 * file_offset is updated to one byte past the range that is recorded as
275 * complete. This allows you to walk forward in the file.
276 */
277int btrfs_dec_test_first_ordered_pending(struct inode *inode,
278 struct btrfs_ordered_extent **cached,
279 u64 *file_offset, u64 io_size)
280{
281 struct btrfs_ordered_inode_tree *tree;
282 struct rb_node *node;
283 struct btrfs_ordered_extent *entry = NULL;
284 int ret;
285 u64 dec_end;
286 u64 dec_start;
287 u64 to_dec;
288
289 tree = &BTRFS_I(inode)->ordered_tree;
290 spin_lock(&tree->lock);
291 node = tree_search(tree, *file_offset);
292 if (!node) {
293 ret = 1;
294 goto out;
295 }
296
297 entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
298 if (!offset_in_entry(entry, *file_offset)) {
299 ret = 1;
300 goto out;
301 }
302
303 dec_start = max(*file_offset, entry->file_offset);
304 dec_end = min(*file_offset + io_size, entry->file_offset +
305 entry->len);
306 *file_offset = dec_end;
307 if (dec_start > dec_end) {
308 printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n",
309 (unsigned long long)dec_start,
310 (unsigned long long)dec_end);
311 }
312 to_dec = dec_end - dec_start;
313 if (to_dec > entry->bytes_left) {
314 printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n",
315 (unsigned long long)entry->bytes_left,
316 (unsigned long long)to_dec);
317 }
318 entry->bytes_left -= to_dec;
319 if (entry->bytes_left == 0)
320 ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
321 else
322 ret = 1;
323out:
324 if (!ret && cached && entry) {
325 *cached = entry;
326 atomic_inc(&entry->refs);
327 }
328 spin_unlock(&tree->lock);
329 return ret == 0;
330}
331
332/*
333 * this is used to account for finished IO across a given range
253 * of the file. The IO should not span ordered extents. If 334 * of the file. The IO should not span ordered extents. If
254 * a given ordered_extent is completely done, 1 is returned, otherwise 335 * a given ordered_extent is completely done, 1 is returned, otherwise
255 * 0. 336 * 0.
@@ -308,6 +389,8 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
308 struct list_head *cur; 389 struct list_head *cur;
309 struct btrfs_ordered_sum *sum; 390 struct btrfs_ordered_sum *sum;
310 391
392 trace_btrfs_ordered_extent_put(entry->inode, entry);
393
311 if (atomic_dec_and_test(&entry->refs)) { 394 if (atomic_dec_and_test(&entry->refs)) {
312 while (!list_empty(&entry->list)) { 395 while (!list_empty(&entry->list)) {
313 cur = entry->list.next; 396 cur = entry->list.next;
@@ -341,6 +424,8 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
341 spin_lock(&root->fs_info->ordered_extent_lock); 424 spin_lock(&root->fs_info->ordered_extent_lock);
342 list_del_init(&entry->root_extent_list); 425 list_del_init(&entry->root_extent_list);
343 426
427 trace_btrfs_ordered_extent_remove(inode, entry);
428
344 /* 429 /*
345 * we have no more ordered extents for this inode and 430 * we have no more ordered extents for this inode and
346 * no dirty pages. We can safely remove it from the 431 * no dirty pages. We can safely remove it from the
@@ -506,6 +591,8 @@ void btrfs_start_ordered_extent(struct inode *inode,
506 u64 start = entry->file_offset; 591 u64 start = entry->file_offset;
507 u64 end = start + entry->len - 1; 592 u64 end = start + entry->len - 1;
508 593
594 trace_btrfs_ordered_extent_start(inode, entry);
595
509 /* 596 /*
510 * pages in the range can be dirty, clean or writeback. We 597 * pages in the range can be dirty, clean or writeback. We
511 * start IO on any dirty ones so the wait doesn't stall waiting 598 * start IO on any dirty ones so the wait doesn't stall waiting
@@ -526,7 +613,6 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
526{ 613{
527 u64 end; 614 u64 end;
528 u64 orig_end; 615 u64 orig_end;
529 u64 wait_end;
530 struct btrfs_ordered_extent *ordered; 616 struct btrfs_ordered_extent *ordered;
531 int found; 617 int found;
532 618
@@ -537,7 +623,6 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
537 if (orig_end > INT_LIMIT(loff_t)) 623 if (orig_end > INT_LIMIT(loff_t))
538 orig_end = INT_LIMIT(loff_t); 624 orig_end = INT_LIMIT(loff_t);
539 } 625 }
540 wait_end = orig_end;
541again: 626again:
542 /* start IO across the range first to instantiate any delalloc 627 /* start IO across the range first to instantiate any delalloc
543 * extents 628 * extents