aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/free-space-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
-rw-r--r--fs/btrfs/free-space-cache.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 202008ec367d..81296c57405a 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -33,6 +33,8 @@
33 33
34static int link_free_space(struct btrfs_free_space_ctl *ctl, 34static int link_free_space(struct btrfs_free_space_ctl *ctl,
35 struct btrfs_free_space *info); 35 struct btrfs_free_space *info);
36static void unlink_free_space(struct btrfs_free_space_ctl *ctl,
37 struct btrfs_free_space *info);
36 38
37static struct inode *__lookup_free_space_inode(struct btrfs_root *root, 39static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
38 struct btrfs_path *path, 40 struct btrfs_path *path,
@@ -75,7 +77,8 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
75 return ERR_PTR(-ENOENT); 77 return ERR_PTR(-ENOENT);
76 } 78 }
77 79
78 inode->i_mapping->flags &= ~__GFP_FS; 80 mapping_set_gfp_mask(inode->i_mapping,
81 mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
79 82
80 return inode; 83 return inode;
81} 84}
@@ -365,7 +368,7 @@ static int io_ctl_prepare_pages(struct io_ctl *io_ctl, struct inode *inode,
365 368
366static void io_ctl_set_generation(struct io_ctl *io_ctl, u64 generation) 369static void io_ctl_set_generation(struct io_ctl *io_ctl, u64 generation)
367{ 370{
368 u64 *val; 371 __le64 *val;
369 372
370 io_ctl_map_page(io_ctl, 1); 373 io_ctl_map_page(io_ctl, 1);
371 374
@@ -388,7 +391,7 @@ static void io_ctl_set_generation(struct io_ctl *io_ctl, u64 generation)
388 391
389static int io_ctl_check_generation(struct io_ctl *io_ctl, u64 generation) 392static int io_ctl_check_generation(struct io_ctl *io_ctl, u64 generation)
390{ 393{
391 u64 *gen; 394 __le64 *gen;
392 395
393 /* 396 /*
394 * Skip the crc area. If we don't check crcs then we just have a 64bit 397 * Skip the crc area. If we don't check crcs then we just have a 64bit
@@ -584,6 +587,44 @@ static int io_ctl_read_bitmap(struct io_ctl *io_ctl,
584 return 0; 587 return 0;
585} 588}
586 589
590/*
591 * Since we attach pinned extents after the fact we can have contiguous sections
592 * of free space that are split up in entries. This poses a problem with the
593 * tree logging stuff since it could have allocated across what appears to be 2
594 * entries since we would have merged the entries when adding the pinned extents
595 * back to the free space cache. So run through the space cache that we just
596 * loaded and merge contiguous entries. This will make the log replay stuff not
597 * blow up and it will make for nicer allocator behavior.
598 */
599static void merge_space_tree(struct btrfs_free_space_ctl *ctl)
600{
601 struct btrfs_free_space *e, *prev = NULL;
602 struct rb_node *n;
603
604again:
605 spin_lock(&ctl->tree_lock);
606 for (n = rb_first(&ctl->free_space_offset); n; n = rb_next(n)) {
607 e = rb_entry(n, struct btrfs_free_space, offset_index);
608 if (!prev)
609 goto next;
610 if (e->bitmap || prev->bitmap)
611 goto next;
612 if (prev->offset + prev->bytes == e->offset) {
613 unlink_free_space(ctl, prev);
614 unlink_free_space(ctl, e);
615 prev->bytes += e->bytes;
616 kmem_cache_free(btrfs_free_space_cachep, e);
617 link_free_space(ctl, prev);
618 prev = NULL;
619 spin_unlock(&ctl->tree_lock);
620 goto again;
621 }
622next:
623 prev = e;
624 }
625 spin_unlock(&ctl->tree_lock);
626}
627
587int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, 628int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
588 struct btrfs_free_space_ctl *ctl, 629 struct btrfs_free_space_ctl *ctl,
589 struct btrfs_path *path, u64 offset) 630 struct btrfs_path *path, u64 offset)
@@ -726,6 +767,7 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
726 } 767 }
727 768
728 io_ctl_drop_pages(&io_ctl); 769 io_ctl_drop_pages(&io_ctl);
770 merge_space_tree(ctl);
729 ret = 1; 771 ret = 1;
730out: 772out:
731 io_ctl_free(&io_ctl); 773 io_ctl_free(&io_ctl);
@@ -972,9 +1014,7 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
972 goto out; 1014 goto out;
973 1015
974 1016
975 ret = filemap_write_and_wait(inode->i_mapping); 1017 btrfs_wait_ordered_range(inode, 0, (u64)-1);
976 if (ret)
977 goto out;
978 1018
979 key.objectid = BTRFS_FREE_SPACE_OBJECTID; 1019 key.objectid = BTRFS_FREE_SPACE_OBJECTID;
980 key.offset = offset; 1020 key.offset = offset;