btrfs: Split btrfs_del_delalloc_inode into 2 functions
[sfrench/cifs-2.6.git] / fs / btrfs / inode.c
index 8f7d41fcfbff62487c8271494ce780a00318ba5d..8e604e7071f14cf166652369e6f167fab5b5f462 100644 (file)
@@ -1,19 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2007 Oracle.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
  */
 
 #include <linux/kernel.h>
@@ -43,6 +30,8 @@
 #include <linux/posix_acl_xattr.h>
 #include <linux/uio.h>
 #include <linux/magic.h>
+#include <linux/iversion.h>
+#include <asm/unaligned.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -57,7 +46,6 @@
 #include "free-space-cache.h"
 #include "inode-map.h"
 #include "backref.h"
-#include "hash.h"
 #include "props.h"
 #include "qgroup.h"
 #include "dedupe.h"
@@ -101,7 +89,7 @@ static const unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = {
 };
 
 static int btrfs_setsize(struct inode *inode, struct iattr *attr);
-static int btrfs_truncate(struct inode *inode);
+static int btrfs_truncate(struct inode *inode, bool skip_writeback);
 static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent);
 static noinline int cow_file_range(struct inode *inode,
                                   struct page *locked_page,
@@ -276,12 +264,12 @@ fail:
  * does the checks required to make sure the data is small enough
  * to fit as an inline extent.
  */
-static noinline int cow_file_range_inline(struct btrfs_root *root,
-                                         struct inode *inode, u64 start,
+static noinline int cow_file_range_inline(struct inode *inode, u64 start,
                                          u64 end, size_t compressed_size,
                                          int compress_type,
                                          struct page **compressed_pages)
 {
+       struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct btrfs_trans_handle *trans;
        u64 isize = i_size_read(inode);
@@ -457,7 +445,6 @@ static noinline void compress_file_range(struct inode *inode,
                                        int *num_added)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct btrfs_root *root = BTRFS_I(inode)->root;
        u64 blocksize = fs_info->sectorsize;
        u64 actual_end;
        u64 isize = i_size_read(inode);
@@ -579,11 +566,11 @@ cont:
                        /* we didn't compress the entire range, try
                         * to make an uncompressed inline extent.
                         */
-                       ret = cow_file_range_inline(root, inode, start, end,
-                                           0, BTRFS_COMPRESS_NONE, NULL);
+                       ret = cow_file_range_inline(inode, start, end, 0,
+                                                   BTRFS_COMPRESS_NONE, NULL);
                } else {
                        /* try making a compressed inline extent */
-                       ret = cow_file_range_inline(root, inode, start, end,
+                       ret = cow_file_range_inline(inode, start, end,
                                                    total_compressed,
                                                    compress_type, pages);
                }
@@ -960,7 +947,6 @@ static noinline int cow_file_range(struct inode *inode,
        u64 alloc_hint = 0;
        u64 num_bytes;
        unsigned long ram_size;
-       u64 disk_num_bytes;
        u64 cur_alloc_size = 0;
        u64 blocksize = fs_info->sectorsize;
        struct btrfs_key ins;
@@ -978,14 +964,14 @@ static noinline int cow_file_range(struct inode *inode,
 
        num_bytes = ALIGN(end - start + 1, blocksize);
        num_bytes = max(blocksize,  num_bytes);
-       disk_num_bytes = num_bytes;
+       ASSERT(num_bytes <= btrfs_super_total_bytes(fs_info->super_copy));
 
        inode_should_defrag(BTRFS_I(inode), start, end, num_bytes, SZ_64K);
 
        if (start == 0) {
                /* lets try to make an inline extent */
-               ret = cow_file_range_inline(root, inode, start, end, 0,
-                                       BTRFS_COMPRESS_NONE, NULL);
+               ret = cow_file_range_inline(inode, start, end, 0,
+                                           BTRFS_COMPRESS_NONE, NULL);
                if (ret == 0) {
                        /*
                         * We use DO_ACCOUNTING here because we need the
@@ -1009,15 +995,12 @@ static noinline int cow_file_range(struct inode *inode,
                }
        }
 
-       BUG_ON(disk_num_bytes >
-              btrfs_super_total_bytes(fs_info->super_copy));
-
        alloc_hint = get_extent_allocation_hint(inode, start, num_bytes);
        btrfs_drop_extent_cache(BTRFS_I(inode), start,
                        start + num_bytes - 1, 0);
 
-       while (disk_num_bytes > 0) {
-               cur_alloc_size = disk_num_bytes;
+       while (num_bytes > 0) {
+               cur_alloc_size = num_bytes;
                ret = btrfs_reserve_extent(root, cur_alloc_size, cur_alloc_size,
                                           fs_info->sectorsize, 0, alloc_hint,
                                           &ins, 1, 1);
@@ -1081,11 +1064,10 @@ static noinline int cow_file_range(struct inode *inode,
                                             delalloc_end, locked_page,
                                             EXTENT_LOCKED | EXTENT_DELALLOC,
                                             page_ops);
-               if (disk_num_bytes < cur_alloc_size)
-                       disk_num_bytes = 0;
+               if (num_bytes < cur_alloc_size)
+                       num_bytes = 0;
                else
-                       disk_num_bytes -= cur_alloc_size;
-               num_bytes -= cur_alloc_size;
+                       num_bytes -= cur_alloc_size;
                alloc_hint = ins.objectid + ins.offset;
                start += cur_alloc_size;
                extent_reserved = false;
@@ -1261,6 +1243,8 @@ static noinline int csum_exist_in_range(struct btrfs_fs_info *fs_info,
                list_del(&sums->list);
                kfree(sums);
        }
+       if (ret < 0)
+               return ret;
        return 1;
 }
 
@@ -1393,10 +1377,23 @@ next_slot:
                                goto out_check;
                        if (btrfs_extent_readonly(fs_info, disk_bytenr))
                                goto out_check;
-                       if (btrfs_cross_ref_exist(root, ino,
-                                                 found_key.offset -
-                                                 extent_offset, disk_bytenr))
+                       ret = btrfs_cross_ref_exist(root, ino,
+                                                   found_key.offset -
+                                                   extent_offset, disk_bytenr);
+                       if (ret) {
+                               /*
+                                * ret could be -EIO if the above fails to read
+                                * metadata.
+                                */
+                               if (ret < 0) {
+                                       if (cow_start != (u64)-1)
+                                               cur_offset = cow_start;
+                                       goto error;
+                               }
+
+                               WARN_ON_ONCE(nolock);
                                goto out_check;
+                       }
                        disk_bytenr += extent_offset;
                        disk_bytenr += cur_offset - found_key.offset;
                        num_bytes = min(end + 1, extent_end) - cur_offset;
@@ -1414,10 +1411,22 @@ next_slot:
                         * this ensure that csum for a given extent are
                         * either valid or do not exist.
                         */
-                       if (csum_exist_in_range(fs_info, disk_bytenr,
-                                               num_bytes)) {
+                       ret = csum_exist_in_range(fs_info, disk_bytenr,
+                                                 num_bytes);
+                       if (ret) {
                                if (!nolock)
                                        btrfs_end_write_no_snapshotting(root);
+
+                               /*
+                                * ret could be -EIO if the above fails to read
+                                * metadata.
+                                */
+                               if (ret < 0) {
+                                       if (cow_start != (u64)-1)
+                                               cur_offset = cow_start;
+                                       goto error;
+                               }
+                               WARN_ON_ONCE(nolock);
                                goto out_check;
                        }
                        if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) {
@@ -1733,12 +1742,12 @@ static void btrfs_add_delalloc_inodes(struct btrfs_root *root,
        spin_unlock(&root->delalloc_lock);
 }
 
-static void btrfs_del_delalloc_inode(struct btrfs_root *root,
-                                    struct btrfs_inode *inode)
+
+void __btrfs_del_delalloc_inode(struct btrfs_root *root,
+                               struct btrfs_inode *inode)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
 
-       spin_lock(&root->delalloc_lock);
        if (!list_empty(&inode->delalloc_inodes)) {
                list_del_init(&inode->delalloc_inodes);
                clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
@@ -1751,6 +1760,13 @@ static void btrfs_del_delalloc_inode(struct btrfs_root *root,
                        spin_unlock(&fs_info->delalloc_root_lock);
                }
        }
+}
+
+static void btrfs_del_delalloc_inode(struct btrfs_root *root,
+                                    struct btrfs_inode *inode)
+{
+       spin_lock(&root->delalloc_lock);
+       __btrfs_del_delalloc_inode(root, inode);
        spin_unlock(&root->delalloc_lock);
 }
 
@@ -1846,7 +1862,7 @@ static void btrfs_clear_bit_hook(void *private_data,
                 */
                if (*bits & EXTENT_CLEAR_META_RESV &&
                    root != fs_info->tree_root)
-                       btrfs_delalloc_release_metadata(inode, len);
+                       btrfs_delalloc_release_metadata(inode, len, false);
 
                /* For sanity tests. */
                if (btrfs_is_testing(fs_info))
@@ -1920,8 +1936,7 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
  * At IO completion time the cums attached on the ordered extent record
  * are inserted into the btree
  */
-static blk_status_t __btrfs_submit_bio_start(void *private_data, struct bio *bio,
-                                   int mirror_num, unsigned long bio_flags,
+static blk_status_t btrfs_submit_bio_start(void *private_data, struct bio *bio,
                                    u64 bio_offset)
 {
        struct inode *inode = private_data;
@@ -1940,9 +1955,8 @@ static blk_status_t __btrfs_submit_bio_start(void *private_data, struct bio *bio
  * At IO completion time the cums attached on the ordered extent record
  * are inserted into the btree
  */
-static blk_status_t __btrfs_submit_bio_done(void *private_data, struct bio *bio,
-                         int mirror_num, unsigned long bio_flags,
-                         u64 bio_offset)
+static blk_status_t btrfs_submit_bio_done(void *private_data, struct bio *bio,
+                         int mirror_num)
 {
        struct inode *inode = private_data;
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -2014,8 +2028,8 @@ static blk_status_t btrfs_submit_bio_hook(void *private_data, struct bio *bio,
                /* we're doing a write, do the async checksumming */
                ret = btrfs_wq_submit_bio(fs_info, bio, mirror_num, bio_flags,
                                          bio_offset, inode,
-                                         __btrfs_submit_bio_start,
-                                         __btrfs_submit_bio_done);
+                                         btrfs_submit_bio_start,
+                                         btrfs_submit_bio_done);
                goto out;
        } else if (!skip_sum) {
                ret = btrfs_csum_one_bio(inode, bio, 0, 0);
@@ -2133,7 +2147,7 @@ again:
 
        ClearPageChecked(page);
        set_page_dirty(page);
-       btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+       btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, false);
 out:
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
                             &cached_state);
@@ -2753,12 +2767,10 @@ static void relink_file_extents(struct new_sa_defrag_extent *new)
        struct sa_defrag_extent_backref *backref;
        struct sa_defrag_extent_backref *prev = NULL;
        struct inode *inode;
-       struct btrfs_root *root;
        struct rb_node *node;
        int ret;
 
        inode = new->inode;
-       root = BTRFS_I(inode)->root;
 
        path = btrfs_alloc_path();
        if (!path)
@@ -3246,6 +3258,16 @@ static int btrfs_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
                                      start, (size_t)(end - start + 1));
 }
 
+/*
+ * btrfs_add_delayed_iput - perform a delayed iput on @inode
+ *
+ * @inode: The inode we want to perform iput on
+ *
+ * This function uses the generic vfs_inode::i_count to track whether we should
+ * just decrement it (in case it's > 1) or if this is the last iput then link
+ * the inode to the delayed iput machinery. Delayed iputs are processed at
+ * transaction commit time/superblock commit/cleaner kthread.
+ */
 void btrfs_add_delayed_iput(struct inode *inode)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -3255,12 +3277,8 @@ void btrfs_add_delayed_iput(struct inode *inode)
                return;
 
        spin_lock(&fs_info->delayed_iput_lock);
-       if (binode->delayed_iput_count == 0) {
-               ASSERT(list_empty(&binode->delayed_iput));
-               list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs);
-       } else {
-               binode->delayed_iput_count++;
-       }
+       ASSERT(list_empty(&binode->delayed_iput));
+       list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs);
        spin_unlock(&fs_info->delayed_iput_lock);
 }
 
@@ -3273,13 +3291,7 @@ void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info)
 
                inode = list_first_entry(&fs_info->delayed_iputs,
                                struct btrfs_inode, delayed_iput);
-               if (inode->delayed_iput_count) {
-                       inode->delayed_iput_count--;
-                       list_move_tail(&inode->delayed_iput,
-                                       &fs_info->delayed_iputs);
-               } else {
-                       list_del_init(&inode->delayed_iput);
-               }
+               list_del_init(&inode->delayed_iput);
                spin_unlock(&fs_info->delayed_iput_lock);
                iput(&inode->vfs_inode);
                spin_lock(&fs_info->delayed_iput_lock);
@@ -3349,7 +3361,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
        struct btrfs_root *root = inode->root;
        struct btrfs_block_rsv *block_rsv = NULL;
        int reserve = 0;
-       int insert = 0;
+       bool insert = false;
        int ret;
 
        if (!root->orphan_block_rsv) {
@@ -3359,7 +3371,16 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
                        return -ENOMEM;
        }
 
+       if (!test_and_set_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
+                             &inode->runtime_flags))
+               insert = true;
+
+       if (!test_and_set_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
+                             &inode->runtime_flags))
+               reserve = 1;
+
        spin_lock(&root->orphan_lock);
+       /* If someone has created ->orphan_block_rsv, be happy to use it. */
        if (!root->orphan_block_rsv) {
                root->orphan_block_rsv = block_rsv;
        } else if (block_rsv) {
@@ -3367,26 +3388,8 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
                block_rsv = NULL;
        }
 
-       if (!test_and_set_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
-                             &inode->runtime_flags)) {
-#if 0
-               /*
-                * For proper ENOSPC handling, we should do orphan
-                * cleanup when mounting. But this introduces backward
-                * compatibility issue.
-                */
-               if (!xchg(&root->orphan_item_inserted, 1))
-                       insert = 2;
-               else
-                       insert = 1;
-#endif
-               insert = 1;
+       if (insert)
                atomic_inc(&root->orphan_inodes);
-       }
-
-       if (!test_and_set_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
-                             &inode->runtime_flags))
-               reserve = 1;
        spin_unlock(&root->orphan_lock);
 
        /* grab metadata reservation from transaction handle */
@@ -3410,7 +3413,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
        }
 
        /* insert an orphan item to track this unlinked/truncated file */
-       if (insert >= 1) {
+       if (insert) {
                ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode));
                if (ret) {
                        if (reserve) {
@@ -3434,15 +3437,6 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
                ret = 0;
        }
 
-       /* insert an orphan item to track subvolume contains orphan files */
-       if (insert >= 2) {
-               ret = btrfs_insert_orphan_item(trans, fs_info->tree_root,
-                                              root->root_key.objectid);
-               if (ret && ret != -EEXIST) {
-                       btrfs_abort_transaction(trans, ret);
-                       return ret;
-               }
-       }
        return 0;
 }
 
@@ -3643,7 +3637,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
                                goto out;
                        }
 
-                       ret = btrfs_truncate(inode);
+                       ret = btrfs_truncate(inode, false);
                        if (ret)
                                btrfs_orphan_del(NULL, BTRFS_I(inode));
                } else {
@@ -3820,7 +3814,8 @@ static int btrfs_read_locked_inode(struct inode *inode)
        BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item);
        BTRFS_I(inode)->last_trans = btrfs_inode_transid(leaf, inode_item);
 
-       inode->i_version = btrfs_inode_sequence(leaf, inode_item);
+       inode_set_iversion_queried(inode,
+                                  btrfs_inode_sequence(leaf, inode_item));
        inode->i_generation = BTRFS_I(inode)->generation;
        inode->i_rdev = 0;
        rdev = btrfs_inode_rdev(leaf, inode_item);
@@ -3988,7 +3983,8 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
                                     &token);
        btrfs_set_token_inode_generation(leaf, item, BTRFS_I(inode)->generation,
                                         &token);
-       btrfs_set_token_inode_sequence(leaf, item, inode->i_version, &token);
+       btrfs_set_token_inode_sequence(leaf, item, inode_peek_iversion(inode),
+                                      &token);
        btrfs_set_token_inode_transid(leaf, item, trans->transid, &token);
        btrfs_set_token_inode_rdev(leaf, item, inode->i_rdev, &token);
        btrfs_set_token_inode_flags(leaf, item, BTRFS_I(inode)->flags, &token);
@@ -4708,7 +4704,6 @@ delete:
                                if (updates) {
                                        trans->delayed_ref_updates = 0;
                                        ret = btrfs_run_delayed_refs(trans,
-                                                                  fs_info,
                                                                   updates * 2);
                                        if (ret && !err)
                                                err = ret;
@@ -4748,8 +4743,7 @@ error:
                unsigned long updates = trans->delayed_ref_updates;
                if (updates) {
                        trans->delayed_ref_updates = 0;
-                       ret = btrfs_run_delayed_refs(trans, fs_info,
-                                                    updates * 2);
+                       ret = btrfs_run_delayed_refs(trans, updates * 2);
                        if (ret && !err)
                                err = ret;
                }
@@ -4803,8 +4797,8 @@ again:
        page = find_or_create_page(mapping, index, mask);
        if (!page) {
                btrfs_delalloc_release_space(inode, data_reserved,
-                                            block_start, blocksize);
-               btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize);
+                                            block_start, blocksize, true);
+               btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize, true);
                ret = -ENOMEM;
                goto out;
        }
@@ -4871,8 +4865,8 @@ again:
 out_unlock:
        if (ret)
                btrfs_delalloc_release_space(inode, data_reserved, block_start,
-                                            blocksize);
-       btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize);
+                                            blocksize, true);
+       btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize, (ret != 0));
        unlock_page(page);
        put_page(page);
 out:
@@ -5127,7 +5121,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)
                inode_dio_wait(inode);
                btrfs_inode_resume_unlocked_dio(BTRFS_I(inode));
 
-               ret = btrfs_truncate(inode);
+               ret = btrfs_truncate(inode, newsize == oldsize);
                if (ret && inode->i_nlink) {
                        int err;
 
@@ -5463,7 +5457,8 @@ no_delete:
 
 /*
  * this returns the key found in the dir entry in the location pointer.
- * If no dir entries were found, location->objectid is 0.
+ * If no dir entries were found, returns -ENOENT.
+ * If found a corrupted location in dir entry, returns -EUCLEAN.
  */
 static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
                               struct btrfs_key *location)
@@ -5481,27 +5476,27 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
 
        di = btrfs_lookup_dir_item(NULL, root, path, btrfs_ino(BTRFS_I(dir)),
                        name, namelen, 0);
-       if (IS_ERR(di))
+       if (!di) {
+               ret = -ENOENT;
+               goto out;
+       }
+       if (IS_ERR(di)) {
                ret = PTR_ERR(di);
-
-       if (IS_ERR_OR_NULL(di))
-               goto out_err;
+               goto out;
+       }
 
        btrfs_dir_item_key_to_cpu(path->nodes[0], di, location);
        if (location->type != BTRFS_INODE_ITEM_KEY &&
            location->type != BTRFS_ROOT_ITEM_KEY) {
+               ret = -EUCLEAN;
                btrfs_warn(root->fs_info,
 "%s gets something invalid in DIR_ITEM (name %s, directory ino %llu, location(%llu %u %llu))",
                           __func__, name, btrfs_ino(BTRFS_I(dir)),
                           location->objectid, location->type, location->offset);
-               goto out_err;
        }
 out:
        btrfs_free_path(path);
        return ret;
-out_err:
-       location->objectid = 0;
-       goto out;
 }
 
 /*
@@ -5804,9 +5799,6 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
        if (ret < 0)
                return ERR_PTR(ret);
 
-       if (location.objectid == 0)
-               return ERR_PTR(-ENOENT);
-
        if (location.type == BTRFS_INODE_ITEM_KEY) {
                inode = btrfs_iget(dir->i_sb, &location, root, NULL);
                return inode;
@@ -5921,11 +5913,13 @@ static int btrfs_filldir(void *addr, int entries, struct dir_context *ctx)
                struct dir_entry *entry = addr;
                char *name = (char *)(entry + 1);
 
-               ctx->pos = entry->offset;
-               if (!dir_emit(ctx, name, entry->name_len, entry->ino,
-                             entry->type))
+               ctx->pos = get_unaligned(&entry->offset);
+               if (!dir_emit(ctx, name, get_unaligned(&entry->name_len),
+                                        get_unaligned(&entry->ino),
+                                        get_unaligned(&entry->type)))
                        return 1;
-               addr += sizeof(struct dir_entry) + entry->name_len;
+               addr += sizeof(struct dir_entry) +
+                       get_unaligned(&entry->name_len);
                ctx->pos++;
        }
        return 0;
@@ -6015,14 +6009,15 @@ again:
                }
 
                entry = addr;
-               entry->name_len = name_len;
+               put_unaligned(name_len, &entry->name_len);
                name_ptr = (char *)(entry + 1);
                read_extent_buffer(leaf, name_ptr, (unsigned long)(di + 1),
                                   name_len);
-               entry->type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];
+               put_unaligned(btrfs_filetype_table[btrfs_dir_type(leaf, di)],
+                               &entry->type);
                btrfs_dir_item_key_to_cpu(leaf, di, &location);
-               entry->ino = location.objectid;
-               entry->offset = found_key.offset;
+               put_unaligned(location.objectid, &entry->ino);
+               put_unaligned(found_key.offset, &entry->offset);
                entries++;
                addr += sizeof(struct dir_entry) + name_len;
                total_len += sizeof(struct dir_entry) + name_len;
@@ -6140,19 +6135,20 @@ static int btrfs_update_time(struct inode *inode, struct timespec *now,
                             int flags)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
+       bool dirty = flags & ~S_VERSION;
 
        if (btrfs_root_readonly(root))
                return -EROFS;
 
        if (flags & S_VERSION)
-               inode_inc_iversion(inode);
+               dirty |= inode_maybe_inc_iversion(inode, dirty);
        if (flags & S_CTIME)
                inode->i_ctime = *now;
        if (flags & S_MTIME)
                inode->i_mtime = *now;
        if (flags & S_ATIME)
                inode->i_atime = *now;
-       return btrfs_dirty_inode(inode);
+       return dirty ? btrfs_dirty_inode(inode) : 0;
 }
 
 /*
@@ -7439,76 +7435,6 @@ out:
        return ret;
 }
 
-bool btrfs_page_exists_in_range(struct inode *inode, loff_t start, loff_t end)
-{
-       struct radix_tree_root *root = &inode->i_mapping->page_tree;
-       bool found = false;
-       void **pagep = NULL;
-       struct page *page = NULL;
-       unsigned long start_idx;
-       unsigned long end_idx;
-
-       start_idx = start >> PAGE_SHIFT;
-
-       /*
-        * end is the last byte in the last page.  end == start is legal
-        */
-       end_idx = end >> PAGE_SHIFT;
-
-       rcu_read_lock();
-
-       /* Most of the code in this while loop is lifted from
-        * find_get_page.  It's been modified to begin searching from a
-        * page and return just the first page found in that range.  If the
-        * found idx is less than or equal to the end idx then we know that
-        * a page exists.  If no pages are found or if those pages are
-        * outside of the range then we're fine (yay!) */
-       while (page == NULL &&
-              radix_tree_gang_lookup_slot(root, &pagep, NULL, start_idx, 1)) {
-               page = radix_tree_deref_slot(pagep);
-               if (unlikely(!page))
-                       break;
-
-               if (radix_tree_exception(page)) {
-                       if (radix_tree_deref_retry(page)) {
-                               page = NULL;
-                               continue;
-                       }
-                       /*
-                        * Otherwise, shmem/tmpfs must be storing a swap entry
-                        * here as an exceptional entry: so return it without
-                        * attempting to raise page count.
-                        */
-                       page = NULL;
-                       break; /* TODO: Is this relevant for this use case? */
-               }
-
-               if (!page_cache_get_speculative(page)) {
-                       page = NULL;
-                       continue;
-               }
-
-               /*
-                * Has the page moved?
-                * This is part of the lockless pagecache protocol. See
-                * include/linux/pagemap.h for details.
-                */
-               if (unlikely(page != *pagep)) {
-                       put_page(page);
-                       page = NULL;
-               }
-       }
-
-       if (page) {
-               if (page->index <= end_idx)
-                       found = true;
-               put_page(page);
-       }
-
-       rcu_read_unlock();
-       return found;
-}
-
 static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
                              struct extent_state **cached_state, int writing)
 {
@@ -7534,8 +7460,8 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
                 * get stale data.
                 */
                if (!ordered &&
-                   (!writing ||
-                    !btrfs_page_exists_in_range(inode, lockstart, lockend)))
+                   (!writing || !filemap_range_has_page(inode->i_mapping,
+                                                        lockstart, lockend)))
                        break;
 
                unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend,
@@ -7910,6 +7836,7 @@ static blk_status_t dio_read_error(struct inode *inode, struct bio *failed_bio,
        int segs;
        int ret;
        blk_status_t status;
+       struct bio_vec bvec;
 
        BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE);
 
@@ -7925,8 +7852,9 @@ static blk_status_t dio_read_error(struct inode *inode, struct bio *failed_bio,
        }
 
        segs = bio_segments(failed_bio);
+       bio_get_first_bvec(failed_bio, &bvec);
        if (segs > 1 ||
-           (failed_bio->bi_io_vec->bv_len > btrfs_inode_sectorsize(inode)))
+           (bvec.bv_len > btrfs_inode_sectorsize(inode)))
                read_mode |= REQ_FAILFAST_DEV;
 
        isector = start - btrfs_io_bio(failed_bio)->logical;
@@ -7969,7 +7897,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
        ASSERT(bio->bi_vcnt == 1);
        io_tree = &BTRFS_I(inode)->io_tree;
        failure_tree = &BTRFS_I(inode)->io_failure_tree;
-       ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(inode));
+       ASSERT(bio_first_bvec_all(bio)->bv_len == btrfs_inode_sectorsize(inode));
 
        done->uptodate = 1;
        ASSERT(!bio_flagged(bio, BIO_CLONED));
@@ -8059,7 +7987,7 @@ static void btrfs_retry_endio(struct bio *bio)
        uptodate = 1;
 
        ASSERT(bio->bi_vcnt == 1);
-       ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(done->inode));
+       ASSERT(bio_first_bvec_all(bio)->bv_len == btrfs_inode_sectorsize(done->inode));
 
        io_tree = &BTRFS_I(inode)->io_tree;
        failure_tree = &BTRFS_I(inode)->io_failure_tree;
@@ -8264,9 +8192,8 @@ static void btrfs_endio_direct_write(struct bio *bio)
        bio_put(bio);
 }
 
-static blk_status_t __btrfs_submit_bio_start_direct_io(void *private_data,
-                                   struct bio *bio, int mirror_num,
-                                   unsigned long bio_flags, u64 offset)
+static blk_status_t btrfs_submit_bio_start_direct_io(void *private_data,
+                                   struct bio *bio, u64 offset)
 {
        struct inode *inode = private_data;
        blk_status_t ret;
@@ -8292,13 +8219,13 @@ static void btrfs_end_dio_bio(struct bio *bio)
                err = dip->subio_endio(dip->inode, btrfs_io_bio(bio), err);
 
        if (err) {
-               dip->errors = 1;
-
                /*
-                * before atomic variable goto zero, we must make sure
-                * dip->errors is perceived to be set.
+                * We want to perceive the errors flag being set before
+                * decrementing the reference count. We don't need a barrier
+                * since atomic operations with a return value are fully
+                * ordered as per atomic_t.txt
                 */
-               smp_mb__before_atomic();
+               dip->errors = 1;
        }
 
        /* if there are more bios still pending for this dio, just exit */
@@ -8346,9 +8273,8 @@ static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode,
        return 0;
 }
 
-static inline blk_status_t
-__btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, u64 file_offset,
-                      int async_submit)
+static inline blk_status_t btrfs_submit_dio_bio(struct bio *bio,
+               struct inode *inode, u64 file_offset, int async_submit)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_dio_private *dip = bio->bi_private;
@@ -8371,8 +8297,8 @@ __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, u64 file_offset,
        if (write && async_submit) {
                ret = btrfs_wq_submit_bio(fs_info, bio, 0, 0,
                                          file_offset, inode,
-                                         __btrfs_submit_bio_start_direct_io,
-                                         __btrfs_submit_bio_done);
+                                         btrfs_submit_bio_start_direct_io,
+                                         btrfs_submit_bio_done);
                goto err;
        } else if (write) {
                /*
@@ -8458,7 +8384,7 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip)
                 */
                atomic_inc(&dip->pending_bios);
 
-               status = __btrfs_submit_dio_bio(bio, inode, file_offset,
+               status = btrfs_submit_dio_bio(bio, inode, file_offset,
                                                async_submit);
                if (status) {
                        bio_put(bio);
@@ -8478,7 +8404,7 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip)
        } while (submit_len > 0);
 
 submit:
-       status = __btrfs_submit_dio_bio(bio, inode, file_offset, async_submit);
+       status = btrfs_submit_dio_bio(bio, inode, file_offset, async_submit);
        if (!status)
                return 0;
 
@@ -8486,10 +8412,11 @@ submit:
 out_err:
        dip->errors = 1;
        /*
-        * before atomic variable goto zero, we must
-        * make sure dip->errors is perceived to be set.
+        * Before atomic variable goto zero, we must  make sure dip->errors is
+        * perceived to be set. This ordering is ensured by the fact that an
+        * atomic operations with a return value are fully ordered as per
+        * atomic_t.txt
         */
-       smp_mb__before_atomic();
        if (atomic_dec_and_test(&dip->pending_bios))
                bio_io_error(dip->orig_bio);
 
@@ -8707,7 +8634,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
                if (ret < 0 && ret != -EIOCBQUEUED) {
                        if (dio_data.reserve)
                                btrfs_delalloc_release_space(inode, data_reserved,
-                                       offset, dio_data.reserve);
+                                       offset, dio_data.reserve, true);
                        /*
                         * On error we might have left some ordered extents
                         * without submitting corresponding bios for them, so
@@ -8723,8 +8650,8 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
                                        false);
                } else if (ret >= 0 && (size_t)ret < count)
                        btrfs_delalloc_release_space(inode, data_reserved,
-                                       offset, count - (size_t)ret);
-               btrfs_delalloc_release_extents(BTRFS_I(inode), count);
+                                       offset, count - (size_t)ret, true);
+               btrfs_delalloc_release_extents(BTRFS_I(inode), count, false);
        }
 out:
        if (wakeup)
@@ -9039,7 +8966,8 @@ again:
                if (reserved_space < PAGE_SIZE) {
                        end = page_start + reserved_space - 1;
                        btrfs_delalloc_release_space(inode, data_reserved,
-                                       page_start, PAGE_SIZE - reserved_space);
+                                       page_start, PAGE_SIZE - reserved_space,
+                                       true);
                }
        }
 
@@ -9089,23 +9017,23 @@ again:
 
 out_unlock:
        if (!ret) {
-               btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+               btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, true);
                sb_end_pagefault(inode->i_sb);
                extent_changeset_free(data_reserved);
                return VM_FAULT_LOCKED;
        }
        unlock_page(page);
 out:
-       btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+       btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, (ret != 0));
        btrfs_delalloc_release_space(inode, data_reserved, page_start,
-                                    reserved_space);
+                                    reserved_space, (ret != 0));
 out_noreserve:
        sb_end_pagefault(inode->i_sb);
        extent_changeset_free(data_reserved);
        return ret;
 }
 
-static int btrfs_truncate(struct inode *inode)
+static int btrfs_truncate(struct inode *inode, bool skip_writeback)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -9116,10 +9044,12 @@ static int btrfs_truncate(struct inode *inode)
        u64 mask = fs_info->sectorsize - 1;
        u64 min_size = btrfs_calc_trunc_metadata_size(fs_info, 1);
 
-       ret = btrfs_wait_ordered_range(inode, inode->i_size & (~mask),
-                                      (u64)-1);
-       if (ret)
-               return ret;
+       if (!skip_writeback) {
+               ret = btrfs_wait_ordered_range(inode, inode->i_size & (~mask),
+                                              (u64)-1);
+               if (ret)
+                       return ret;
+       }
 
        /*
         * Yes ladies and gentlemen, this is indeed ugly.  The fact is we have
@@ -9329,7 +9259,6 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
        ei->dir_index = 0;
        ei->last_unlink_trans = 0;
        ei->last_log_commit = 0;
-       ei->delayed_iput_count = 0;
 
        spin_lock_init(&ei->lock);
        ei->outstanding_extents = 0;
@@ -9449,7 +9378,7 @@ static void init_once(void *foo)
        inode_init_once(&ei->vfs_inode);
 }
 
-void btrfs_destroy_cachep(void)
+void __cold btrfs_destroy_cachep(void)
 {
        /*
         * Make sure all delayed rcu free inodes are flushed before we