diff options
author | Yan, Zheng <zheng.yan@oracle.com> | 2010-05-16 10:49:58 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2010-05-25 10:34:52 -0400 |
commit | 8929ecfa50f266163832eeacfbc3642ed5eb83b6 (patch) | |
tree | e0177748af36d49d5f652cff0e421a8268cf7194 /fs/btrfs/disk-io.c | |
parent | 0ca1f7ceb1991099ed5273885ebcf4323948c72e (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.c | 59 |
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 | } | ||
1528 | sleep: | 1526 | sleep: |
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 | ||