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 /fs/btrfs/inode.c | |
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>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 47 |
1 files changed, 35 insertions, 12 deletions
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 | ||