Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 128873
b: refs/heads/master
c: f87f057
h: refs/heads/master
i:
  128871: f1d875e
v: v3
  • Loading branch information
Chris Mason committed Sep 25, 2008
1 parent d1f4612 commit c27da3f
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 492bb6deee3416ad792dcd8584ebd95c463af1a6
refs/heads/master: f87f057b49ee52cf5c627ab27a706e3252767c9f
85 changes: 56 additions & 29 deletions trunk/fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2333,8 +2333,6 @@ static int noinline drop_leaf_ref_no_cache(struct btrfs_trans_handle *trans,
leaf_owner = btrfs_header_owner(leaf);
leaf_generation = btrfs_header_generation(leaf);

mutex_unlock(&root->fs_info->alloc_mutex);

for (i = 0; i < nritems; i++) {
u64 disk_bytenr;
cond_resched();
Expand Down Expand Up @@ -2362,8 +2360,6 @@ static int noinline drop_leaf_ref_no_cache(struct btrfs_trans_handle *trans,
mutex_unlock(&root->fs_info->alloc_mutex);
BUG_ON(ret);
}

mutex_lock(&root->fs_info->alloc_mutex);
return 0;
}

Expand All @@ -2375,7 +2371,6 @@ static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans,
int ret;
struct btrfs_extent_info *info = ref->extents;

mutex_unlock(&root->fs_info->alloc_mutex);
for (i = 0; i < ref->nritems; i++) {
mutex_lock(&root->fs_info->alloc_mutex);
ret = __btrfs_free_extent(trans, root,
Expand All @@ -2386,7 +2381,6 @@ static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans,
BUG_ON(ret);
info++;
}
mutex_lock(&root->fs_info->alloc_mutex);

return 0;
}
Expand Down Expand Up @@ -2440,10 +2434,39 @@ int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len,
u32 *refs)
{
int ret;
mutex_unlock(&root->fs_info->alloc_mutex);

ret = lookup_extent_ref(NULL, root, start, len, refs);
BUG_ON(ret);

#if 0 // some debugging code in case we see problems here
/* if the refs count is one, it won't get increased again. But
* if the ref count is > 1, someone may be decreasing it at
* the same time we are.
*/
if (*refs != 1) {
struct extent_buffer *eb = NULL;
eb = btrfs_find_create_tree_block(root, start, len);
if (eb)
btrfs_tree_lock(eb);

mutex_lock(&root->fs_info->alloc_mutex);
ret = lookup_extent_ref(NULL, root, start, len, refs);
BUG_ON(ret);
mutex_unlock(&root->fs_info->alloc_mutex);

if (eb) {
btrfs_tree_unlock(eb);
free_extent_buffer(eb);
}
if (*refs == 1) {
printk("block %llu went down to one during drop_snap\n",
(unsigned long long)start);
}

}
#endif

cond_resched();
mutex_lock(&root->fs_info->alloc_mutex);
return ret;
}

Expand All @@ -2467,8 +2490,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
int ret;
u32 refs;

mutex_lock(&root->fs_info->alloc_mutex);

WARN_ON(*level < 0);
WARN_ON(*level >= BTRFS_MAX_LEVEL);
ret = drop_snap_lookup_refcount(root, path->nodes[*level]->start,
Expand Down Expand Up @@ -2507,13 +2528,21 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
root_owner = btrfs_header_owner(parent);
root_gen = btrfs_header_generation(parent);
path->slots[*level]++;

mutex_lock(&root->fs_info->alloc_mutex);
ret = __btrfs_free_extent(trans, root, bytenr,
blocksize, root_owner,
root_gen, 0, 0, 1);
BUG_ON(ret);
mutex_unlock(&root->fs_info->alloc_mutex);
continue;
}

/*
* at this point, we have a single ref, and since the
* only place referencing this extent is a dead root
* the reference count should never go higher.
* So, we don't need to check it again
*/
if (*level == 1) {
struct btrfs_key key;
btrfs_node_key_to_cpu(cur, &key, path->slots[*level]);
Expand All @@ -2533,33 +2562,23 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
next = btrfs_find_tree_block(root, bytenr, blocksize);
if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
free_extent_buffer(next);
mutex_unlock(&root->fs_info->alloc_mutex);

if (path->slots[*level] == 0)
reada_walk_down(root, cur, path->slots[*level]);
next = read_tree_block(root, bytenr, blocksize,
ptr_gen);
cond_resched();
mutex_lock(&root->fs_info->alloc_mutex);

/* we've dropped the lock, double check */
#if 0
/*
* this is a debugging check and can go away
* the ref should never go all the way down to 1
* at this point
*/
ret = lookup_extent_ref(NULL, root, bytenr, blocksize,
&refs);
BUG_ON(ret);
if (refs != 1) {
parent = path->nodes[*level];
root_owner = btrfs_header_owner(parent);
root_gen = btrfs_header_generation(parent);

path->slots[*level]++;
free_extent_buffer(next);
ret = __btrfs_free_extent(trans, root, bytenr,
blocksize,
root_owner,
root_gen, 0, 0, 1);
BUG_ON(ret);
continue;
}
WARN_ON(refs != 1);
#endif
}
WARN_ON(*level <= 0);
if (path->nodes[*level-1])
Expand All @@ -2584,13 +2603,16 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
root_owner = btrfs_header_owner(parent);
root_gen = btrfs_header_generation(parent);


mutex_lock(&root->fs_info->alloc_mutex);
ret = __btrfs_free_extent(trans, root, bytenr, blocksize,
root_owner, root_gen, 0, 0, 1);
free_extent_buffer(path->nodes[*level]);
path->nodes[*level] = NULL;
*level += 1;
BUG_ON(ret);
mutex_unlock(&root->fs_info->alloc_mutex);

cond_resched();
return 0;
}
Expand Down Expand Up @@ -2834,6 +2856,11 @@ static int noinline relocate_inode_pages(struct inode *inode, u64 start,
}
set_page_extent_mapped(page);

/*
* make sure page_mkwrite is called for this page if userland
* wants to change it from mmap
*/
clear_page_dirty_for_io(page);

set_extent_delalloc(io_tree, page_start,
page_end, GFP_NOFS);
Expand Down
13 changes: 8 additions & 5 deletions trunk/fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,13 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
btrfs_drop_extent_cache(inode, start_pos, aligned_end - 1);
BUG_ON(err);
mutex_unlock(&BTRFS_I(inode)->extent_mutex);

/*
* an ugly way to do all the prop accounting around
* the page bits and mapping tags
*/
set_page_writeback(pages[0]);
end_page_writeback(pages[0]);
did_inline = 1;
}
if (end_pos > isize) {
Expand Down Expand Up @@ -833,11 +840,7 @@ static int prepare_pages(struct btrfs_root *root, struct file *file,
start_pos, last_pos - 1, GFP_NOFS);
}
for (i = 0; i < num_pages; i++) {
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
ClearPageDirty(pages[i]);
#else
cancel_dirty_page(pages[i], PAGE_CACHE_SIZE);
#endif
clear_page_dirty_for_io(pages[i]);
set_page_extent_mapped(pages[i]);
WARN_ON(!PageLocked(pages[i]));
}
Expand Down
6 changes: 6 additions & 0 deletions trunk/fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ int btrfs_defrag_file(struct file *file)
}
set_page_extent_mapped(page);

/*
* this makes sure page_mkwrite is called on the
* page if it is dirtied again later
*/
clear_page_dirty_for_io(page);

set_extent_delalloc(io_tree, page_start,
page_end, GFP_NOFS);

Expand Down

0 comments on commit c27da3f

Please sign in to comment.