diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 640648c66b22..8a405a5fa6a3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -303,6 +303,10 @@ int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | |||
303 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | 303 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); |
304 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; | 304 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; |
305 | root->fs_info->delalloc_bytes += end - start + 1; | 305 | root->fs_info->delalloc_bytes += end - start + 1; |
306 | if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | ||
307 | list_add_tail(&BTRFS_I(inode)->delalloc_inodes, | ||
308 | &root->fs_info->delalloc_inodes); | ||
309 | } | ||
306 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 310 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); |
307 | } | 311 | } |
308 | return 0; | 312 | return 0; |
@@ -325,6 +329,10 @@ int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, | |||
325 | root->fs_info->delalloc_bytes -= end - start + 1; | 329 | root->fs_info->delalloc_bytes -= end - start + 1; |
326 | BTRFS_I(inode)->delalloc_bytes -= end - start + 1; | 330 | BTRFS_I(inode)->delalloc_bytes -= end - start + 1; |
327 | } | 331 | } |
332 | if (BTRFS_I(inode)->delalloc_bytes == 0 && | ||
333 | !list_empty(&BTRFS_I(inode)->delalloc_inodes)) { | ||
334 | list_del_init(&BTRFS_I(inode)->delalloc_inodes); | ||
335 | } | ||
328 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | 336 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); |
329 | } | 337 | } |
330 | return 0; | 338 | return 0; |
@@ -408,6 +416,12 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, | |||
408 | return 0; | 416 | return 0; |
409 | } | 417 | } |
410 | 418 | ||
419 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end) | ||
420 | { | ||
421 | return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, | ||
422 | GFP_NOFS); | ||
423 | } | ||
424 | |||
411 | struct btrfs_writepage_fixup { | 425 | struct btrfs_writepage_fixup { |
412 | struct page *page; | 426 | struct page *page; |
413 | struct btrfs_work work; | 427 | struct btrfs_work work; |
@@ -453,8 +467,7 @@ again: | |||
453 | goto again; | 467 | goto again; |
454 | } | 468 | } |
455 | 469 | ||
456 | set_extent_delalloc(&BTRFS_I(inode)->io_tree, page_start, page_end, | 470 | btrfs_set_extent_delalloc(inode, page_start, page_end); |
457 | GFP_NOFS); | ||
458 | ClearPageChecked(page); | 471 | ClearPageChecked(page); |
459 | out: | 472 | out: |
460 | unlock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); | 473 | unlock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); |
@@ -1530,8 +1543,7 @@ again: | |||
1530 | goto again; | 1543 | goto again; |
1531 | } | 1544 | } |
1532 | 1545 | ||
1533 | set_extent_delalloc(&BTRFS_I(inode)->io_tree, page_start, | 1546 | btrfs_set_extent_delalloc(inode, page_start, page_end); |
1534 | page_end, GFP_NOFS); | ||
1535 | ret = 0; | 1547 | ret = 0; |
1536 | if (offset != PAGE_CACHE_SIZE) { | 1548 | if (offset != PAGE_CACHE_SIZE) { |
1537 | kaddr = kmap(page); | 1549 | kaddr = kmap(page); |
@@ -1766,6 +1778,7 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) | |||
1766 | inode->i_mapping, GFP_NOFS); | 1778 | inode->i_mapping, GFP_NOFS); |
1767 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 1779 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
1768 | inode->i_mapping, GFP_NOFS); | 1780 | inode->i_mapping, GFP_NOFS); |
1781 | INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes); | ||
1769 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); | 1782 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); |
1770 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 1783 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
1771 | mutex_init(&BTRFS_I(inode)->extent_mutex); | 1784 | mutex_init(&BTRFS_I(inode)->extent_mutex); |
@@ -2158,6 +2171,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
2158 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 2171 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
2159 | inode->i_mapping, GFP_NOFS); | 2172 | inode->i_mapping, GFP_NOFS); |
2160 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); | 2173 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); |
2174 | INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes); | ||
2161 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 2175 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
2162 | mutex_init(&BTRFS_I(inode)->extent_mutex); | 2176 | mutex_init(&BTRFS_I(inode)->extent_mutex); |
2163 | BTRFS_I(inode)->delalloc_bytes = 0; | 2177 | BTRFS_I(inode)->delalloc_bytes = 0; |
@@ -2400,6 +2414,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
2400 | inode->i_mapping, GFP_NOFS); | 2414 | inode->i_mapping, GFP_NOFS); |
2401 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 2415 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
2402 | inode->i_mapping, GFP_NOFS); | 2416 | inode->i_mapping, GFP_NOFS); |
2417 | INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes); | ||
2403 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 2418 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
2404 | mutex_init(&BTRFS_I(inode)->extent_mutex); | 2419 | mutex_init(&BTRFS_I(inode)->extent_mutex); |
2405 | BTRFS_I(inode)->delalloc_bytes = 0; | 2420 | BTRFS_I(inode)->delalloc_bytes = 0; |
@@ -3049,8 +3064,7 @@ again: | |||
3049 | goto again; | 3064 | goto again; |
3050 | } | 3065 | } |
3051 | 3066 | ||
3052 | set_extent_delalloc(&BTRFS_I(inode)->io_tree, page_start, | 3067 | btrfs_set_extent_delalloc(inode, page_start, page_end); |
3053 | page_end, GFP_NOFS); | ||
3054 | ret = 0; | 3068 | ret = 0; |
3055 | 3069 | ||
3056 | /* page is wholly or partially inside EOF */ | 3070 | /* page is wholly or partially inside EOF */ |
@@ -3373,6 +3387,26 @@ out_unlock: | |||
3373 | return ret; | 3387 | return ret; |
3374 | } | 3388 | } |
3375 | 3389 | ||
3390 | int btrfs_start_delalloc_inodes(struct btrfs_root *root) | ||
3391 | { | ||
3392 | struct list_head *head = &root->fs_info->delalloc_inodes; | ||
3393 | struct btrfs_inode *binode; | ||
3394 | unsigned long flags; | ||
3395 | |||
3396 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | ||
3397 | while(!list_empty(head)) { | ||
3398 | binode = list_entry(head->next, struct btrfs_inode, | ||
3399 | delalloc_inodes); | ||
3400 | atomic_inc(&binode->vfs_inode.i_count); | ||
3401 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | ||
3402 | filemap_write_and_wait(binode->vfs_inode.i_mapping); | ||
3403 | iput(&binode->vfs_inode); | ||
3404 | spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); | ||
3405 | } | ||
3406 | spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); | ||
3407 | return 0; | ||
3408 | } | ||
3409 | |||
3376 | static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | 3410 | static int btrfs_symlink(struct inode *dir, struct dentry *dentry, |
3377 | const char *symname) | 3411 | const char *symname) |
3378 | { | 3412 | { |
@@ -3436,6 +3470,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
3436 | inode->i_mapping, GFP_NOFS); | 3470 | inode->i_mapping, GFP_NOFS); |
3437 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | 3471 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, |
3438 | inode->i_mapping, GFP_NOFS); | 3472 | inode->i_mapping, GFP_NOFS); |
3473 | INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes); | ||
3439 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 3474 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
3440 | mutex_init(&BTRFS_I(inode)->extent_mutex); | 3475 | mutex_init(&BTRFS_I(inode)->extent_mutex); |
3441 | BTRFS_I(inode)->delalloc_bytes = 0; | 3476 | BTRFS_I(inode)->delalloc_bytes = 0; |