]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - fs/btrfs/tree-log.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[linux-imx.git] / fs / btrfs / tree-log.c
index c276ac9a0ec338c86973a752d74b9e93d22cc9a8..ff60d8978ae264d95709d83342e1c309113521f0 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/blkdev.h>
 #include <linux/list_sort.h>
 #include "ctree.h"
 #include "transaction.h"
@@ -279,11 +280,23 @@ static int process_one_buffer(struct btrfs_root *log,
 {
        int ret = 0;
 
+       /*
+        * If this fs is mixed then we need to be able to process the leaves to
+        * pin down any logged extents, so we have to read the block.
+        */
+       if (btrfs_fs_incompat(log->fs_info, MIXED_GROUPS)) {
+               ret = btrfs_read_buffer(eb, gen);
+               if (ret)
+                       return ret;
+       }
+
        if (wc->pin)
                ret = btrfs_pin_extent_for_log_replay(log->fs_info->extent_root,
                                                      eb->start, eb->len);
 
        if (!ret && btrfs_buffer_uptodate(eb, gen, 0)) {
+               if (wc->pin && btrfs_header_level(eb) == 0)
+                       ret = btrfs_exclude_logged_extents(log, eb);
                if (wc->write)
                        btrfs_write_tree_block(eb);
                if (wc->wait)
@@ -2016,13 +2029,8 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
                                             eb, i, &key);
                        if (ret)
                                break;
-               } else if (key.type == BTRFS_INODE_REF_KEY) {
-                       ret = add_inode_ref(wc->trans, root, log, path,
-                                           eb, i, &key);
-                       if (ret && ret != -ENOENT)
-                               break;
-                       ret = 0;
-               } else if (key.type == BTRFS_INODE_EXTREF_KEY) {
+               } else if (key.type == BTRFS_INODE_REF_KEY ||
+                          key.type == BTRFS_INODE_EXTREF_KEY) {
                        ret = add_inode_ref(wc->trans, root, log, path,
                                            eb, i, &key);
                        if (ret && ret != -ENOENT)
@@ -2358,6 +2366,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        struct btrfs_root *log = root->log_root;
        struct btrfs_root *log_root_tree = root->fs_info->log_root_tree;
        unsigned long log_transid = 0;
+       struct blk_plug plug;
 
        mutex_lock(&root->log_mutex);
        log_transid = root->log_transid;
@@ -2401,8 +2410,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        /* we start IO on  all the marked extents here, but we don't actually
         * wait for them until later.
         */
+       blk_start_plug(&plug);
        ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark);
        if (ret) {
+               blk_finish_plug(&plug);
                btrfs_abort_transaction(trans, root, ret);
                btrfs_free_logged_extents(log, log_transid);
                mutex_unlock(&root->log_mutex);
@@ -2437,6 +2448,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        }
 
        if (ret) {
+               blk_finish_plug(&plug);
                if (ret != -ENOSPC) {
                        btrfs_abort_transaction(trans, root, ret);
                        mutex_unlock(&log_root_tree->log_mutex);
@@ -2452,6 +2464,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
 
        index2 = log_root_tree->log_transid % 2;
        if (atomic_read(&log_root_tree->log_commit[index2])) {
+               blk_finish_plug(&plug);
                btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
                wait_log_commit(trans, log_root_tree,
                                log_root_tree->log_transid);
@@ -2474,6 +2487,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
         * check the full commit flag again
         */
        if (root->fs_info->last_trans_log_full_commit == trans->transid) {
+               blk_finish_plug(&plug);
                btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
                btrfs_free_logged_extents(log, log_transid);
                mutex_unlock(&log_root_tree->log_mutex);
@@ -2481,9 +2495,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                goto out_wake_log_root;
        }
 
-       ret = btrfs_write_and_wait_marked_extents(log_root_tree,
-                               &log_root_tree->dirty_log_pages,
-                               EXTENT_DIRTY | EXTENT_NEW);
+       ret = btrfs_write_marked_extents(log_root_tree,
+                                        &log_root_tree->dirty_log_pages,
+                                        EXTENT_DIRTY | EXTENT_NEW);
+       blk_finish_plug(&plug);
        if (ret) {
                btrfs_abort_transaction(trans, root, ret);
                btrfs_free_logged_extents(log, log_transid);
@@ -2491,6 +2506,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                goto out_wake_log_root;
        }
        btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
+       btrfs_wait_marked_extents(log_root_tree,
+                                 &log_root_tree->dirty_log_pages,
+                                 EXTENT_NEW | EXTENT_DIRTY);
        btrfs_wait_logged_extents(log, log_transid);
 
        btrfs_set_super_log_root(root->fs_info->super_for_commit,
@@ -3728,8 +3746,9 @@ next_slot:
        }
 
 log_extents:
+       btrfs_release_path(path);
+       btrfs_release_path(dst_path);
        if (fast_search) {
-               btrfs_release_path(dst_path);
                ret = btrfs_log_changed_extents(trans, root, inode, dst_path);
                if (ret) {
                        err = ret;
@@ -3746,8 +3765,6 @@ log_extents:
        }
 
        if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) {
-               btrfs_release_path(path);
-               btrfs_release_path(dst_path);
                ret = log_directory_changes(trans, root, inode, path, dst_path);
                if (ret) {
                        err = ret;
@@ -4016,8 +4033,7 @@ again:
                if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID)
                        break;
 
-               log = btrfs_read_fs_root_no_radix(log_root_tree,
-                                                 &found_key);
+               log = btrfs_read_fs_root(log_root_tree, &found_key);
                if (IS_ERR(log)) {
                        ret = PTR_ERR(log);
                        btrfs_error(fs_info, ret,