diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-09-17 10:58:06 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:00:48 -0400 |
commit | d3c2fdcf7b79079f60ac64e61d886964d4647910 (patch) | |
tree | 146379e460b1209fef52635bf8e581c68864a452 | |
parent | 7d7d6068bee9d8004ea7cc8a2ebda2c99a57caec (diff) |
Btrfs: Use balance_dirty_pages_nr on btree blocks
btrfs_btree_balance_dirty is changed to pass the number of pages dirtied
for more accurate dirty throttling. This lets the VM make better decisions
about when to force some writeback.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r-- | fs/btrfs/disk-io.c | 5 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 2 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 1 | ||||
-rw-r--r-- | fs/btrfs/file.c | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 47 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 14 |
6 files changed, 51 insertions, 20 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 4296839eea1a..ef6d76f2ec20 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -666,7 +666,8 @@ void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf) | |||
666 | brelse(buf); | 666 | brelse(buf); |
667 | } | 667 | } |
668 | 668 | ||
669 | void btrfs_btree_balance_dirty(struct btrfs_root *root) | 669 | void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) |
670 | { | 670 | { |
671 | balance_dirty_pages_ratelimited(root->fs_info->btree_inode->i_mapping); | 671 | balance_dirty_pages_ratelimited_nr( |
672 | root->fs_info->btree_inode->i_mapping, nr); | ||
672 | } | 673 | } |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 714fa877438b..fc6b520c6e0b 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -80,7 +80,7 @@ int btrfs_insert_dev_radix(struct btrfs_root *root, | |||
80 | u64 num_blocks); | 80 | u64 num_blocks); |
81 | int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh, | 81 | int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh, |
82 | u64 logical); | 82 | u64 logical); |
83 | void btrfs_btree_balance_dirty(struct btrfs_root *root); | 83 | void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); |
84 | int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); | 84 | int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); |
85 | void btrfs_mark_buffer_dirty(struct buffer_head *bh); | 85 | void btrfs_mark_buffer_dirty(struct buffer_head *bh); |
86 | #endif | 86 | #endif |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 9151850266b0..fe772f9b06cf 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1275,6 +1275,7 @@ struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
1275 | set_buffer_checked(buf); | 1275 | set_buffer_checked(buf); |
1276 | set_buffer_defrag(buf); | 1276 | set_buffer_defrag(buf); |
1277 | set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index); | 1277 | set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index); |
1278 | trans->blocks_used++; | ||
1278 | return buf; | 1279 | return buf; |
1279 | } | 1280 | } |
1280 | 1281 | ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 26826a543355..698eaea612f1 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -655,7 +655,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
655 | num_written += write_bytes; | 655 | num_written += write_bytes; |
656 | 656 | ||
657 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages); | 657 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages); |
658 | btrfs_btree_balance_dirty(root); | 658 | btrfs_btree_balance_dirty(root, 1); |
659 | cond_resched(); | 659 | cond_resched(); |
660 | } | 660 | } |
661 | mutex_unlock(&inode->i_mutex); | 661 | mutex_unlock(&inode->i_mutex); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e24b875327da..bd00df33fb3f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -387,15 +387,17 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
387 | struct btrfs_root *root; | 387 | struct btrfs_root *root; |
388 | struct btrfs_trans_handle *trans; | 388 | struct btrfs_trans_handle *trans; |
389 | int ret; | 389 | int ret; |
390 | unsigned long nr; | ||
390 | 391 | ||
391 | root = BTRFS_I(dir)->root; | 392 | root = BTRFS_I(dir)->root; |
392 | mutex_lock(&root->fs_info->fs_mutex); | 393 | mutex_lock(&root->fs_info->fs_mutex); |
393 | trans = btrfs_start_transaction(root, 1); | 394 | trans = btrfs_start_transaction(root, 1); |
394 | btrfs_set_trans_block_group(trans, dir); | 395 | btrfs_set_trans_block_group(trans, dir); |
395 | ret = btrfs_unlink_trans(trans, root, dir, dentry); | 396 | ret = btrfs_unlink_trans(trans, root, dir, dentry); |
397 | nr = trans->blocks_used; | ||
396 | btrfs_end_transaction(trans, root); | 398 | btrfs_end_transaction(trans, root); |
397 | mutex_unlock(&root->fs_info->fs_mutex); | 399 | mutex_unlock(&root->fs_info->fs_mutex); |
398 | btrfs_btree_balance_dirty(root); | 400 | btrfs_btree_balance_dirty(root, nr); |
399 | return ret; | 401 | return ret; |
400 | } | 402 | } |
401 | 403 | ||
@@ -412,6 +414,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
412 | int found_type; | 414 | int found_type; |
413 | struct btrfs_leaf *leaf; | 415 | struct btrfs_leaf *leaf; |
414 | char *goodnames = ".."; | 416 | char *goodnames = ".."; |
417 | unsigned long nr; | ||
415 | 418 | ||
416 | path = btrfs_alloc_path(); | 419 | path = btrfs_alloc_path(); |
417 | BUG_ON(!path); | 420 | BUG_ON(!path); |
@@ -467,8 +470,9 @@ out: | |||
467 | btrfs_release_path(root, path); | 470 | btrfs_release_path(root, path); |
468 | btrfs_free_path(path); | 471 | btrfs_free_path(path); |
469 | mutex_unlock(&root->fs_info->fs_mutex); | 472 | mutex_unlock(&root->fs_info->fs_mutex); |
473 | nr = trans->blocks_used; | ||
470 | ret = btrfs_end_transaction(trans, root); | 474 | ret = btrfs_end_transaction(trans, root); |
471 | btrfs_btree_balance_dirty(root); | 475 | btrfs_btree_balance_dirty(root, nr); |
472 | if (ret && !err) | 476 | if (ret && !err) |
473 | err = ret; | 477 | err = ret; |
474 | return err; | 478 | return err; |
@@ -764,6 +768,7 @@ void btrfs_delete_inode(struct inode *inode) | |||
764 | { | 768 | { |
765 | struct btrfs_trans_handle *trans; | 769 | struct btrfs_trans_handle *trans; |
766 | struct btrfs_root *root = BTRFS_I(inode)->root; | 770 | struct btrfs_root *root = BTRFS_I(inode)->root; |
771 | unsigned long nr; | ||
767 | int ret; | 772 | int ret; |
768 | 773 | ||
769 | truncate_inode_pages(&inode->i_data, 0); | 774 | truncate_inode_pages(&inode->i_data, 0); |
@@ -780,15 +785,17 @@ void btrfs_delete_inode(struct inode *inode) | |||
780 | ret = btrfs_free_inode(trans, root, inode); | 785 | ret = btrfs_free_inode(trans, root, inode); |
781 | if (ret) | 786 | if (ret) |
782 | goto no_delete_lock; | 787 | goto no_delete_lock; |
788 | nr = trans->blocks_used; | ||
783 | btrfs_end_transaction(trans, root); | 789 | btrfs_end_transaction(trans, root); |
784 | mutex_unlock(&root->fs_info->fs_mutex); | 790 | mutex_unlock(&root->fs_info->fs_mutex); |
785 | btrfs_btree_balance_dirty(root); | 791 | btrfs_btree_balance_dirty(root, nr); |
786 | return; | 792 | return; |
787 | 793 | ||
788 | no_delete_lock: | 794 | no_delete_lock: |
795 | nr = trans->blocks_used; | ||
789 | btrfs_end_transaction(trans, root); | 796 | btrfs_end_transaction(trans, root); |
790 | mutex_unlock(&root->fs_info->fs_mutex); | 797 | mutex_unlock(&root->fs_info->fs_mutex); |
791 | btrfs_btree_balance_dirty(root); | 798 | btrfs_btree_balance_dirty(root, nr); |
792 | no_delete: | 799 | no_delete: |
793 | clear_inode(inode); | 800 | clear_inode(inode); |
794 | } | 801 | } |
@@ -1165,6 +1172,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1165 | int err; | 1172 | int err; |
1166 | int drop_inode = 0; | 1173 | int drop_inode = 0; |
1167 | u64 objectid; | 1174 | u64 objectid; |
1175 | unsigned long nr; | ||
1168 | 1176 | ||
1169 | if (!new_valid_dev(rdev)) | 1177 | if (!new_valid_dev(rdev)) |
1170 | return -EINVAL; | 1178 | return -EINVAL; |
@@ -1198,6 +1206,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1198 | btrfs_update_inode_block_group(trans, inode); | 1206 | btrfs_update_inode_block_group(trans, inode); |
1199 | btrfs_update_inode_block_group(trans, dir); | 1207 | btrfs_update_inode_block_group(trans, dir); |
1200 | out_unlock: | 1208 | out_unlock: |
1209 | nr = trans->blocks_used; | ||
1201 | btrfs_end_transaction(trans, root); | 1210 | btrfs_end_transaction(trans, root); |
1202 | mutex_unlock(&root->fs_info->fs_mutex); | 1211 | mutex_unlock(&root->fs_info->fs_mutex); |
1203 | 1212 | ||
@@ -1205,7 +1214,7 @@ out_unlock: | |||
1205 | inode_dec_link_count(inode); | 1214 | inode_dec_link_count(inode); |
1206 | iput(inode); | 1215 | iput(inode); |
1207 | } | 1216 | } |
1208 | btrfs_btree_balance_dirty(root); | 1217 | btrfs_btree_balance_dirty(root, nr); |
1209 | return err; | 1218 | return err; |
1210 | } | 1219 | } |
1211 | 1220 | ||
@@ -1217,6 +1226,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
1217 | struct inode *inode; | 1226 | struct inode *inode; |
1218 | int err; | 1227 | int err; |
1219 | int drop_inode = 0; | 1228 | int drop_inode = 0; |
1229 | unsigned long nr; | ||
1220 | u64 objectid; | 1230 | u64 objectid; |
1221 | 1231 | ||
1222 | mutex_lock(&root->fs_info->fs_mutex); | 1232 | mutex_lock(&root->fs_info->fs_mutex); |
@@ -1251,6 +1261,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
1251 | btrfs_update_inode_block_group(trans, inode); | 1261 | btrfs_update_inode_block_group(trans, inode); |
1252 | btrfs_update_inode_block_group(trans, dir); | 1262 | btrfs_update_inode_block_group(trans, dir); |
1253 | out_unlock: | 1263 | out_unlock: |
1264 | nr = trans->blocks_used; | ||
1254 | btrfs_end_transaction(trans, root); | 1265 | btrfs_end_transaction(trans, root); |
1255 | mutex_unlock(&root->fs_info->fs_mutex); | 1266 | mutex_unlock(&root->fs_info->fs_mutex); |
1256 | 1267 | ||
@@ -1258,7 +1269,7 @@ out_unlock: | |||
1258 | inode_dec_link_count(inode); | 1269 | inode_dec_link_count(inode); |
1259 | iput(inode); | 1270 | iput(inode); |
1260 | } | 1271 | } |
1261 | btrfs_btree_balance_dirty(root); | 1272 | btrfs_btree_balance_dirty(root, nr); |
1262 | return err; | 1273 | return err; |
1263 | } | 1274 | } |
1264 | 1275 | ||
@@ -1268,6 +1279,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1268 | struct btrfs_trans_handle *trans; | 1279 | struct btrfs_trans_handle *trans; |
1269 | struct btrfs_root *root = BTRFS_I(dir)->root; | 1280 | struct btrfs_root *root = BTRFS_I(dir)->root; |
1270 | struct inode *inode = old_dentry->d_inode; | 1281 | struct inode *inode = old_dentry->d_inode; |
1282 | unsigned long nr; | ||
1271 | int err; | 1283 | int err; |
1272 | int drop_inode = 0; | 1284 | int drop_inode = 0; |
1273 | 1285 | ||
@@ -1288,6 +1300,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1288 | if (err) | 1300 | if (err) |
1289 | drop_inode = 1; | 1301 | drop_inode = 1; |
1290 | 1302 | ||
1303 | nr = trans->blocks_used; | ||
1291 | btrfs_end_transaction(trans, root); | 1304 | btrfs_end_transaction(trans, root); |
1292 | mutex_unlock(&root->fs_info->fs_mutex); | 1305 | mutex_unlock(&root->fs_info->fs_mutex); |
1293 | 1306 | ||
@@ -1295,7 +1308,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1295 | inode_dec_link_count(inode); | 1308 | inode_dec_link_count(inode); |
1296 | iput(inode); | 1309 | iput(inode); |
1297 | } | 1310 | } |
1298 | btrfs_btree_balance_dirty(root); | 1311 | btrfs_btree_balance_dirty(root, nr); |
1299 | return err; | 1312 | return err; |
1300 | } | 1313 | } |
1301 | 1314 | ||
@@ -1336,6 +1349,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1336 | int err = 0; | 1349 | int err = 0; |
1337 | int drop_on_err = 0; | 1350 | int drop_on_err = 0; |
1338 | u64 objectid; | 1351 | u64 objectid; |
1352 | unsigned long nr = 1; | ||
1339 | 1353 | ||
1340 | mutex_lock(&root->fs_info->fs_mutex); | 1354 | mutex_lock(&root->fs_info->fs_mutex); |
1341 | trans = btrfs_start_transaction(root, 1); | 1355 | trans = btrfs_start_transaction(root, 1); |
@@ -1380,12 +1394,13 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1380 | btrfs_update_inode_block_group(trans, dir); | 1394 | btrfs_update_inode_block_group(trans, dir); |
1381 | 1395 | ||
1382 | out_fail: | 1396 | out_fail: |
1397 | nr = trans->blocks_used; | ||
1383 | btrfs_end_transaction(trans, root); | 1398 | btrfs_end_transaction(trans, root); |
1384 | out_unlock: | 1399 | out_unlock: |
1385 | mutex_unlock(&root->fs_info->fs_mutex); | 1400 | mutex_unlock(&root->fs_info->fs_mutex); |
1386 | if (drop_on_err) | 1401 | if (drop_on_err) |
1387 | iput(inode); | 1402 | iput(inode); |
1388 | btrfs_btree_balance_dirty(root); | 1403 | btrfs_btree_balance_dirty(root, nr); |
1389 | return err; | 1404 | return err; |
1390 | } | 1405 | } |
1391 | 1406 | ||
@@ -1682,6 +1697,7 @@ static void btrfs_truncate(struct inode *inode) | |||
1682 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1697 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1683 | int ret; | 1698 | int ret; |
1684 | struct btrfs_trans_handle *trans; | 1699 | struct btrfs_trans_handle *trans; |
1700 | unsigned long nr; | ||
1685 | 1701 | ||
1686 | if (!S_ISREG(inode->i_mode)) | 1702 | if (!S_ISREG(inode->i_mode)) |
1687 | return; | 1703 | return; |
@@ -1697,10 +1713,11 @@ static void btrfs_truncate(struct inode *inode) | |||
1697 | /* FIXME, add redo link to tree so we don't leak on crash */ | 1713 | /* FIXME, add redo link to tree so we don't leak on crash */ |
1698 | ret = btrfs_truncate_in_trans(trans, root, inode); | 1714 | ret = btrfs_truncate_in_trans(trans, root, inode); |
1699 | btrfs_update_inode(trans, root, inode); | 1715 | btrfs_update_inode(trans, root, inode); |
1716 | nr = trans->blocks_used; | ||
1700 | ret = btrfs_end_transaction(trans, root); | 1717 | ret = btrfs_end_transaction(trans, root); |
1701 | BUG_ON(ret); | 1718 | BUG_ON(ret); |
1702 | mutex_unlock(&root->fs_info->fs_mutex); | 1719 | mutex_unlock(&root->fs_info->fs_mutex); |
1703 | btrfs_btree_balance_dirty(root); | 1720 | btrfs_btree_balance_dirty(root, nr); |
1704 | } | 1721 | } |
1705 | 1722 | ||
1706 | int btrfs_commit_write(struct file *file, struct page *page, | 1723 | int btrfs_commit_write(struct file *file, struct page *page, |
@@ -1725,6 +1742,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1725 | int err; | 1742 | int err; |
1726 | u64 objectid; | 1743 | u64 objectid; |
1727 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; | 1744 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; |
1745 | unsigned long nr = 1; | ||
1728 | 1746 | ||
1729 | mutex_lock(&root->fs_info->fs_mutex); | 1747 | mutex_lock(&root->fs_info->fs_mutex); |
1730 | trans = btrfs_start_transaction(root, 1); | 1748 | trans = btrfs_start_transaction(root, 1); |
@@ -1814,12 +1832,13 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1814 | if (ret) | 1832 | if (ret) |
1815 | goto fail; | 1833 | goto fail; |
1816 | fail: | 1834 | fail: |
1835 | nr = trans->blocks_used; | ||
1817 | err = btrfs_commit_transaction(trans, root); | 1836 | err = btrfs_commit_transaction(trans, root); |
1818 | if (err && !ret) | 1837 | if (err && !ret) |
1819 | ret = err; | 1838 | ret = err; |
1820 | fail_commit: | 1839 | fail_commit: |
1821 | mutex_unlock(&root->fs_info->fs_mutex); | 1840 | mutex_unlock(&root->fs_info->fs_mutex); |
1822 | btrfs_btree_balance_dirty(root); | 1841 | btrfs_btree_balance_dirty(root, nr); |
1823 | return ret; | 1842 | return ret; |
1824 | } | 1843 | } |
1825 | 1844 | ||
@@ -1832,6 +1851,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
1832 | int ret; | 1851 | int ret; |
1833 | int err; | 1852 | int err; |
1834 | u64 objectid; | 1853 | u64 objectid; |
1854 | unsigned long nr; | ||
1835 | 1855 | ||
1836 | if (!root->ref_cows) | 1856 | if (!root->ref_cows) |
1837 | return -EINVAL; | 1857 | return -EINVAL; |
@@ -1884,12 +1904,13 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
1884 | if (ret) | 1904 | if (ret) |
1885 | goto fail; | 1905 | goto fail; |
1886 | fail: | 1906 | fail: |
1907 | nr = trans->blocks_used; | ||
1887 | err = btrfs_commit_transaction(trans, root); | 1908 | err = btrfs_commit_transaction(trans, root); |
1888 | if (err && !ret) | 1909 | if (err && !ret) |
1889 | ret = err; | 1910 | ret = err; |
1890 | mutex_unlock(&root->fs_info->fs_mutex); | 1911 | mutex_unlock(&root->fs_info->fs_mutex); |
1891 | up_write(&root->snap_sem); | 1912 | up_write(&root->snap_sem); |
1892 | btrfs_btree_balance_dirty(root); | 1913 | btrfs_btree_balance_dirty(root, nr); |
1893 | return ret; | 1914 | return ret; |
1894 | } | 1915 | } |
1895 | 1916 | ||
@@ -2240,6 +2261,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2240 | int datasize; | 2261 | int datasize; |
2241 | char *ptr; | 2262 | char *ptr; |
2242 | struct btrfs_file_extent_item *ei; | 2263 | struct btrfs_file_extent_item *ei; |
2264 | unsigned long nr; | ||
2243 | 2265 | ||
2244 | name_len = strlen(symname) + 1; | 2266 | name_len = strlen(symname) + 1; |
2245 | if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) | 2267 | if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) |
@@ -2309,13 +2331,14 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
2309 | drop_inode = 1; | 2331 | drop_inode = 1; |
2310 | 2332 | ||
2311 | out_unlock: | 2333 | out_unlock: |
2334 | nr = trans->blocks_used; | ||
2312 | btrfs_end_transaction(trans, root); | 2335 | btrfs_end_transaction(trans, root); |
2313 | mutex_unlock(&root->fs_info->fs_mutex); | 2336 | mutex_unlock(&root->fs_info->fs_mutex); |
2314 | if (drop_inode) { | 2337 | if (drop_inode) { |
2315 | inode_dec_link_count(inode); | 2338 | inode_dec_link_count(inode); |
2316 | iput(inode); | 2339 | iput(inode); |
2317 | } | 2340 | } |
2318 | btrfs_btree_balance_dirty(root); | 2341 | btrfs_btree_balance_dirty(root, nr); |
2319 | return err; | 2342 | return err; |
2320 | } | 2343 | } |
2321 | 2344 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 29755593de65..087074db0bd5 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/writeback.h> | ||
21 | #include "ctree.h" | 22 | #include "ctree.h" |
22 | #include "disk-io.h" | 23 | #include "disk-io.h" |
23 | #include "transaction.h" | 24 | #include "transaction.h" |
@@ -340,6 +341,7 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
340 | struct btrfs_fs_info *info = root->fs_info; | 341 | struct btrfs_fs_info *info = root->fs_info; |
341 | int ret; | 342 | int ret; |
342 | struct btrfs_trans_handle *trans; | 343 | struct btrfs_trans_handle *trans; |
344 | unsigned long nr; | ||
343 | 345 | ||
344 | if (root->defrag_running) | 346 | if (root->defrag_running) |
345 | return 0; | 347 | return 0; |
@@ -348,10 +350,11 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
348 | while (1) { | 350 | while (1) { |
349 | root->defrag_running = 1; | 351 | root->defrag_running = 1; |
350 | ret = btrfs_defrag_leaves(trans, root, cacheonly); | 352 | ret = btrfs_defrag_leaves(trans, root, cacheonly); |
353 | nr = trans->blocks_used; | ||
351 | btrfs_end_transaction(trans, root); | 354 | btrfs_end_transaction(trans, root); |
352 | mutex_unlock(&info->fs_mutex); | 355 | mutex_unlock(&info->fs_mutex); |
353 | 356 | ||
354 | btrfs_btree_balance_dirty(root); | 357 | btrfs_btree_balance_dirty(info->tree_root, nr); |
355 | cond_resched(); | 358 | cond_resched(); |
356 | 359 | ||
357 | mutex_lock(&info->fs_mutex); | 360 | mutex_lock(&info->fs_mutex); |
@@ -398,6 +401,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
398 | { | 401 | { |
399 | struct dirty_root *dirty; | 402 | struct dirty_root *dirty; |
400 | struct btrfs_trans_handle *trans; | 403 | struct btrfs_trans_handle *trans; |
404 | unsigned long nr; | ||
401 | u64 num_blocks; | 405 | u64 num_blocks; |
402 | u64 blocks_used; | 406 | u64 blocks_used; |
403 | int ret = 0; | 407 | int ret = 0; |
@@ -426,11 +430,11 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
426 | &dirty->root->root_item); | 430 | &dirty->root->root_item); |
427 | if (err) | 431 | if (err) |
428 | ret = err; | 432 | ret = err; |
433 | nr = trans->blocks_used; | ||
429 | ret = btrfs_end_transaction(trans, tree_root); | 434 | ret = btrfs_end_transaction(trans, tree_root); |
430 | BUG_ON(ret); | 435 | BUG_ON(ret); |
431 | mutex_unlock(&tree_root->fs_info->fs_mutex); | 436 | mutex_unlock(&tree_root->fs_info->fs_mutex); |
432 | 437 | btrfs_btree_balance_dirty(tree_root, nr); | |
433 | btrfs_btree_balance_dirty(tree_root); | ||
434 | schedule(); | 438 | schedule(); |
435 | 439 | ||
436 | mutex_lock(&tree_root->fs_info->fs_mutex); | 440 | mutex_lock(&tree_root->fs_info->fs_mutex); |
@@ -449,13 +453,15 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
449 | BUG(); | 453 | BUG(); |
450 | break; | 454 | break; |
451 | } | 455 | } |
456 | nr = trans->blocks_used; | ||
452 | ret = btrfs_end_transaction(trans, tree_root); | 457 | ret = btrfs_end_transaction(trans, tree_root); |
453 | BUG_ON(ret); | 458 | BUG_ON(ret); |
454 | 459 | ||
455 | kfree(dirty->root); | 460 | kfree(dirty->root); |
456 | kfree(dirty); | 461 | kfree(dirty); |
457 | mutex_unlock(&tree_root->fs_info->fs_mutex); | 462 | mutex_unlock(&tree_root->fs_info->fs_mutex); |
458 | btrfs_btree_balance_dirty(tree_root); | 463 | |
464 | btrfs_btree_balance_dirty(tree_root, nr); | ||
459 | schedule(); | 465 | schedule(); |
460 | } | 466 | } |
461 | return ret; | 467 | return ret; |