diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index a29a781b86c2..130a1d3d9f5f 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -18,14 +18,14 @@ | |||
18 | #include "btrfs_inode.h" | 18 | #include "btrfs_inode.h" |
19 | #include "ioctl.h" | 19 | #include "ioctl.h" |
20 | 20 | ||
21 | void btrfs_fsinfo_release(struct kobject *obj) | 21 | static void btrfs_fsinfo_release(struct kobject *obj) |
22 | { | 22 | { |
23 | struct btrfs_fs_info *fsinfo = container_of(obj, | 23 | struct btrfs_fs_info *fsinfo = container_of(obj, |
24 | struct btrfs_fs_info, kobj); | 24 | struct btrfs_fs_info, kobj); |
25 | kfree(fsinfo); | 25 | kfree(fsinfo); |
26 | } | 26 | } |
27 | 27 | ||
28 | struct kobj_type btrfs_fsinfo_ktype = { | 28 | static struct kobj_type btrfs_fsinfo_ktype = { |
29 | .release = btrfs_fsinfo_release, | 29 | .release = btrfs_fsinfo_release, |
30 | }; | 30 | }; |
31 | 31 | ||
@@ -148,7 +148,6 @@ static void fill_inode_item(struct btrfs_inode_item *item, | |||
148 | BTRFS_I(inode)->block_group->key.objectid); | 148 | BTRFS_I(inode)->block_group->key.objectid); |
149 | } | 149 | } |
150 | 150 | ||
151 | |||
152 | static int btrfs_update_inode(struct btrfs_trans_handle *trans, | 151 | static int btrfs_update_inode(struct btrfs_trans_handle *trans, |
153 | struct btrfs_root *root, | 152 | struct btrfs_root *root, |
154 | struct inode *inode) | 153 | struct inode *inode) |
@@ -251,6 +250,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
251 | ret = btrfs_unlink_trans(trans, root, dir, dentry); | 250 | ret = btrfs_unlink_trans(trans, root, dir, dentry); |
252 | btrfs_end_transaction(trans, root); | 251 | btrfs_end_transaction(trans, root); |
253 | mutex_unlock(&root->fs_info->fs_mutex); | 252 | mutex_unlock(&root->fs_info->fs_mutex); |
253 | btrfs_btree_balance_dirty(root); | ||
254 | return ret; | 254 | return ret; |
255 | } | 255 | } |
256 | 256 | ||
@@ -324,6 +324,7 @@ out: | |||
324 | btrfs_free_path(path); | 324 | btrfs_free_path(path); |
325 | mutex_unlock(&root->fs_info->fs_mutex); | 325 | mutex_unlock(&root->fs_info->fs_mutex); |
326 | ret = btrfs_end_transaction(trans, root); | 326 | ret = btrfs_end_transaction(trans, root); |
327 | btrfs_btree_balance_dirty(root); | ||
327 | if (ret && !err) | 328 | if (ret && !err) |
328 | err = ret; | 329 | err = ret; |
329 | return err; | 330 | return err; |
@@ -449,6 +450,7 @@ static void btrfs_delete_inode(struct inode *inode) | |||
449 | btrfs_free_inode(trans, root, inode); | 450 | btrfs_free_inode(trans, root, inode); |
450 | btrfs_end_transaction(trans, root); | 451 | btrfs_end_transaction(trans, root); |
451 | mutex_unlock(&root->fs_info->fs_mutex); | 452 | mutex_unlock(&root->fs_info->fs_mutex); |
453 | btrfs_btree_balance_dirty(root); | ||
452 | return; | 454 | return; |
453 | no_delete: | 455 | no_delete: |
454 | clear_inode(inode); | 456 | clear_inode(inode); |
@@ -481,7 +483,7 @@ out: | |||
481 | return ret; | 483 | return ret; |
482 | } | 484 | } |
483 | 485 | ||
484 | int fixup_tree_root_location(struct btrfs_root *root, | 486 | static int fixup_tree_root_location(struct btrfs_root *root, |
485 | struct btrfs_key *location, | 487 | struct btrfs_key *location, |
486 | struct btrfs_root **sub_root) | 488 | struct btrfs_root **sub_root) |
487 | { | 489 | { |
@@ -512,7 +514,7 @@ int fixup_tree_root_location(struct btrfs_root *root, | |||
512 | return 0; | 514 | return 0; |
513 | } | 515 | } |
514 | 516 | ||
515 | int btrfs_init_locked_inode(struct inode *inode, void *p) | 517 | static int btrfs_init_locked_inode(struct inode *inode, void *p) |
516 | { | 518 | { |
517 | struct btrfs_iget_args *args = p; | 519 | struct btrfs_iget_args *args = p; |
518 | inode->i_ino = args->ino; | 520 | inode->i_ino = args->ino; |
@@ -520,15 +522,15 @@ int btrfs_init_locked_inode(struct inode *inode, void *p) | |||
520 | return 0; | 522 | return 0; |
521 | } | 523 | } |
522 | 524 | ||
523 | int btrfs_find_actor(struct inode *inode, void *opaque) | 525 | static int btrfs_find_actor(struct inode *inode, void *opaque) |
524 | { | 526 | { |
525 | struct btrfs_iget_args *args = opaque; | 527 | struct btrfs_iget_args *args = opaque; |
526 | return (args->ino == inode->i_ino && | 528 | return (args->ino == inode->i_ino && |
527 | args->root == BTRFS_I(inode)->root); | 529 | args->root == BTRFS_I(inode)->root); |
528 | } | 530 | } |
529 | 531 | ||
530 | struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, | 532 | static struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, |
531 | struct btrfs_root *root) | 533 | struct btrfs_root *root) |
532 | { | 534 | { |
533 | struct inode *inode; | 535 | struct inode *inode; |
534 | struct btrfs_iget_args args; | 536 | struct btrfs_iget_args args; |
@@ -790,6 +792,7 @@ static void btrfs_dirty_inode(struct inode *inode) | |||
790 | btrfs_update_inode(trans, root, inode); | 792 | btrfs_update_inode(trans, root, inode); |
791 | btrfs_end_transaction(trans, root); | 793 | btrfs_end_transaction(trans, root); |
792 | mutex_unlock(&root->fs_info->fs_mutex); | 794 | mutex_unlock(&root->fs_info->fs_mutex); |
795 | btrfs_btree_balance_dirty(root); | ||
793 | } | 796 | } |
794 | 797 | ||
795 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | 798 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, |
@@ -913,6 +916,7 @@ out_unlock: | |||
913 | inode_dec_link_count(inode); | 916 | inode_dec_link_count(inode); |
914 | iput(inode); | 917 | iput(inode); |
915 | } | 918 | } |
919 | btrfs_btree_balance_dirty(root); | ||
916 | return err; | 920 | return err; |
917 | } | 921 | } |
918 | 922 | ||
@@ -1002,6 +1006,7 @@ out_unlock: | |||
1002 | mutex_unlock(&root->fs_info->fs_mutex); | 1006 | mutex_unlock(&root->fs_info->fs_mutex); |
1003 | if (drop_on_err) | 1007 | if (drop_on_err) |
1004 | iput(inode); | 1008 | iput(inode); |
1009 | btrfs_btree_balance_dirty(root); | ||
1005 | return err; | 1010 | return err; |
1006 | } | 1011 | } |
1007 | 1012 | ||
@@ -1099,7 +1104,6 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, | |||
1099 | found_type != BTRFS_EXTENT_DATA_KEY) { | 1104 | found_type != BTRFS_EXTENT_DATA_KEY) { |
1100 | extent_end = 0; | 1105 | extent_end = 0; |
1101 | extent_start = 0; | 1106 | extent_start = 0; |
1102 | btrfs_release_path(root, path); | ||
1103 | goto out; | 1107 | goto out; |
1104 | } | 1108 | } |
1105 | found_type = btrfs_file_extent_type(item); | 1109 | found_type = btrfs_file_extent_type(item); |
@@ -1135,7 +1139,6 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, | |||
1135 | btrfs_map_bh_to_logical(root, result, 0); | 1139 | btrfs_map_bh_to_logical(root, result, 0); |
1136 | } | 1140 | } |
1137 | out: | 1141 | out: |
1138 | btrfs_release_path(root, path); | ||
1139 | btrfs_free_path(path); | 1142 | btrfs_free_path(path); |
1140 | return err; | 1143 | return err; |
1141 | } | 1144 | } |
@@ -1231,13 +1234,13 @@ static int __btrfs_write_full_page(struct inode *inode, struct page *page, | |||
1231 | } else if (!buffer_mapped(bh) && buffer_dirty(bh)) { | 1234 | } else if (!buffer_mapped(bh) && buffer_dirty(bh)) { |
1232 | WARN_ON(bh->b_size != blocksize); | 1235 | WARN_ON(bh->b_size != blocksize); |
1233 | err = btrfs_get_block(inode, block, bh, 0); | 1236 | err = btrfs_get_block(inode, block, bh, 0); |
1234 | if (err) | 1237 | if (err) { |
1238 | printk("writepage going to recovery err %d\n", err); | ||
1235 | goto recover; | 1239 | goto recover; |
1240 | } | ||
1236 | if (buffer_new(bh)) { | 1241 | if (buffer_new(bh)) { |
1237 | /* blockdev mappings never come here */ | 1242 | /* blockdev mappings never come here */ |
1238 | clear_buffer_new(bh); | 1243 | clear_buffer_new(bh); |
1239 | unmap_underlying_metadata(bh->b_bdev, | ||
1240 | bh->b_blocknr); | ||
1241 | } | 1244 | } |
1242 | } | 1245 | } |
1243 | bh = bh->b_this_page; | 1246 | bh = bh->b_this_page; |
@@ -1303,11 +1306,6 @@ done: | |||
1303 | if (uptodate) | 1306 | if (uptodate) |
1304 | SetPageUptodate(page); | 1307 | SetPageUptodate(page); |
1305 | end_page_writeback(page); | 1308 | end_page_writeback(page); |
1306 | /* | ||
1307 | * The page and buffer_heads can be released at any time from | ||
1308 | * here on. | ||
1309 | */ | ||
1310 | wbc->pages_skipped++; /* We didn't write this page */ | ||
1311 | } | 1309 | } |
1312 | return err; | 1310 | return err; |
1313 | 1311 | ||
@@ -1409,10 +1407,11 @@ static void btrfs_truncate(struct inode *inode) | |||
1409 | btrfs_set_trans_block_group(trans, inode); | 1407 | btrfs_set_trans_block_group(trans, inode); |
1410 | ret = btrfs_truncate_in_trans(trans, root, inode); | 1408 | ret = btrfs_truncate_in_trans(trans, root, inode); |
1411 | BUG_ON(ret); | 1409 | BUG_ON(ret); |
1410 | btrfs_update_inode(trans, root, inode); | ||
1412 | ret = btrfs_end_transaction(trans, root); | 1411 | ret = btrfs_end_transaction(trans, root); |
1413 | BUG_ON(ret); | 1412 | BUG_ON(ret); |
1414 | mutex_unlock(&root->fs_info->fs_mutex); | 1413 | mutex_unlock(&root->fs_info->fs_mutex); |
1415 | mark_inode_dirty(inode); | 1414 | btrfs_btree_balance_dirty(root); |
1416 | } | 1415 | } |
1417 | 1416 | ||
1418 | /* | 1417 | /* |
@@ -1777,10 +1776,15 @@ static int prepare_pages(struct btrfs_root *root, | |||
1777 | err = -ENOMEM; | 1776 | err = -ENOMEM; |
1778 | goto failed_release; | 1777 | goto failed_release; |
1779 | } | 1778 | } |
1779 | cancel_dirty_page(pages[i], PAGE_CACHE_SIZE); | ||
1780 | wait_on_page_writeback(pages[i]); | ||
1780 | offset = pos & (PAGE_CACHE_SIZE -1); | 1781 | offset = pos & (PAGE_CACHE_SIZE -1); |
1781 | this_write = min(PAGE_CACHE_SIZE - offset, write_bytes); | 1782 | this_write = min(PAGE_CACHE_SIZE - offset, write_bytes); |
1782 | create_empty_buffers(pages[i], root->fs_info->sb->s_blocksize, | 1783 | if (!page_has_buffers(pages[i])) { |
1783 | (1 << BH_Uptodate)); | 1784 | create_empty_buffers(pages[i], |
1785 | root->fs_info->sb->s_blocksize, | ||
1786 | (1 << BH_Uptodate)); | ||
1787 | } | ||
1784 | head = page_buffers(pages[i]); | 1788 | head = page_buffers(pages[i]); |
1785 | bh = head; | 1789 | bh = head; |
1786 | do { | 1790 | do { |
@@ -1820,7 +1824,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1820 | struct inode *inode = file->f_path.dentry->d_inode; | 1824 | struct inode *inode = file->f_path.dentry->d_inode; |
1821 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1825 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1822 | struct page *pages[8]; | 1826 | struct page *pages[8]; |
1823 | struct page *pinned[2] = { NULL, NULL }; | 1827 | struct page *pinned[2]; |
1824 | unsigned long first_index; | 1828 | unsigned long first_index; |
1825 | unsigned long last_index; | 1829 | unsigned long last_index; |
1826 | u64 start_pos; | 1830 | u64 start_pos; |
@@ -1829,6 +1833,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1829 | struct btrfs_trans_handle *trans; | 1833 | struct btrfs_trans_handle *trans; |
1830 | struct btrfs_key ins; | 1834 | struct btrfs_key ins; |
1831 | 1835 | ||
1836 | pinned[0] = NULL; | ||
1837 | pinned[1] = NULL; | ||
1832 | if (file->f_flags & O_DIRECT) | 1838 | if (file->f_flags & O_DIRECT) |
1833 | return -EINVAL; | 1839 | return -EINVAL; |
1834 | pos = *ppos; | 1840 | pos = *ppos; |
@@ -1858,6 +1864,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1858 | if (!PageUptodate(pinned[0])) { | 1864 | if (!PageUptodate(pinned[0])) { |
1859 | ret = mpage_readpage(pinned[0], btrfs_get_block); | 1865 | ret = mpage_readpage(pinned[0], btrfs_get_block); |
1860 | BUG_ON(ret); | 1866 | BUG_ON(ret); |
1867 | wait_on_page_locked(pinned[0]); | ||
1861 | } else { | 1868 | } else { |
1862 | unlock_page(pinned[0]); | 1869 | unlock_page(pinned[0]); |
1863 | } | 1870 | } |
@@ -1869,6 +1876,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1869 | if (!PageUptodate(pinned[1])) { | 1876 | if (!PageUptodate(pinned[1])) { |
1870 | ret = mpage_readpage(pinned[1], btrfs_get_block); | 1877 | ret = mpage_readpage(pinned[1], btrfs_get_block); |
1871 | BUG_ON(ret); | 1878 | BUG_ON(ret); |
1879 | wait_on_page_locked(pinned[1]); | ||
1872 | } else { | 1880 | } else { |
1873 | unlock_page(pinned[1]); | 1881 | unlock_page(pinned[1]); |
1874 | } | 1882 | } |
@@ -1940,6 +1948,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1940 | num_written += write_bytes; | 1948 | num_written += write_bytes; |
1941 | 1949 | ||
1942 | balance_dirty_pages_ratelimited(inode->i_mapping); | 1950 | balance_dirty_pages_ratelimited(inode->i_mapping); |
1951 | btrfs_btree_balance_dirty(root); | ||
1943 | cond_resched(); | 1952 | cond_resched(); |
1944 | } | 1953 | } |
1945 | out_unlock: | 1954 | out_unlock: |
@@ -2165,6 +2174,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2165 | iput(inode); | 2174 | iput(inode); |
2166 | 2175 | ||
2167 | mutex_unlock(&root->fs_info->fs_mutex); | 2176 | mutex_unlock(&root->fs_info->fs_mutex); |
2177 | btrfs_btree_balance_dirty(root); | ||
2168 | return 0; | 2178 | return 0; |
2169 | } | 2179 | } |
2170 | 2180 | ||
@@ -2220,6 +2230,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2220 | ret = btrfs_commit_transaction(trans, root); | 2230 | ret = btrfs_commit_transaction(trans, root); |
2221 | BUG_ON(ret); | 2231 | BUG_ON(ret); |
2222 | mutex_unlock(&root->fs_info->fs_mutex); | 2232 | mutex_unlock(&root->fs_info->fs_mutex); |
2233 | btrfs_btree_balance_dirty(root); | ||
2223 | return 0; | 2234 | return 0; |
2224 | } | 2235 | } |
2225 | 2236 | ||
@@ -2295,6 +2306,7 @@ out: | |||
2295 | mutex_unlock(&root->fs_info->fs_mutex); | 2306 | mutex_unlock(&root->fs_info->fs_mutex); |
2296 | out_nolock: | 2307 | out_nolock: |
2297 | btrfs_free_path(path); | 2308 | btrfs_free_path(path); |
2309 | btrfs_btree_balance_dirty(root); | ||
2298 | 2310 | ||
2299 | return ret; | 2311 | return ret; |
2300 | } | 2312 | } |