Commit 75eff68e authored by Chris Mason's avatar Chris Mason

Btrfs: Don't use spin*lock_irq for the delalloc lock

The delalloc lock doesn't need to have irqs disabled, nobody that
changes the number of delalloc bytes in the FS is running with irqs off.
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 42dc7bab
...@@ -1047,11 +1047,11 @@ static int noinline free_extents(struct btrfs_trans_handle *trans, ...@@ -1047,11 +1047,11 @@ static int noinline free_extents(struct btrfs_trans_handle *trans,
end = pos; end = pos;
/* update the free space counters */ /* update the free space counters */
spin_lock_irq(&info->delalloc_lock); spin_lock(&info->delalloc_lock);
super_used = btrfs_super_bytes_used(&info->super_copy); super_used = btrfs_super_bytes_used(&info->super_copy);
btrfs_set_super_bytes_used(&info->super_copy, btrfs_set_super_bytes_used(&info->super_copy,
super_used - bytes_freed); super_used - bytes_freed);
spin_unlock_irq(&info->delalloc_lock); spin_unlock(&info->delalloc_lock);
root_used = btrfs_root_used(&extent_root->root_item); root_used = btrfs_root_used(&extent_root->root_item);
btrfs_set_root_used(&extent_root->root_item, btrfs_set_root_used(&extent_root->root_item,
...@@ -2463,11 +2463,11 @@ static int __free_extent(struct btrfs_trans_handle *trans, ...@@ -2463,11 +2463,11 @@ static int __free_extent(struct btrfs_trans_handle *trans,
BUG_ON(ret < 0); BUG_ON(ret < 0);
} }
/* block accounting for super block */ /* block accounting for super block */
spin_lock_irq(&info->delalloc_lock); spin_lock(&info->delalloc_lock);
super_used = btrfs_super_bytes_used(&info->super_copy); super_used = btrfs_super_bytes_used(&info->super_copy);
btrfs_set_super_bytes_used(&info->super_copy, btrfs_set_super_bytes_used(&info->super_copy,
super_used - num_bytes); super_used - num_bytes);
spin_unlock_irq(&info->delalloc_lock); spin_unlock(&info->delalloc_lock);
/* block accounting for root item */ /* block accounting for root item */
root_used = btrfs_root_used(&root->root_item); root_used = btrfs_root_used(&root->root_item);
...@@ -3151,10 +3151,10 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, ...@@ -3151,10 +3151,10 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans,
parent = ins->objectid; parent = ins->objectid;
/* block accounting for super block */ /* block accounting for super block */
spin_lock_irq(&info->delalloc_lock); spin_lock(&info->delalloc_lock);
super_used = btrfs_super_bytes_used(&info->super_copy); super_used = btrfs_super_bytes_used(&info->super_copy);
btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes); btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes);
spin_unlock_irq(&info->delalloc_lock); spin_unlock(&info->delalloc_lock);
/* block accounting for root item */ /* block accounting for root item */
root_used = btrfs_root_used(&root->root_item); root_used = btrfs_root_used(&root->root_item);
......
...@@ -101,10 +101,9 @@ int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, ...@@ -101,10 +101,9 @@ int btrfs_check_free_space(struct btrfs_root *root, u64 num_required,
u64 total; u64 total;
u64 used; u64 used;
u64 thresh; u64 thresh;
unsigned long flags;
int ret = 0; int ret = 0;
spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); spin_lock(&root->fs_info->delalloc_lock);
total = btrfs_super_total_bytes(&root->fs_info->super_copy); total = btrfs_super_total_bytes(&root->fs_info->super_copy);
used = btrfs_super_bytes_used(&root->fs_info->super_copy); used = btrfs_super_bytes_used(&root->fs_info->super_copy);
if (for_del) if (for_del)
...@@ -116,7 +115,7 @@ int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, ...@@ -116,7 +115,7 @@ int btrfs_check_free_space(struct btrfs_root *root, u64 num_required,
if (used + root->fs_info->delalloc_bytes + num_required > thresh) if (used + root->fs_info->delalloc_bytes + num_required > thresh)
ret = -ENOSPC; ret = -ENOSPC;
spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); spin_unlock(&root->fs_info->delalloc_lock);
return ret; return ret;
} }
...@@ -1166,17 +1165,21 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, ...@@ -1166,17 +1165,21 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
unsigned long old, unsigned long bits) unsigned long old, unsigned long bits)
{ {
unsigned long flags; /*
* set_bit and clear bit hooks normally require _irqsave/restore
* but in this case, we are only testeing for the DELALLOC
* bit, which is only set or cleared with irqs on
*/
if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); spin_lock(&root->fs_info->delalloc_lock);
BTRFS_I(inode)->delalloc_bytes += end - start + 1; BTRFS_I(inode)->delalloc_bytes += end - start + 1;
root->fs_info->delalloc_bytes += end - start + 1; root->fs_info->delalloc_bytes += end - start + 1;
if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) { if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
list_add_tail(&BTRFS_I(inode)->delalloc_inodes, list_add_tail(&BTRFS_I(inode)->delalloc_inodes,
&root->fs_info->delalloc_inodes); &root->fs_info->delalloc_inodes);
} }
spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); spin_unlock(&root->fs_info->delalloc_lock);
} }
return 0; return 0;
} }
...@@ -1187,11 +1190,15 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, ...@@ -1187,11 +1190,15 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
unsigned long old, unsigned long bits) unsigned long old, unsigned long bits)
{ {
/*
* set_bit and clear bit hooks normally require _irqsave/restore
* but in this case, we are only testeing for the DELALLOC
* bit, which is only set or cleared with irqs on
*/
if ((old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { if ((old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
unsigned long flags;
spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); spin_lock(&root->fs_info->delalloc_lock);
if (end - start + 1 > root->fs_info->delalloc_bytes) { if (end - start + 1 > root->fs_info->delalloc_bytes) {
printk("warning: delalloc account %Lu %Lu\n", printk("warning: delalloc account %Lu %Lu\n",
end - start + 1, root->fs_info->delalloc_bytes); end - start + 1, root->fs_info->delalloc_bytes);
...@@ -1205,7 +1212,7 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, ...@@ -1205,7 +1212,7 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
!list_empty(&BTRFS_I(inode)->delalloc_inodes)) { !list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
list_del_init(&BTRFS_I(inode)->delalloc_inodes); list_del_init(&BTRFS_I(inode)->delalloc_inodes);
} }
spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); spin_unlock(&root->fs_info->delalloc_lock);
} }
return 0; return 0;
} }
...@@ -4651,27 +4658,26 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root) ...@@ -4651,27 +4658,26 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root)
struct list_head *head = &root->fs_info->delalloc_inodes; struct list_head *head = &root->fs_info->delalloc_inodes;
struct btrfs_inode *binode; struct btrfs_inode *binode;
struct inode *inode; struct inode *inode;
unsigned long flags;
if (root->fs_info->sb->s_flags & MS_RDONLY) if (root->fs_info->sb->s_flags & MS_RDONLY)
return -EROFS; return -EROFS;
spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); spin_lock(&root->fs_info->delalloc_lock);
while(!list_empty(head)) { while(!list_empty(head)) {
binode = list_entry(head->next, struct btrfs_inode, binode = list_entry(head->next, struct btrfs_inode,
delalloc_inodes); delalloc_inodes);
inode = igrab(&binode->vfs_inode); inode = igrab(&binode->vfs_inode);
if (!inode) if (!inode)
list_del_init(&binode->delalloc_inodes); list_del_init(&binode->delalloc_inodes);
spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); spin_unlock(&root->fs_info->delalloc_lock);
if (inode) { if (inode) {
filemap_flush(inode->i_mapping); filemap_flush(inode->i_mapping);
iput(inode); iput(inode);
} }
cond_resched(); cond_resched();
spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); spin_lock(&root->fs_info->delalloc_lock);
} }
spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); spin_unlock(&root->fs_info->delalloc_lock);
/* the filemap_flush will queue IO into the worker threads, but /* the filemap_flush will queue IO into the worker threads, but
* we have to make sure the IO is actually started and that * we have to make sure the IO is actually started and that
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment