]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/btrfs/ordered-data.c
ASoC: max98357a: Document MAX98357A bindings
[karo-tx-linux.git] / fs / btrfs / ordered-data.c
index ac734ec4cc20ecbc47bc1b495b75021b4c699edf..534544e08f769486a97c3c7f3719bed982500783 100644 (file)
@@ -220,6 +220,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
        INIT_LIST_HEAD(&entry->work_list);
        init_completion(&entry->completion);
        INIT_LIST_HEAD(&entry->log_list);
+       INIT_LIST_HEAD(&entry->trans_list);
 
        trace_btrfs_ordered_extent_add(inode, entry);
 
@@ -431,19 +432,31 @@ out:
 
 /* Needs to either be called under a log transaction or the log_mutex */
 void btrfs_get_logged_extents(struct inode *inode,
-                             struct list_head *logged_list)
+                             struct list_head *logged_list,
+                             const loff_t start,
+                             const loff_t end)
 {
        struct btrfs_ordered_inode_tree *tree;
        struct btrfs_ordered_extent *ordered;
        struct rb_node *n;
+       struct rb_node *prev;
 
        tree = &BTRFS_I(inode)->ordered_tree;
        spin_lock_irq(&tree->lock);
-       for (n = rb_first(&tree->tree); n; n = rb_next(n)) {
+       n = __tree_search(&tree->tree, end, &prev);
+       if (!n)
+               n = prev;
+       for (; n; n = rb_prev(n)) {
                ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node);
+               if (ordered->file_offset > end)
+                       continue;
+               if (entry_end(ordered) <= start)
+                       break;
                if (!list_empty(&ordered->log_list))
                        continue;
-               list_add_tail(&ordered->log_list, logged_list);
+               if (test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags))
+                       continue;
+               list_add(&ordered->log_list, logged_list);
                atomic_inc(&ordered->refs);
        }
        spin_unlock_irq(&tree->lock);
@@ -472,7 +485,8 @@ 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_root *log, u64 transid)
+void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
+                              struct btrfs_root *log, u64 transid)
 {
        struct btrfs_ordered_extent *ordered;
        int index = transid % 2;
@@ -497,7 +511,8 @@ void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid)
                wait_event(ordered->wait, test_bit(BTRFS_ORDERED_IO_DONE,
                                                   &ordered->flags));
 
-               btrfs_put_ordered_extent(ordered);
+               if (!test_and_set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags))
+                       list_add_tail(&ordered->trans_list, &trans->ordered);
                spin_lock_irq(&log->log_extents_lock[index]);
        }
        spin_unlock_irq(&log->log_extents_lock[index]);
@@ -725,30 +740,10 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
        /* start IO across the range first to instantiate any delalloc
         * extents
         */
-       ret = filemap_fdatawrite_range(inode->i_mapping, start, orig_end);
+       ret = btrfs_fdatawrite_range(inode, start, orig_end);
        if (ret)
                return ret;
-       /*
-        * So with compression we will find and lock a dirty page and clear the
-        * first one as dirty, setup an async extent, and immediately return
-        * with the entire range locked but with nobody actually marked with
-        * writeback.  So we can't just filemap_write_and_wait_range() and
-        * expect it to work since it will just kick off a thread to do the
-        * actual work.  So we need to call filemap_fdatawrite_range _again_
-        * since it will wait on the page lock, which won't be unlocked until
-        * after the pages have been marked as writeback and so we're good to go
-        * from there.  We have to do this otherwise we'll miss the ordered
-        * extents and that results in badness.  Please Josef, do not think you
-        * know better and pull this out at some point in the future, it is
-        * right and you are wrong.
-        */
-       if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
-                    &BTRFS_I(inode)->runtime_flags)) {
-               ret = filemap_fdatawrite_range(inode->i_mapping, start,
-                                              orig_end);
-               if (ret)
-                       return ret;
-       }
+
        ret = filemap_fdatawait_range(inode->i_mapping, start, orig_end);
        if (ret)
                return ret;