diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 12 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 34 |
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: | |||
1047 | end = pos; | 1047 | end = pos; |
1048 | 1048 | ||
1049 | /* update the free space counters */ | 1049 | /* update the free space counters */ |
1050 | spin_lock_irq(&info->delalloc_lock); | 1050 | spin_lock(&info->delalloc_lock); |
1051 | super_used = btrfs_super_bytes_used(&info->super_copy); | 1051 | super_used = btrfs_super_bytes_used(&info->super_copy); |
1052 | btrfs_set_super_bytes_used(&info->super_copy, | 1052 | btrfs_set_super_bytes_used(&info->super_copy, |
1053 | super_used - bytes_freed); | 1053 | super_used - bytes_freed); |
1054 | spin_unlock_irq(&info->delalloc_lock); | 1054 | spin_unlock(&info->delalloc_lock); |
1055 | 1055 | ||
1056 | root_used = btrfs_root_used(&extent_root->root_item); | 1056 | root_used = btrfs_root_used(&extent_root->root_item); |
1057 | btrfs_set_root_used(&extent_root->root_item, | 1057 | btrfs_set_root_used(&extent_root->root_item, |
@@ -2463,11 +2463,11 @@ static int __free_extent(struct btrfs_trans_handle *trans, | |||
2463 | BUG_ON(ret < 0); | 2463 | BUG_ON(ret < 0); |
2464 | } | 2464 | } |
2465 | /* block accounting for super block */ | 2465 | /* block accounting for super block */ |
2466 | spin_lock_irq(&info->delalloc_lock); | 2466 | spin_lock(&info->delalloc_lock); |
2467 | super_used = btrfs_super_bytes_used(&info->super_copy); | 2467 | super_used = btrfs_super_bytes_used(&info->super_copy); |
2468 | btrfs_set_super_bytes_used(&info->super_copy, | 2468 | btrfs_set_super_bytes_used(&info->super_copy, |
2469 | super_used - num_bytes); | 2469 | super_used - num_bytes); |
2470 | spin_unlock_irq(&info->delalloc_lock); | 2470 | spin_unlock(&info->delalloc_lock); |
2471 | 2471 | ||
2472 | /* block accounting for root item */ | 2472 | /* block accounting for root item */ |
2473 | root_used = btrfs_root_used(&root->root_item); | 2473 | root_used = btrfs_root_used(&root->root_item); |
@@ -3151,10 +3151,10 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
3151 | parent = ins->objectid; | 3151 | parent = ins->objectid; |
3152 | 3152 | ||
3153 | /* block accounting for super block */ | 3153 | /* block accounting for super block */ |
3154 | spin_lock_irq(&info->delalloc_lock); | 3154 | spin_lock(&info->delalloc_lock); |
3155 | super_used = btrfs_super_bytes_used(&info->super_copy); | 3155 | super_used = btrfs_super_bytes_used(&info->super_copy); |
3156 | btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes); | 3156 | btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes); |
3157 | spin_unlock_irq(&info->delalloc_lock); | 3157 | spin_unlock(&info->delalloc_lock); |
3158 | 3158 | ||
3159 | /* block accounting for root item */ | 3159 | /* block accounting for root item */ |
3160 | root_used = btrfs_root_used(&root->root_item); | 3160 | 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, | |||
101 | u64 total; | 101 | u64 total; |
102 | u64 used; | 102 | u64 used; |
103 | u64 thresh; | 103 | u64 thresh; |
104 | unsigned long flags; | ||
105 | int ret = 0; | 104 | int ret = 0; |
106 | 105 | ||
107 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | 106 | spin_lock(&root->fs_info->delalloc_lock); |
108 | total = btrfs_super_total_bytes(&root->fs_info->super_copy); | 107 | total = btrfs_super_total_bytes(&root->fs_info->super_copy); |
109 | used = btrfs_super_bytes_used(&root->fs_info->super_copy); | 108 | used = btrfs_super_bytes_used(&root->fs_info->super_copy); |
110 | if (for_del) | 109 | if (for_del) |
@@ -116,7 +115,7 @@ int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, | |||
116 | 115 | ||
117 | if (used + root->fs_info->delalloc_bytes + num_required > thresh) | 116 | if (used + root->fs_info->delalloc_bytes + num_required > thresh) |
118 | ret = -ENOSPC; | 117 | ret = -ENOSPC; |
119 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 118 | spin_unlock(&root->fs_info->delalloc_lock); |
120 | return ret; | 119 | return ret; |
121 | } | 120 | } |
122 | 121 | ||
@@ -1166,17 +1165,21 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, | |||
1166 | static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | 1165 | static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, |
1167 | unsigned long old, unsigned long bits) | 1166 | unsigned long old, unsigned long bits) |
1168 | { | 1167 | { |
1169 | unsigned long flags; | 1168 | /* |
1169 | * set_bit and clear bit hooks normally require _irqsave/restore | ||
1170 | * but in this case, we are only testeing for the DELALLOC | ||
1171 | * bit, which is only set or cleared with irqs on | ||
1172 | */ | ||
1170 | if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { | 1173 | if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { |
1171 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1174 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1172 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | 1175 | spin_lock(&root->fs_info->delalloc_lock); |
1173 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; | 1176 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; |
1174 | root->fs_info->delalloc_bytes += end - start + 1; | 1177 | root->fs_info->delalloc_bytes += end - start + 1; |
1175 | if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | 1178 | if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) { |
1176 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, | 1179 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, |
1177 | &root->fs_info->delalloc_inodes); | 1180 | &root->fs_info->delalloc_inodes); |
1178 | } | 1181 | } |
1179 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 1182 | spin_unlock(&root->fs_info->delalloc_lock); |
1180 | } | 1183 | } |
1181 | return 0; | 1184 | return 0; |
1182 | } | 1185 | } |
@@ -1187,11 +1190,15 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | |||
1187 | static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, | 1190 | static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, |
1188 | unsigned long old, unsigned long bits) | 1191 | unsigned long old, unsigned long bits) |
1189 | { | 1192 | { |
1193 | /* | ||
1194 | * set_bit and clear bit hooks normally require _irqsave/restore | ||
1195 | * but in this case, we are only testeing for the DELALLOC | ||
1196 | * bit, which is only set or cleared with irqs on | ||
1197 | */ | ||
1190 | if ((old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { | 1198 | if ((old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { |
1191 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1199 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1192 | unsigned long flags; | ||
1193 | 1200 | ||
1194 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | 1201 | spin_lock(&root->fs_info->delalloc_lock); |
1195 | if (end - start + 1 > root->fs_info->delalloc_bytes) { | 1202 | if (end - start + 1 > root->fs_info->delalloc_bytes) { |
1196 | printk("warning: delalloc account %Lu %Lu\n", | 1203 | printk("warning: delalloc account %Lu %Lu\n", |
1197 | end - start + 1, root->fs_info->delalloc_bytes); | 1204 | 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 | !list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | 1212 | !list_empty(&BTRFS_I(inode)->delalloc_inodes)) { |
1206 | list_del_init(&BTRFS_I(inode)->delalloc_inodes); | 1213 | list_del_init(&BTRFS_I(inode)->delalloc_inodes); |
1207 | } | 1214 | } |
1208 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 1215 | spin_unlock(&root->fs_info->delalloc_lock); |
1209 | } | 1216 | } |
1210 | return 0; | 1217 | return 0; |
1211 | } | 1218 | } |
@@ -4651,27 +4658,26 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root) | |||
4651 | struct list_head *head = &root->fs_info->delalloc_inodes; | 4658 | struct list_head *head = &root->fs_info->delalloc_inodes; |
4652 | struct btrfs_inode *binode; | 4659 | struct btrfs_inode *binode; |
4653 | struct inode *inode; | 4660 | struct inode *inode; |
4654 | unsigned long flags; | ||
4655 | 4661 | ||
4656 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 4662 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
4657 | return -EROFS; | 4663 | return -EROFS; |
4658 | 4664 | ||
4659 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | 4665 | spin_lock(&root->fs_info->delalloc_lock); |
4660 | while(!list_empty(head)) { | 4666 | while(!list_empty(head)) { |
4661 | binode = list_entry(head->next, struct btrfs_inode, | 4667 | binode = list_entry(head->next, struct btrfs_inode, |
4662 | delalloc_inodes); | 4668 | delalloc_inodes); |
4663 | inode = igrab(&binode->vfs_inode); | 4669 | inode = igrab(&binode->vfs_inode); |
4664 | if (!inode) | 4670 | if (!inode) |
4665 | list_del_init(&binode->delalloc_inodes); | 4671 | list_del_init(&binode->delalloc_inodes); |
4666 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 4672 | spin_unlock(&root->fs_info->delalloc_lock); |
4667 | if (inode) { | 4673 | if (inode) { |
4668 | filemap_flush(inode->i_mapping); | 4674 | filemap_flush(inode->i_mapping); |
4669 | iput(inode); | 4675 | iput(inode); |
4670 | } | 4676 | } |
4671 | cond_resched(); | 4677 | cond_resched(); |
4672 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | 4678 | spin_lock(&root->fs_info->delalloc_lock); |
4673 | } | 4679 | } |
4674 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 4680 | spin_unlock(&root->fs_info->delalloc_lock); |
4675 | 4681 | ||
4676 | /* the filemap_flush will queue IO into the worker threads, but | 4682 | /* the filemap_flush will queue IO into the worker threads, but |
4677 | * we have to make sure the IO is actually started and that | 4683 | * we have to make sure the IO is actually started and that |