Skip to content

Commit 43be214

Browse files
Josef Bacikchrismason-xx
authored andcommitted
Btrfs: fix free space cache when there are pinned extents and clusters V2
I noticed a huge problem with the free space cache that was presenting as an early ENOSPC. Turns out when writing the free space cache out I forgot to take into account pinned extents and more importantly clusters. This would result in us leaking free space everytime we unmounted the filesystem and remounted it. I fix this by making sure to check and see if the current block group has a cluster and writing out any entries that are in the cluster to the cache, as well as writing any pinned extents we currently have to the cache since those will be available for us to use the next time the fs mounts. This patch also adds a check to the end of load_free_space_cache to make sure we got the right amount of free space cache, and if not make sure to clear the cache and re-cache the old fashioned way. Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
1 parent 08fe4db commit 43be214

File tree

1 file changed

+78
-4
lines changed

1 file changed

+78
-4
lines changed

fs/btrfs/free-space-cache.c

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "free-space-cache.h"
2525
#include "transaction.h"
2626
#include "disk-io.h"
27+
#include "extent_io.h"
2728

2829
#define BITS_PER_BITMAP (PAGE_CACHE_SIZE * 8)
2930
#define MAX_CACHE_BYTES_PER_GIG (32 * 1024)
@@ -224,6 +225,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
224225
u64 num_entries;
225226
u64 num_bitmaps;
226227
u64 generation;
228+
u64 used = btrfs_block_group_used(&block_group->item);
227229
u32 cur_crc = ~(u32)0;
228230
pgoff_t index = 0;
229231
unsigned long first_page_offset;
@@ -469,6 +471,17 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
469471
index++;
470472
}
471473

474+
spin_lock(&block_group->tree_lock);
475+
if (block_group->free_space != (block_group->key.offset - used -
476+
block_group->bytes_super)) {
477+
spin_unlock(&block_group->tree_lock);
478+
printk(KERN_ERR "block group %llu has an wrong amount of free "
479+
"space\n", block_group->key.objectid);
480+
ret = 0;
481+
goto free_cache;
482+
}
483+
spin_unlock(&block_group->tree_lock);
484+
472485
ret = 1;
473486
out:
474487
kfree(checksums);
@@ -497,8 +510,11 @@ int btrfs_write_out_cache(struct btrfs_root *root,
497510
struct list_head *pos, *n;
498511
struct page *page;
499512
struct extent_state *cached_state = NULL;
513+
struct btrfs_free_cluster *cluster = NULL;
514+
struct extent_io_tree *unpin = NULL;
500515
struct list_head bitmap_list;
501516
struct btrfs_key key;
517+
u64 start, end, len;
502518
u64 bytes = 0;
503519
u32 *crc, *checksums;
504520
pgoff_t index = 0, last_index = 0;
@@ -507,6 +523,7 @@ int btrfs_write_out_cache(struct btrfs_root *root,
507523
int entries = 0;
508524
int bitmaps = 0;
509525
int ret = 0;
526+
bool next_page = false;
510527

511528
root = root->fs_info->tree_root;
512529

@@ -553,6 +570,18 @@ int btrfs_write_out_cache(struct btrfs_root *root,
553570
*/
554571
first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64);
555572

573+
/* Get the cluster for this block_group if it exists */
574+
if (!list_empty(&block_group->cluster_list))
575+
cluster = list_entry(block_group->cluster_list.next,
576+
struct btrfs_free_cluster,
577+
block_group_list);
578+
579+
/*
580+
* We shouldn't have switched the pinned extents yet so this is the
581+
* right one
582+
*/
583+
unpin = root->fs_info->pinned_extents;
584+
556585
/*
557586
* Lock all pages first so we can lock the extent safely.
558587
*
@@ -582,13 +611,21 @@ int btrfs_write_out_cache(struct btrfs_root *root,
582611
lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
583612
0, &cached_state, GFP_NOFS);
584613

614+
/*
615+
* When searching for pinned extents, we need to start at our start
616+
* offset.
617+
*/
618+
start = block_group->key.objectid;
619+
585620
/* Write out the extent entries */
586621
do {
587622
struct btrfs_free_space_entry *entry;
588623
void *addr;
589624
unsigned long offset = 0;
590625
unsigned long start_offset = 0;
591626

627+
next_page = false;
628+
592629
if (index == 0) {
593630
start_offset = first_page_offset;
594631
offset = start_offset;
@@ -600,7 +637,7 @@ int btrfs_write_out_cache(struct btrfs_root *root,
600637
entry = addr + start_offset;
601638

602639
memset(addr, 0, PAGE_CACHE_SIZE);
603-
while (1) {
640+
while (node && !next_page) {
604641
struct btrfs_free_space *e;
605642

606643
e = rb_entry(node, struct btrfs_free_space, offset_index);
@@ -616,12 +653,49 @@ int btrfs_write_out_cache(struct btrfs_root *root,
616653
entry->type = BTRFS_FREE_SPACE_EXTENT;
617654
}
618655
node = rb_next(node);
619-
if (!node)
620-
break;
656+
if (!node && cluster) {
657+
node = rb_first(&cluster->root);
658+
cluster = NULL;
659+
}
621660
offset += sizeof(struct btrfs_free_space_entry);
622661
if (offset + sizeof(struct btrfs_free_space_entry) >=
623662
PAGE_CACHE_SIZE)
663+
next_page = true;
664+
entry++;
665+
}
666+
667+
/*
668+
* We want to add any pinned extents to our free space cache
669+
* so we don't leak the space
670+
*/
671+
while (!next_page && (start < block_group->key.objectid +
672+
block_group->key.offset)) {
673+
ret = find_first_extent_bit(unpin, start, &start, &end,
674+
EXTENT_DIRTY);
675+
if (ret) {
676+
ret = 0;
677+
break;
678+
}
679+
680+
/* This pinned extent is out of our range */
681+
if (start >= block_group->key.objectid +
682+
block_group->key.offset)
624683
break;
684+
685+
len = block_group->key.objectid +
686+
block_group->key.offset - start;
687+
len = min(len, end + 1 - start);
688+
689+
entries++;
690+
entry->offset = cpu_to_le64(start);
691+
entry->bytes = cpu_to_le64(len);
692+
entry->type = BTRFS_FREE_SPACE_EXTENT;
693+
694+
start = end + 1;
695+
offset += sizeof(struct btrfs_free_space_entry);
696+
if (offset + sizeof(struct btrfs_free_space_entry) >=
697+
PAGE_CACHE_SIZE)
698+
next_page = true;
625699
entry++;
626700
}
627701
*crc = ~(u32)0;
@@ -652,7 +726,7 @@ int btrfs_write_out_cache(struct btrfs_root *root,
652726
page_cache_release(page);
653727

654728
index++;
655-
} while (node);
729+
} while (node || next_page);
656730

657731
/* Write out the bitmaps */
658732
list_for_each_safe(pos, n, &bitmap_list) {

0 commit comments

Comments
 (0)