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 @@ search:
end = pos;
/* 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);
btrfs_set_super_bytes_used(&info->super_copy,
super_used - bytes_freed);
spin_unlock_irq(&info->delalloc_lock);
spin_unlock(&info->delalloc_lock);
root_used = btrfs_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,
BUG_ON(ret < 0);
}
/* 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);
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 */
root_used = btrfs_root_used(&root->root_item);
......@@ -3151,10 +3151,10 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans,
parent = ins->objectid;
/* 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);
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 */
root_used = btrfs_root_used(&root->root_item);
......
......@@ -101,10 +101,9 @@ int btrfs_check_free_space(struct btrfs_root *root, u64 num_required,
u64 total;
u64 used;
u64 thresh;
unsigned long flags;
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);
used = btrfs_super_bytes_used(&root->fs_info->super_copy);
if (for_del)
......@@ -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)
ret = -ENOSPC;
spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
spin_unlock(&root->fs_info->delalloc_lock);
return ret;
}
......@@ -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,
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)) {
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;
root->fs_info->delalloc_bytes += end - start + 1;
if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
list_add_tail(&BTRFS_I(inode)->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;
}
......@@ -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,
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)) {
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) {
printk("warning: delalloc account %Lu %Lu\n",
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,
!list_empty(&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;
}
......@@ -4651,27 +4658,26 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root)
struct list_head *head = &root->fs_info->delalloc_inodes;
struct btrfs_inode *binode;
struct inode *inode;
unsigned long flags;
if (root->fs_info->sb->s_flags & MS_RDONLY)
return -EROFS;
spin_lock_irqsave(&root->fs_info->delalloc_lock, flags);
spin_lock(&root->fs_info->delalloc_lock);
while(!list_empty(head)) {
binode = list_entry(head->next, struct btrfs_inode,
delalloc_inodes);
inode = igrab(&binode->vfs_inode);
if (!inode)
list_del_init(&binode->delalloc_inodes);
spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
spin_unlock(&root->fs_info->delalloc_lock);
if (inode) {
filemap_flush(inode->i_mapping);
iput(inode);
}
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
* 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