summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-12-15 15:54:40 -0500
committerChris Mason <chris.mason@oracle.com>2008-12-15 15:54:40 -0500
commit75eff68ea6959efd999b125fc3dcf73931a3b30b (patch)
tree8467dd51761446dd3539e515055671e707b5f5a0
parent42dc7babdcc99feadb04d461592ce5898a362550 (diff)
downloadlinux-stable-75eff68ea6959efd999b125fc3dcf73931a3b30b.tar.gz
linux-stable-75eff68ea6959efd999b125fc3dcf73931a3b30b.tar.bz2
linux-stable-75eff68ea6959efd999b125fc3dcf73931a3b30b.zip
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: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/extent-tree.c12
-rw-r--r--fs/btrfs/inode.c34
2 files changed, 26 insertions, 20 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 8004695d24d6..fbd6a8f28b52 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -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);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5313a13a998d..0577e77e661d 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -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