aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2010-05-16 10:49:58 -0400
committerChris Mason <chris.mason@oracle.com>2010-05-25 10:34:52 -0400
commit8929ecfa50f266163832eeacfbc3642ed5eb83b6 (patch)
treee0177748af36d49d5f652cff0e421a8268cf7194 /fs/btrfs/disk-io.c
parent0ca1f7ceb1991099ed5273885ebcf4323948c72e (diff)
Btrfs: Introduce global metadata reservation
Reserve metadata space for extent tree, checksum tree and root tree Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 054b4475c757..309d8c08a640 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1463,10 +1463,6 @@ static int cleaner_kthread(void *arg)
1463 struct btrfs_root *root = arg; 1463 struct btrfs_root *root = arg;
1464 1464
1465 do { 1465 do {
1466 smp_mb();
1467 if (root->fs_info->closing)
1468 break;
1469
1470 vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); 1466 vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
1471 1467
1472 if (!(root->fs_info->sb->s_flags & MS_RDONLY) && 1468 if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
@@ -1479,11 +1475,9 @@ static int cleaner_kthread(void *arg)
1479 if (freezing(current)) { 1475 if (freezing(current)) {
1480 refrigerator(); 1476 refrigerator();
1481 } else { 1477 } else {
1482 smp_mb();
1483 if (root->fs_info->closing)
1484 break;
1485 set_current_state(TASK_INTERRUPTIBLE); 1478 set_current_state(TASK_INTERRUPTIBLE);
1486 schedule(); 1479 if (!kthread_should_stop())
1480 schedule();
1487 __set_current_state(TASK_RUNNING); 1481 __set_current_state(TASK_RUNNING);
1488 } 1482 }
1489 } while (!kthread_should_stop()); 1483 } while (!kthread_should_stop());
@@ -1495,36 +1489,40 @@ static int transaction_kthread(void *arg)
1495 struct btrfs_root *root = arg; 1489 struct btrfs_root *root = arg;
1496 struct btrfs_trans_handle *trans; 1490 struct btrfs_trans_handle *trans;
1497 struct btrfs_transaction *cur; 1491 struct btrfs_transaction *cur;
1492 u64 transid;
1498 unsigned long now; 1493 unsigned long now;
1499 unsigned long delay; 1494 unsigned long delay;
1500 int ret; 1495 int ret;
1501 1496
1502 do { 1497 do {
1503 smp_mb();
1504 if (root->fs_info->closing)
1505 break;
1506
1507 delay = HZ * 30; 1498 delay = HZ * 30;
1508 vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); 1499 vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
1509 mutex_lock(&root->fs_info->transaction_kthread_mutex); 1500 mutex_lock(&root->fs_info->transaction_kthread_mutex);
1510 1501
1511 mutex_lock(&root->fs_info->trans_mutex); 1502 spin_lock(&root->fs_info->new_trans_lock);
1512 cur = root->fs_info->running_transaction; 1503 cur = root->fs_info->running_transaction;
1513 if (!cur) { 1504 if (!cur) {
1514 mutex_unlock(&root->fs_info->trans_mutex); 1505 spin_unlock(&root->fs_info->new_trans_lock);
1515 goto sleep; 1506 goto sleep;
1516 } 1507 }
1517 1508
1518 now = get_seconds(); 1509 now = get_seconds();
1519 if (now < cur->start_time || now - cur->start_time < 30) { 1510 if (!cur->blocked &&
1520 mutex_unlock(&root->fs_info->trans_mutex); 1511 (now < cur->start_time || now - cur->start_time < 30)) {
1512 spin_unlock(&root->fs_info->new_trans_lock);
1521 delay = HZ * 5; 1513 delay = HZ * 5;
1522 goto sleep; 1514 goto sleep;
1523 } 1515 }
1524 mutex_unlock(&root->fs_info->trans_mutex); 1516 transid = cur->transid;
1525 trans = btrfs_join_transaction(root, 1); 1517 spin_unlock(&root->fs_info->new_trans_lock);
1526 ret = btrfs_commit_transaction(trans, root);
1527 1518
1519 trans = btrfs_join_transaction(root, 1);
1520 if (transid == trans->transid) {
1521 ret = btrfs_commit_transaction(trans, root);
1522 BUG_ON(ret);
1523 } else {
1524 btrfs_end_transaction(trans, root);
1525 }
1528sleep: 1526sleep:
1529 wake_up_process(root->fs_info->cleaner_kthread); 1527 wake_up_process(root->fs_info->cleaner_kthread);
1530 mutex_unlock(&root->fs_info->transaction_kthread_mutex); 1528 mutex_unlock(&root->fs_info->transaction_kthread_mutex);
@@ -1532,10 +1530,10 @@ sleep:
1532 if (freezing(current)) { 1530 if (freezing(current)) {
1533 refrigerator(); 1531 refrigerator();
1534 } else { 1532 } else {
1535 if (root->fs_info->closing)
1536 break;
1537 set_current_state(TASK_INTERRUPTIBLE); 1533 set_current_state(TASK_INTERRUPTIBLE);
1538 schedule_timeout(delay); 1534 if (!kthread_should_stop() &&
1535 !btrfs_transaction_blocked(root->fs_info))
1536 schedule_timeout(delay);
1539 __set_current_state(TASK_RUNNING); 1537 __set_current_state(TASK_RUNNING);
1540 } 1538 }
1541 } while (!kthread_should_stop()); 1539 } while (!kthread_should_stop());
@@ -1917,17 +1915,18 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1917 1915
1918 csum_root->track_dirty = 1; 1916 csum_root->track_dirty = 1;
1919 1917
1918 fs_info->generation = generation;
1919 fs_info->last_trans_committed = generation;
1920 fs_info->data_alloc_profile = (u64)-1;
1921 fs_info->metadata_alloc_profile = (u64)-1;
1922 fs_info->system_alloc_profile = fs_info->metadata_alloc_profile;
1923
1920 ret = btrfs_read_block_groups(extent_root); 1924 ret = btrfs_read_block_groups(extent_root);
1921 if (ret) { 1925 if (ret) {
1922 printk(KERN_ERR "Failed to read block groups: %d\n", ret); 1926 printk(KERN_ERR "Failed to read block groups: %d\n", ret);
1923 goto fail_block_groups; 1927 goto fail_block_groups;
1924 } 1928 }
1925 1929
1926 fs_info->generation = generation;
1927 fs_info->last_trans_committed = generation;
1928 fs_info->data_alloc_profile = (u64)-1;
1929 fs_info->metadata_alloc_profile = (u64)-1;
1930 fs_info->system_alloc_profile = fs_info->metadata_alloc_profile;
1931 fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, 1930 fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
1932 "btrfs-cleaner"); 1931 "btrfs-cleaner");
1933 if (IS_ERR(fs_info->cleaner_kthread)) 1932 if (IS_ERR(fs_info->cleaner_kthread))
@@ -2430,15 +2429,15 @@ int close_ctree(struct btrfs_root *root)
2430 fs_info->closing = 1; 2429 fs_info->closing = 1;
2431 smp_mb(); 2430 smp_mb();
2432 2431
2433 kthread_stop(root->fs_info->transaction_kthread);
2434 kthread_stop(root->fs_info->cleaner_kthread);
2435
2436 if (!(fs_info->sb->s_flags & MS_RDONLY)) { 2432 if (!(fs_info->sb->s_flags & MS_RDONLY)) {
2437 ret = btrfs_commit_super(root); 2433 ret = btrfs_commit_super(root);
2438 if (ret) 2434 if (ret)
2439 printk(KERN_ERR "btrfs: commit super ret %d\n", ret); 2435 printk(KERN_ERR "btrfs: commit super ret %d\n", ret);
2440 } 2436 }
2441 2437
2438 kthread_stop(root->fs_info->transaction_kthread);
2439 kthread_stop(root->fs_info->cleaner_kthread);
2440
2442 fs_info->closing = 2; 2441 fs_info->closing = 2;
2443 smp_mb(); 2442 smp_mb();
2444 2443