diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-12-15 15:54:40 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-12-15 15:54:40 -0500 |
commit | 75eff68ea6959efd999b125fc3dcf73931a3b30b (patch) | |
tree | 8467dd51761446dd3539e515055671e707b5f5a0 /fs/btrfs/inode.c | |
parent | 42dc7babdcc99feadb04d461592ce5898a362550 (diff) |
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>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 34 |
1 files changed, 20 insertions, 14 deletions
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 |