]> git.hungrycats.org Git - linux/commitdiff
Btrfs: make fsync fast again
authorJosef Bacik <jbacik@fb.com>
Tue, 25 Aug 2015 16:54:39 +0000 (12:54 -0400)
committerZygo Blaxell <zblaxell@thirteen.furryterror.org>
Sat, 17 Oct 2015 03:11:55 +0000 (23:11 -0400)
Filipe removed the main reason I made fsync fast, which was to move the waiting
on ordered IO while we're logging extents.  This patch preserves his need to
catch IO errors and my need for fsync performance to not suck donkey balls.
Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
(cherry picked from commit 67921b028b4a52ae65e6260228d311fa39659e99)
(cherry picked from commit 5252010ae22d84a32aa17a71e6407312b89d4b0e)
(cherry picked from commit 0db052656b316c6dbcbfcf2b91ee9854c2d54308)

fs/btrfs/ordered-data.c
fs/btrfs/ordered-data.h
fs/btrfs/tree-log.c

index 52170cf1757e3d25192a6cf6211a9d2edaa52751..611b0ab832405c1be2cf34f0143a0b18ac1400f2 100644 (file)
@@ -476,11 +476,12 @@ void btrfs_submit_logged_extents(struct list_head *logged_list,
        spin_unlock_irq(&log->log_extents_lock[index]);
 }
 
-void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
-                              struct btrfs_root *log, u64 transid)
+int btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
+                             struct btrfs_root *log, u64 transid)
 {
        struct btrfs_ordered_extent *ordered;
        int index = transid % 2;
+       int ret = 0;
 
        spin_lock_irq(&log->log_extents_lock[index]);
        while (!list_empty(&log->logged_list[index])) {
@@ -502,6 +503,9 @@ void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
                wait_event(ordered->wait, test_bit(BTRFS_ORDERED_IO_DONE,
                                                   &ordered->flags));
 
+               if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags))
+                       ret = -EIO;
+
                /*
                 * If our ordered extent completed it means it updated the
                 * fs/subvol and csum trees already, so no need to make the
@@ -520,6 +524,7 @@ void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
                spin_lock_irq(&log->log_extents_lock[index]);
        }
        spin_unlock_irq(&log->log_extents_lock[index]);
+       return ret;
 }
 
 void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid)
index 7176cc0fe43f7074ffa3c959bb3a7eae0d3b90e2..6fbe6af34c6101113fa39c6d39a59a745d20ac90 100644 (file)
@@ -204,8 +204,8 @@ void btrfs_get_logged_extents(struct inode *inode,
 void btrfs_put_logged_extents(struct list_head *logged_list);
 void btrfs_submit_logged_extents(struct list_head *logged_list,
                                 struct btrfs_root *log);
-void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
-                              struct btrfs_root *log, u64 transid);
+int btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
+                             struct btrfs_root *log, u64 transid);
 void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid);
 int __init ordered_data_init(void);
 void ordered_data_exit(void);
index 55443ce4c8794389c62ab50e52203eb4ca4519a7..1705f2fdf82a656905aff17905ddca9187b3049e 100644 (file)
@@ -2858,8 +2858,11 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                blk_finish_plug(&plug);
                ret = btrfs_wait_marked_extents(log, &log->dirty_log_pages,
                                                mark);
-               btrfs_wait_logged_extents(trans, log, log_transid);
+               if (!ret)
+                       ret = btrfs_wait_logged_extents(trans, log,
+                                                 log_transid);
                if (ret) {
+                       btrfs_free_logged_extents(log, log_transid);
                        btrfs_set_log_full_commit(root->fs_info, trans);
                        ctx->io_err = ret;
                }
@@ -2915,7 +2918,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                mutex_unlock(&log_root_tree->log_mutex);
                goto out_wake_log_root;
        }
-       btrfs_wait_logged_extents(trans, log, log_transid);
+       ret = btrfs_wait_logged_extents(trans, log, log_transid);
 
        btrfs_set_super_log_root(root->fs_info->super_for_commit,
                                log_root_tree->node->start);
@@ -3881,12 +3884,10 @@ static int extent_cmp(void *priv, struct list_head *a, struct list_head *b)
        return 0;
 }
 
-static int wait_ordered_extents(struct btrfs_trans_handle *trans,
-                               struct inode *inode,
-                               struct btrfs_root *root,
-                               const struct extent_map *em,
-                               const struct list_head *logged_list,
-                               bool *ordered_io_error)
+static int log_csums(struct btrfs_trans_handle *trans, struct inode *inode,
+                    struct btrfs_root *root, const struct extent_map *em,
+                    const struct list_head *logged_list,
+                    bool *ordered_io_error)
 {
        struct btrfs_ordered_extent *ordered;
        struct btrfs_root *log = root->log_root;
@@ -3919,20 +3920,6 @@ static int wait_ordered_extents(struct btrfs_trans_handle *trans,
                    mod_start + mod_len <= ordered->file_offset)
                        continue;
 
-               if (!test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags) &&
-                   !test_bit(BTRFS_ORDERED_IOERR, &ordered->flags) &&
-                   !test_bit(BTRFS_ORDERED_DIRECT, &ordered->flags)) {
-                       const u64 start = ordered->file_offset;
-                       const u64 end = ordered->file_offset + ordered->len - 1;
-
-                       WARN_ON(ordered->inode != inode);
-                       filemap_fdatawrite_range(inode->i_mapping, start, end);
-               }
-
-               wait_event(ordered->wait,
-                          (test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags) ||
-                           test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)));
-
                if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)) {
                        /*
                         * Clear the AS_EIO/AS_ENOSPC flags from the inode's
@@ -4042,8 +4029,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
        int extent_inserted = 0;
        bool ordered_io_err = false;
 
-       ret = wait_ordered_extents(trans, inode, root, em, logged_list,
-                                  &ordered_io_err);
+       ret = log_csums(trans, inode, root, em, logged_list, &ordered_io_err);
        if (ret)
                return ret;