Merge tag 'for-4.19-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
[muen/linux.git] / fs / btrfs / inode.c
index def3ada0f0b8e575723908a3f1e311c217499c10..9357a19d2bff2c76de1b29d2e221333b6f76da7e 100644 (file)
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/backing-dev.h>
-#include <linux/mpage.h>
-#include <linux/swap.h>
 #include <linux/writeback.h>
 #include <linux/compat.h>
-#include <linux/bit_spinlock.h>
 #include <linux/xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/falloc.h>
 #include <linux/slab.h>
 #include <linux/ratelimit.h>
-#include <linux/mount.h>
 #include <linux/btrfs.h>
 #include <linux/blkdev.h>
 #include <linux/posix_acl_xattr.h>
@@ -1443,8 +1439,7 @@ next_slot:
                        nocow = 1;
                } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
                        extent_end = found_key.offset +
-                               btrfs_file_extent_inline_len(leaf,
-                                                    path->slots[0], fi);
+                               btrfs_file_extent_ram_bytes(leaf, fi);
                        extent_end = ALIGN(extent_end,
                                           fs_info->sectorsize);
                } else {
@@ -1752,7 +1747,7 @@ static void btrfs_add_delalloc_inodes(struct btrfs_root *root,
 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);
+       struct btrfs_fs_info *fs_info = root->fs_info;
 
        if (!list_empty(&inode->delalloc_inodes)) {
                list_del_init(&inode->delalloc_inodes);
@@ -1903,8 +1898,8 @@ static void btrfs_clear_bit_hook(void *private_data,
 }
 
 /*
- * extent_io.c merge_bio_hook, this must check the chunk tree to make sure
- * we don't create bios that span stripes or chunks
+ * Merge bio hook, this must check the chunk tree to make sure we don't create
+ * bios that span stripes or chunks
  *
  * return 1 if page cannot be merged to bio
  * return 0 if page can be merged to bio
@@ -1962,7 +1957,7 @@ 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,
+blk_status_t btrfs_submit_bio_done(void *private_data, struct bio *bio,
                          int mirror_num)
 {
        struct inode *inode = private_data;
@@ -2035,8 +2030,7 @@ 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);
                goto out;
        } else if (!skip_sum) {
                ret = btrfs_csum_one_bio(inode, bio, 0, 0);
@@ -3610,18 +3604,15 @@ static int btrfs_read_locked_inode(struct inode *inode)
                filled = true;
 
        path = btrfs_alloc_path();
-       if (!path) {
-               ret = -ENOMEM;
-               goto make_bad;
-       }
+       if (!path)
+               return -ENOMEM;
 
        memcpy(&location, &BTRFS_I(inode)->location, sizeof(location));
 
        ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
        if (ret) {
-               if (ret > 0)
-                       ret = -ENOENT;
-               goto make_bad;
+               btrfs_free_path(path);
+               return ret;
        }
 
        leaf = path->nodes[0];
@@ -3774,11 +3765,6 @@ cache_acl:
 
        btrfs_sync_inode_flags_to_i_flags(inode);
        return 0;
-
-make_bad:
-       btrfs_free_path(path);
-       make_bad_inode(inode);
-       return ret;
 }
 
 /*
@@ -3984,7 +3970,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
                goto err;
        }
 skip_backref:
-       ret = btrfs_delete_delayed_dir_index(trans, fs_info, dir, index);
+       ret = btrfs_delete_delayed_dir_index(trans, dir, index);
        if (ret) {
                btrfs_abort_transaction(trans, ret);
                goto err;
@@ -4087,11 +4073,10 @@ out:
 }
 
 static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
-                       struct btrfs_root *root,
-                       struct inode *dir, u64 objectid,
-                       const char *name, int name_len)
+                              struct inode *dir, u64 objectid,
+                              const char *name, int name_len)
 {
-       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct btrfs_root *root = BTRFS_I(dir)->root;
        struct btrfs_path *path;
        struct extent_buffer *leaf;
        struct btrfs_dir_item *di;
@@ -4124,9 +4109,8 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
        }
        btrfs_release_path(path);
 
-       ret = btrfs_del_root_ref(trans, fs_info, objectid,
-                                root->root_key.objectid, dir_ino,
-                                &index, name, name_len);
+       ret = btrfs_del_root_ref(trans, objectid, root->root_key.objectid,
+                                dir_ino, &index, name, name_len);
        if (ret < 0) {
                if (ret != -ENOENT) {
                        btrfs_abort_transaction(trans, ret);
@@ -4145,12 +4129,11 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
 
                leaf = path->nodes[0];
                btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
-               btrfs_release_path(path);
                index = key.offset;
        }
        btrfs_release_path(path);
 
-       ret = btrfs_delete_delayed_dir_index(trans, fs_info, BTRFS_I(dir), index);
+       ret = btrfs_delete_delayed_dir_index(trans, BTRFS_I(dir), index);
        if (ret) {
                btrfs_abort_transaction(trans, ret);
                goto out;
@@ -4243,9 +4226,9 @@ again:
                prev = node;
                entry = rb_entry(node, struct btrfs_inode, rb_node);
 
-               if (objectid < btrfs_ino(BTRFS_I(&entry->vfs_inode)))
+               if (objectid < btrfs_ino(entry))
                        node = node->rb_left;
-               else if (objectid > btrfs_ino(BTRFS_I(&entry->vfs_inode)))
+               else if (objectid > btrfs_ino(entry))
                        node = node->rb_right;
                else
                        break;
@@ -4253,7 +4236,7 @@ again:
        if (!node) {
                while (prev) {
                        entry = rb_entry(prev, struct btrfs_inode, rb_node);
-                       if (objectid <= btrfs_ino(BTRFS_I(&entry->vfs_inode))) {
+                       if (objectid <= btrfs_ino(entry)) {
                                node = prev;
                                break;
                        }
@@ -4262,7 +4245,7 @@ again:
        }
        while (node) {
                entry = rb_entry(node, struct btrfs_inode, rb_node);
-               objectid = btrfs_ino(BTRFS_I(&entry->vfs_inode)) + 1;
+               objectid = btrfs_ino(entry) + 1;
                inode = igrab(&entry->vfs_inode);
                if (inode) {
                        spin_unlock(&root->inode_lock);
@@ -4343,10 +4326,8 @@ int btrfs_delete_subvolume(struct inode *dir, struct dentry *dentry)
 
        btrfs_record_snapshot_destroy(trans, BTRFS_I(dir));
 
-       ret = btrfs_unlink_subvol(trans, root, dir,
-                               dest->root_key.objectid,
-                               dentry->d_name.name,
-                               dentry->d_name.len);
+       ret = btrfs_unlink_subvol(trans, dir, dest->root_key.objectid,
+                                 dentry->d_name.name, dentry->d_name.len);
        if (ret) {
                err = ret;
                btrfs_abort_transaction(trans, ret);
@@ -4441,7 +4422,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
                return PTR_ERR(trans);
 
        if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {
-               err = btrfs_unlink_subvol(trans, root, dir,
+               err = btrfs_unlink_subvol(trans, dir,
                                          BTRFS_I(inode)->location.objectid,
                                          dentry->d_name.name,
                                          dentry->d_name.len);
@@ -4643,8 +4624,8 @@ search_again:
                                        BTRFS_I(inode), leaf, fi,
                                        found_key.offset);
                        } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
-                               item_end += btrfs_file_extent_inline_len(leaf,
-                                                        path->slots[0], fi);
+                               item_end += btrfs_file_extent_ram_bytes(leaf,
+                                                                       fi);
 
                                trace_btrfs_truncate_show_fi_inline(
                                        BTRFS_I(inode), leaf, fi, path->slots[0],
@@ -5615,9 +5596,9 @@ static void inode_tree_add(struct inode *inode)
                parent = *p;
                entry = rb_entry(parent, struct btrfs_inode, rb_node);
 
-               if (ino < btrfs_ino(BTRFS_I(&entry->vfs_inode)))
+               if (ino < btrfs_ino(entry))
                        p = &parent->rb_left;
-               else if (ino > btrfs_ino(BTRFS_I(&entry->vfs_inode)))
+               else if (ino > btrfs_ino(entry))
                        p = &parent->rb_right;
                else {
                        WARN_ON(!(entry->vfs_inode.i_state &
@@ -5708,16 +5689,21 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
                int ret;
 
                ret = btrfs_read_locked_inode(inode);
-               if (!is_bad_inode(inode)) {
+               if (!ret) {
                        inode_tree_add(inode);
                        unlock_new_inode(inode);
                        if (new)
                                *new = 1;
                } else {
-                       unlock_new_inode(inode);
-                       iput(inode);
-                       ASSERT(ret < 0);
-                       inode = ERR_PTR(ret < 0 ? ret : -ESTALE);
+                       iget_failed(inode);
+                       /*
+                        * ret > 0 can come from btrfs_search_slot called by
+                        * btrfs_read_locked_inode, this means the inode item
+                        * was not found.
+                        */
+                       if (ret > 0)
+                               ret = -ENOENT;
+                       inode = ERR_PTR(ret);
                }
        }
 
@@ -5745,7 +5731,7 @@ static struct inode *new_simple_dir(struct super_block *s,
        inode->i_mtime = current_time(inode);
        inode->i_atime = inode->i_mtime;
        inode->i_ctime = inode->i_mtime;
-       BTRFS_I(inode)->i_otime = timespec64_to_timespec(inode->i_mtime);
+       BTRFS_I(inode)->i_otime = inode->i_mtime;
 
        return inode;
 }
@@ -6027,32 +6013,6 @@ err:
        return ret;
 }
 
-int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
-{
-       struct btrfs_root *root = BTRFS_I(inode)->root;
-       struct btrfs_trans_handle *trans;
-       int ret = 0;
-       bool nolock = false;
-
-       if (test_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags))
-               return 0;
-
-       if (btrfs_fs_closing(root->fs_info) &&
-                       btrfs_is_free_space_inode(BTRFS_I(inode)))
-               nolock = true;
-
-       if (wbc->sync_mode == WB_SYNC_ALL) {
-               if (nolock)
-                       trans = btrfs_join_transaction_nolock(root);
-               else
-                       trans = btrfs_join_transaction(root);
-               if (IS_ERR(trans))
-                       return PTR_ERR(trans);
-               ret = btrfs_commit_transaction(trans);
-       }
-       return ret;
-}
-
 /*
  * This is somewhat expensive, updating the tree every time the
  * inode changes.  But, it is most likely to find the inode in cache.
@@ -6351,7 +6311,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        inode->i_mtime = current_time(inode);
        inode->i_atime = inode->i_mtime;
        inode->i_ctime = inode->i_mtime;
-       BTRFS_I(inode)->i_otime = timespec64_to_timespec(inode->i_mtime);
+       BTRFS_I(inode)->i_otime = inode->i_mtime;
 
        inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
                                  struct btrfs_inode_item);
@@ -6420,7 +6380,6 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
                   struct btrfs_inode *parent_inode, struct btrfs_inode *inode,
                   const char *name, int name_len, int add_backref, u64 index)
 {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
        int ret = 0;
        struct btrfs_key key;
        struct btrfs_root *root = parent_inode->root;
@@ -6436,7 +6395,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
        }
 
        if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) {
-               ret = btrfs_add_root_ref(trans, fs_info, key.objectid,
+               ret = btrfs_add_root_ref(trans, key.objectid,
                                         root->root_key.objectid, parent_ino,
                                         index, name, name_len);
        } else if (add_backref) {
@@ -6472,7 +6431,7 @@ fail_dir_item:
        if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) {
                u64 local_index;
                int err;
-               err = btrfs_del_root_ref(trans, fs_info, key.objectid,
+               err = btrfs_del_root_ref(trans, key.objectid,
                                         root->root_key.objectid, parent_ino,
                                         &local_index, name, name_len);
 
@@ -6832,7 +6791,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
            size_t pg_offset, u64 start, u64 len,
                int create)
 {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
+       struct btrfs_fs_info *fs_info = inode->root->fs_info;
        int ret;
        int err = 0;
        u64 extent_start = 0;
@@ -6928,7 +6887,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
                                                       extent_start);
        } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
                size_t size;
-               size = btrfs_file_extent_inline_len(leaf, path->slots[0], item);
+
+               size = btrfs_file_extent_ram_bytes(leaf, item);
                extent_end = ALIGN(extent_start + size,
                                   fs_info->sectorsize);
 
@@ -6979,7 +6939,7 @@ next:
                if (new_inline)
                        goto out;
 
-               size = btrfs_file_extent_inline_len(leaf, path->slots[0], item);
+               size = btrfs_file_extent_ram_bytes(leaf, item);
                extent_offset = page_offset(page) + pg_offset - extent_start;
                copy_size = min_t(u64, PAGE_SIZE - pg_offset,
                                  size - extent_offset);
@@ -7850,7 +7810,7 @@ static blk_status_t dio_read_error(struct inode *inode, struct bio *failed_bio,
        isector >>= inode->i_sb->s_blocksize_bits;
        bio = btrfs_create_repair_bio(inode, failed_bio, failrec, page,
                                pgoff, isector, repair_endio, repair_arg);
-       bio_set_op_attrs(bio, REQ_OP_READ, read_mode);
+       bio->bi_opf = REQ_OP_READ | read_mode;
 
        btrfs_debug(BTRFS_I(inode)->root->fs_info,
                    "repair DIO read error: submitting new dio read[%#x] to this_mirror=%d, in_validation=%d",
@@ -8284,8 +8244,7 @@ static inline blk_status_t btrfs_submit_dio_bio(struct bio *bio,
        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);
                goto err;
        } else if (write) {
                /*
@@ -9525,8 +9484,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
        /* src is a subvolume */
        if (old_ino == BTRFS_FIRST_FREE_OBJECTID) {
                root_objectid = BTRFS_I(old_inode)->root->root_key.objectid;
-               ret = btrfs_unlink_subvol(trans, root, old_dir,
-                                         root_objectid,
+               ret = btrfs_unlink_subvol(trans, old_dir, root_objectid,
                                          old_dentry->d_name.name,
                                          old_dentry->d_name.len);
        } else { /* src is an inode */
@@ -9545,8 +9503,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
        /* dest is a subvolume */
        if (new_ino == BTRFS_FIRST_FREE_OBJECTID) {
                root_objectid = BTRFS_I(new_inode)->root->root_key.objectid;
-               ret = btrfs_unlink_subvol(trans, dest, new_dir,
-                                         root_objectid,
+               ret = btrfs_unlink_subvol(trans, new_dir, root_objectid,
                                          new_dentry->d_name.name,
                                          new_dentry->d_name.len);
        } else { /* dest is an inode */
@@ -9806,7 +9763,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        if (unlikely(old_ino == BTRFS_FIRST_FREE_OBJECTID)) {
                root_objectid = BTRFS_I(old_inode)->root->root_key.objectid;
-               ret = btrfs_unlink_subvol(trans, root, old_dir, root_objectid,
+               ret = btrfs_unlink_subvol(trans, old_dir, root_objectid,
                                        old_dentry->d_name.name,
                                        old_dentry->d_name.len);
        } else {
@@ -9828,8 +9785,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                if (unlikely(btrfs_ino(BTRFS_I(new_inode)) ==
                             BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {
                        root_objectid = BTRFS_I(new_inode)->location.objectid;
-                       ret = btrfs_unlink_subvol(trans, dest, new_dir,
-                                               root_objectid,
+                       ret = btrfs_unlink_subvol(trans, new_dir, root_objectid,
                                                new_dentry->d_name.name,
                                                new_dentry->d_name.len);
                        BUG_ON(new_inode->i_nlink == 0);
@@ -10451,12 +10407,6 @@ static int btrfs_readpage_io_failed_hook(struct page *page, int failed_mirror)
        return -EAGAIN;
 }
 
-static struct btrfs_fs_info *iotree_fs_info(void *private_data)
-{
-       struct inode *inode = private_data;
-       return btrfs_sb(inode->i_sb);
-}
-
 static void btrfs_check_extent_io_range(void *private_data, const char *caller,
                                        u64 start, u64 end)
 {
@@ -10471,9 +10421,9 @@ static void btrfs_check_extent_io_range(void *private_data, const char *caller,
        }
 }
 
-void btrfs_set_range_writeback(void *private_data, u64 start, u64 end)
+void btrfs_set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end)
 {
-       struct inode *inode = private_data;
+       struct inode *inode = tree->private_data;
        unsigned long index = start >> PAGE_SHIFT;
        unsigned long end_index = end >> PAGE_SHIFT;
        struct page *page;
@@ -10529,10 +10479,7 @@ static const struct extent_io_ops btrfs_extent_io_ops = {
        /* mandatory callbacks */
        .submit_bio_hook = btrfs_submit_bio_hook,
        .readpage_end_io_hook = btrfs_readpage_end_io_hook,
-       .merge_bio_hook = btrfs_merge_bio_hook,
        .readpage_io_failed_hook = btrfs_readpage_io_failed_hook,
-       .tree_fs_info = iotree_fs_info,
-       .set_range_writeback = btrfs_set_range_writeback,
 
        /* optional callbacks */
        .fill_delalloc = run_delalloc_range,