}
 
+static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode,
+                                        const u64 start,
+                                        const u64 len,
+                                        struct extent_state **cached_state)
+{
+       u64 search_start = start;
+       const u64 end = start + len - 1;
+
+       while (search_start < end) {
+               const u64 search_len = end - search_start + 1;
+               struct extent_map *em;
+               u64 em_len;
+               int ret = 0;
+
+               em = btrfs_get_extent(inode, NULL, 0, search_start,
+                                     search_len, 0);
+               if (IS_ERR(em))
+                       return PTR_ERR(em);
+
+               if (em->block_start != EXTENT_MAP_HOLE)
+                       goto next;
+
+               em_len = em->len;
+               if (em->start < search_start)
+                       em_len -= search_start - em->start;
+               if (em_len > search_len)
+                       em_len = search_len;
+
+               ret = set_extent_bit(&inode->io_tree, search_start,
+                                    search_start + em_len - 1,
+                                    EXTENT_DELALLOC_NEW,
+                                    NULL, cached_state, GFP_NOFS);
+next:
+               search_start = extent_map_end(em);
+               free_extent_map(em);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
+
 /*
  * This function locks the extent and properly waits for data=ordered extents
  * to finish before allowing the pages to be modified if need.
                + round_up(pos + write_bytes - start_pos,
                           fs_info->sectorsize) - 1;
 
-       if (start_pos < inode->vfs_inode.i_size) {
+       if (start_pos < inode->vfs_inode.i_size ||
+           (inode->flags & BTRFS_INODE_PREALLOC)) {
                struct btrfs_ordered_extent *ordered;
+               unsigned int clear_bits;
+
                lock_extent_bits(&inode->io_tree, start_pos, last_pos,
                                cached_state);
                ordered = btrfs_lookup_ordered_range(inode, start_pos,
                }
                if (ordered)
                        btrfs_put_ordered_extent(ordered);
-
+               ret = btrfs_find_new_delalloc_bytes(inode, start_pos,
+                                                   last_pos - start_pos + 1,
+                                                   cached_state);
+               clear_bits = EXTENT_DIRTY | EXTENT_DELALLOC |
+                       EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG;
+               if (ret)
+                       clear_bits |= EXTENT_DELALLOC_NEW | EXTENT_LOCKED;
                clear_extent_bit(&inode->io_tree, start_pos,
-                                 last_pos, EXTENT_DIRTY | EXTENT_DELALLOC |
-                                 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
-                                 0, 0, cached_state, GFP_NOFS);
+                                last_pos, clear_bits,
+                                (clear_bits & EXTENT_LOCKED) ? 1 : 0,
+                                0, cached_state, GFP_NOFS);
+               if (ret)
+                       return ret;
                *lockstart = start_pos;
                *lockend = last_pos;
                ret = 1;
 
                }
                if (ret <= 0) {
                        unsigned long clear_flags = EXTENT_DELALLOC |
-                               EXTENT_DEFRAG;
+                               EXTENT_DELALLOC_NEW | EXTENT_DEFRAG;
                        unsigned long page_error_op;
 
                        clear_flags |= (ret < 0) ? EXTENT_DO_ACCOUNTING : 0;
                                     async_extent->start +
                                     async_extent->ram_size - 1,
                                     NULL, EXTENT_LOCKED | EXTENT_DELALLOC |
+                                    EXTENT_DELALLOC_NEW |
                                     EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING,
                                     PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
                                     PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK |
                        extent_clear_unlock_delalloc(inode, start, end,
                                     delalloc_end, NULL,
                                     EXTENT_LOCKED | EXTENT_DELALLOC |
+                                    EXTENT_DELALLOC_NEW |
                                     EXTENT_DEFRAG, PAGE_UNLOCK |
                                     PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK |
                                     PAGE_END_WRITEBACK);
        btrfs_dec_block_group_reservations(fs_info, ins.objectid);
        btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, 1);
 out_unlock:
-       clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DEFRAG |
-               EXTENT_CLEAR_META_RESV;
+       clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
+               EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV;
        page_ops = PAGE_UNLOCK | PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK |
                PAGE_END_WRITEBACK;
        /*
                        btrfs_add_delalloc_inodes(root, inode);
                spin_unlock(&BTRFS_I(inode)->lock);
        }
+
+       if (!(state->state & EXTENT_DELALLOC_NEW) &&
+           (*bits & EXTENT_DELALLOC_NEW)) {
+               spin_lock(&BTRFS_I(inode)->lock);
+               BTRFS_I(inode)->new_delalloc_bytes += state->end + 1 -
+                       state->start;
+               spin_unlock(&BTRFS_I(inode)->lock);
+       }
 }
 
 /*
                        btrfs_del_delalloc_inode(root, inode);
                spin_unlock(&inode->lock);
        }
+
+       if ((state->state & EXTENT_DELALLOC_NEW) &&
+           (*bits & EXTENT_DELALLOC_NEW)) {
+               spin_lock(&inode->lock);
+               ASSERT(inode->new_delalloc_bytes >= len);
+               inode->new_delalloc_bytes -= len;
+               spin_unlock(&inode->lock);
+       }
 }
 
 /*
        u64 logical_len = ordered_extent->len;
        bool nolock;
        bool truncated = false;
+       bool range_locked = false;
+       bool clear_new_delalloc_bytes = false;
+
+       if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) &&
+           !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags) &&
+           !test_bit(BTRFS_ORDERED_DIRECT, &ordered_extent->flags))
+               clear_new_delalloc_bytes = true;
 
        nolock = btrfs_is_free_space_inode(BTRFS_I(inode));
 
                goto out;
        }
 
+       range_locked = true;
        lock_extent_bits(io_tree, ordered_extent->file_offset,
                         ordered_extent->file_offset + ordered_extent->len - 1,
                         &cached_state);
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
                trans = NULL;
-               goto out_unlock;
+               goto out;
        }
 
        trans->block_rsv = &fs_info->delalloc_block_rsv;
                           trans->transid);
        if (ret < 0) {
                btrfs_abort_transaction(trans, ret);
-               goto out_unlock;
+               goto out;
        }
 
        add_pending_csums(trans, inode, &ordered_extent->list);
        ret = btrfs_update_inode_fallback(trans, root, inode);
        if (ret) { /* -ENOMEM or corruption */
                btrfs_abort_transaction(trans, ret);
-               goto out_unlock;
+               goto out;
        }
        ret = 0;
-out_unlock:
-       unlock_extent_cached(io_tree, ordered_extent->file_offset,
-                            ordered_extent->file_offset +
-                            ordered_extent->len - 1, &cached_state, GFP_NOFS);
 out:
+       if (range_locked || clear_new_delalloc_bytes) {
+               unsigned int clear_bits = 0;
+
+               if (range_locked)
+                       clear_bits |= EXTENT_LOCKED;
+               if (clear_new_delalloc_bytes)
+                       clear_bits |= EXTENT_DELALLOC_NEW;
+               clear_extent_bit(&BTRFS_I(inode)->io_tree,
+                                ordered_extent->file_offset,
+                                ordered_extent->file_offset +
+                                ordered_extent->len - 1,
+                                clear_bits,
+                                (clear_bits & EXTENT_LOCKED) ? 1 : 0,
+                                0, &cached_state, GFP_NOFS);
+       }
+
        if (root != fs_info->tree_root)
                btrfs_delalloc_release_metadata(BTRFS_I(inode),
                                ordered_extent->len);
                if (!inode_evicting)
                        clear_extent_bit(tree, start, end,
                                         EXTENT_DIRTY | EXTENT_DELALLOC |
+                                        EXTENT_DELALLOC_NEW |
                                         EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
                                         EXTENT_DEFRAG, 1, 0, &cached_state,
                                         GFP_NOFS);
        if (!inode_evicting) {
                clear_extent_bit(tree, page_start, page_end,
                                 EXTENT_LOCKED | EXTENT_DIRTY |
-                                EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING |
-                                EXTENT_DEFRAG, 1, 1,
+                                EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
+                                EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 1, 1,
                                 &cached_state, GFP_NOFS);
 
                __btrfs_releasepage(page, GFP_NOFS);
        ei->last_sub_trans = 0;
        ei->logged_trans = 0;
        ei->delalloc_bytes = 0;
+       ei->new_delalloc_bytes = 0;
        ei->defrag_bytes = 0;
        ei->disk_i_size = 0;
        ei->flags = 0;
        WARN_ON(BTRFS_I(inode)->outstanding_extents);
        WARN_ON(BTRFS_I(inode)->reserved_extents);
        WARN_ON(BTRFS_I(inode)->delalloc_bytes);
+       WARN_ON(BTRFS_I(inode)->new_delalloc_bytes);
        WARN_ON(BTRFS_I(inode)->csum_bytes);
        WARN_ON(BTRFS_I(inode)->defrag_bytes);
 
        stat->dev = BTRFS_I(inode)->root->anon_dev;
 
        spin_lock(&BTRFS_I(inode)->lock);
-       delalloc_bytes = BTRFS_I(inode)->delalloc_bytes;
+       delalloc_bytes = BTRFS_I(inode)->new_delalloc_bytes;
        spin_unlock(&BTRFS_I(inode)->lock);
        stat->blocks = (ALIGN(inode_get_bytes(inode), blocksize) +
                        ALIGN(delalloc_bytes, blocksize)) >> 9;