Merge tag 'idmapped-mounts-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-rpi.git] / fs / btrfs / inode.c
index c0b11db..2e1c282 100644 (file)
@@ -50,6 +50,7 @@
 #include "delalloc-space.h"
 #include "block-group.h"
 #include "space-info.h"
+#include "zoned.h"
 
 struct btrfs_iget_args {
        u64 ino;
@@ -692,8 +693,7 @@ cont:
                                                     NULL,
                                                     clear_flags,
                                                     PAGE_UNLOCK |
-                                                    PAGE_CLEAR_DIRTY |
-                                                    PAGE_SET_WRITEBACK |
+                                                    PAGE_START_WRITEBACK |
                                                     page_error_op |
                                                     PAGE_END_WRITEBACK);
 
@@ -917,7 +917,6 @@ retry:
                                                ins.objectid,
                                                async_extent->ram_size,
                                                ins.offset,
-                                               BTRFS_ORDERED_COMPRESSED,
                                                async_extent->compress_type);
                if (ret) {
                        btrfs_drop_extent_cache(inode, async_extent->start,
@@ -934,8 +933,7 @@ retry:
                                async_extent->start +
                                async_extent->ram_size - 1,
                                NULL, EXTENT_LOCKED | EXTENT_DELALLOC,
-                               PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
-                               PAGE_SET_WRITEBACK);
+                               PAGE_UNLOCK | PAGE_START_WRITEBACK);
                if (btrfs_submit_compressed_write(inode, async_extent->start,
                                    async_extent->ram_size,
                                    ins.objectid,
@@ -971,9 +969,8 @@ out_free:
                                     NULL, EXTENT_LOCKED | EXTENT_DELALLOC |
                                     EXTENT_DELALLOC_NEW |
                                     EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING,
-                                    PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
-                                    PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK |
-                                    PAGE_SET_ERROR);
+                                    PAGE_UNLOCK | PAGE_START_WRITEBACK |
+                                    PAGE_END_WRITEBACK | PAGE_SET_ERROR);
        free_async_extent_pages(async_extent);
        kfree(async_extent);
        goto again;
@@ -1071,8 +1068,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
                                     EXTENT_LOCKED | EXTENT_DELALLOC |
                                     EXTENT_DELALLOC_NEW | EXTENT_DEFRAG |
                                     EXTENT_DO_ACCOUNTING, PAGE_UNLOCK |
-                                    PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK |
-                                    PAGE_END_WRITEBACK);
+                                    PAGE_START_WRITEBACK | PAGE_END_WRITEBACK);
                        *nr_written = *nr_written +
                             (end - start + PAGE_SIZE) / PAGE_SIZE;
                        *page_started = 1;
@@ -1127,7 +1123,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
                free_extent_map(em);
 
                ret = btrfs_add_ordered_extent(inode, start, ins.objectid,
-                                              ram_size, cur_alloc_size, 0);
+                                              ram_size, cur_alloc_size,
+                                              BTRFS_ORDERED_REGULAR);
                if (ret)
                        goto out_drop_extent_cache;
 
@@ -1194,8 +1191,7 @@ out_reserve:
 out_unlock:
        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;
+       page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
        /*
         * If we reserved an extent for our delalloc range (or a subrange) and
         * failed to create the respective ordered extent, then it means that
@@ -1320,9 +1316,8 @@ static int cow_file_range_async(struct btrfs_inode *inode,
                unsigned clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC |
                        EXTENT_DELALLOC_NEW | EXTENT_DEFRAG |
                        EXTENT_DO_ACCOUNTING;
-               unsigned long page_ops = PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
-                       PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK |
-                       PAGE_SET_ERROR;
+               unsigned long page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK |
+                                        PAGE_END_WRITEBACK | PAGE_SET_ERROR;
 
                extent_clear_unlock_delalloc(inode, start, end, locked_page,
                                             clear_bits, page_ops);
@@ -1399,6 +1394,29 @@ static int cow_file_range_async(struct btrfs_inode *inode,
        return 0;
 }
 
+static noinline int run_delalloc_zoned(struct btrfs_inode *inode,
+                                      struct page *locked_page, u64 start,
+                                      u64 end, int *page_started,
+                                      unsigned long *nr_written)
+{
+       int ret;
+
+       ret = cow_file_range(inode, locked_page, start, end, page_started,
+                            nr_written, 0);
+       if (ret)
+               return ret;
+
+       if (*page_started)
+               return 0;
+
+       __set_page_dirty_nobuffers(locked_page);
+       account_page_redirty(locked_page);
+       extent_write_locked_range(&inode->vfs_inode, start, end, WB_SYNC_ALL);
+       *page_started = 1;
+
+       return 0;
+}
+
 static noinline int csum_exist_in_range(struct btrfs_fs_info *fs_info,
                                        u64 bytenr, u64 num_bytes)
 {
@@ -1519,8 +1537,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
                                             EXTENT_LOCKED | EXTENT_DELALLOC |
                                             EXTENT_DO_ACCOUNTING |
                                             EXTENT_DEFRAG, PAGE_UNLOCK |
-                                            PAGE_CLEAR_DIRTY |
-                                            PAGE_SET_WRITEBACK |
+                                            PAGE_START_WRITEBACK |
                                             PAGE_END_WRITEBACK);
                return -ENOMEM;
        }
@@ -1842,8 +1859,7 @@ error:
                                             locked_page, EXTENT_LOCKED |
                                             EXTENT_DELALLOC | EXTENT_DEFRAG |
                                             EXTENT_DO_ACCOUNTING, PAGE_UNLOCK |
-                                            PAGE_CLEAR_DIRTY |
-                                            PAGE_SET_WRITEBACK |
+                                            PAGE_START_WRITEBACK |
                                             PAGE_END_WRITEBACK);
        btrfs_free_path(path);
        return ret;
@@ -1878,17 +1894,24 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page
 {
        int ret;
        int force_cow = need_force_cow(inode, start, end);
+       const bool zoned = btrfs_is_zoned(inode->root->fs_info);
 
        if (inode->flags & BTRFS_INODE_NODATACOW && !force_cow) {
+               ASSERT(!zoned);
                ret = run_delalloc_nocow(inode, locked_page, start, end,
                                         page_started, 1, nr_written);
        } else if (inode->flags & BTRFS_INODE_PREALLOC && !force_cow) {
+               ASSERT(!zoned);
                ret = run_delalloc_nocow(inode, locked_page, start, end,
                                         page_started, 0, nr_written);
        } else if (!inode_can_compress(inode) ||
                   !inode_need_compress(inode, start, end)) {
-               ret = cow_file_range(inode, locked_page, start, end,
-                                    page_started, nr_written, 1);
+               if (zoned)
+                       ret = run_delalloc_zoned(inode, locked_page, start, end,
+                                                page_started, nr_written);
+               else
+                       ret = cow_file_range(inode, locked_page, start, end,
+                                            page_started, nr_written, 1);
        } else {
                set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, &inode->runtime_flags);
                ret = cow_file_range_async(inode, wbc, locked_page, start, end,
@@ -2183,9 +2206,10 @@ int btrfs_bio_fits_in_stripe(struct page *page, size_t size, struct bio *bio,
        struct inode *inode = page->mapping->host;
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        u64 logical = bio->bi_iter.bi_sector << 9;
+       struct extent_map *em;
        u64 length = 0;
        u64 map_length;
-       int ret;
+       int ret = 0;
        struct btrfs_io_geometry geom;
 
        if (bio_flags & EXTENT_BIO_COMPRESSED)
@@ -2193,14 +2217,19 @@ int btrfs_bio_fits_in_stripe(struct page *page, size_t size, struct bio *bio,
 
        length = bio->bi_iter.bi_size;
        map_length = length;
-       ret = btrfs_get_io_geometry(fs_info, btrfs_op(bio), logical, map_length,
-                                   &geom);
+       em = btrfs_get_chunk_map(fs_info, logical, map_length);
+       if (IS_ERR(em))
+               return PTR_ERR(em);
+       ret = btrfs_get_io_geometry(fs_info, em, btrfs_op(bio), logical,
+                                   map_length, &geom);
        if (ret < 0)
-               return ret;
+               goto out;
 
        if (geom.len < length + size)
-               return 1;
-       return 0;
+               ret = 1;
+out:
+       free_extent_map(em);
+       return ret;
 }
 
 /*
@@ -2217,6 +2246,119 @@ static blk_status_t btrfs_submit_bio_start(struct inode *inode, struct bio *bio,
        return btrfs_csum_one_bio(BTRFS_I(inode), bio, 0, 0);
 }
 
+bool btrfs_bio_fits_in_ordered_extent(struct page *page, struct bio *bio,
+                                     unsigned int size)
+{
+       struct btrfs_inode *inode = BTRFS_I(page->mapping->host);
+       struct btrfs_fs_info *fs_info = inode->root->fs_info;
+       struct btrfs_ordered_extent *ordered;
+       u64 len = bio->bi_iter.bi_size + size;
+       bool ret = true;
+
+       ASSERT(btrfs_is_zoned(fs_info));
+       ASSERT(fs_info->max_zone_append_size > 0);
+       ASSERT(bio_op(bio) == REQ_OP_ZONE_APPEND);
+
+       /* Ordered extent not yet created, so we're good */
+       ordered = btrfs_lookup_ordered_extent(inode, page_offset(page));
+       if (!ordered)
+               return ret;
+
+       if ((bio->bi_iter.bi_sector << SECTOR_SHIFT) + len >
+           ordered->disk_bytenr + ordered->disk_num_bytes)
+               ret = false;
+
+       btrfs_put_ordered_extent(ordered);
+
+       return ret;
+}
+
+static blk_status_t extract_ordered_extent(struct btrfs_inode *inode,
+                                          struct bio *bio, loff_t file_offset)
+{
+       struct btrfs_ordered_extent *ordered;
+       struct extent_map *em = NULL, *em_new = NULL;
+       struct extent_map_tree *em_tree = &inode->extent_tree;
+       u64 start = (u64)bio->bi_iter.bi_sector << SECTOR_SHIFT;
+       u64 len = bio->bi_iter.bi_size;
+       u64 end = start + len;
+       u64 ordered_end;
+       u64 pre, post;
+       int ret = 0;
+
+       ordered = btrfs_lookup_ordered_extent(inode, file_offset);
+       if (WARN_ON_ONCE(!ordered))
+               return BLK_STS_IOERR;
+
+       /* No need to split */
+       if (ordered->disk_num_bytes == len)
+               goto out;
+
+       /* We cannot split once end_bio'd ordered extent */
+       if (WARN_ON_ONCE(ordered->bytes_left != ordered->disk_num_bytes)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* We cannot split a compressed ordered extent */
+       if (WARN_ON_ONCE(ordered->disk_num_bytes != ordered->num_bytes)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ordered_end = ordered->disk_bytenr + ordered->disk_num_bytes;
+       /* bio must be in one ordered extent */
+       if (WARN_ON_ONCE(start < ordered->disk_bytenr || end > ordered_end)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* Checksum list should be empty */
+       if (WARN_ON_ONCE(!list_empty(&ordered->list))) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pre = start - ordered->disk_bytenr;
+       post = ordered_end - end;
+
+       ret = btrfs_split_ordered_extent(ordered, pre, post);
+       if (ret)
+               goto out;
+
+       read_lock(&em_tree->lock);
+       em = lookup_extent_mapping(em_tree, ordered->file_offset, len);
+       if (!em) {
+               read_unlock(&em_tree->lock);
+               ret = -EIO;
+               goto out;
+       }
+       read_unlock(&em_tree->lock);
+
+       ASSERT(!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags));
+       /*
+        * We cannot reuse em_new here but have to create a new one, as
+        * unpin_extent_cache() expects the start of the extent map to be the
+        * logical offset of the file, which does not hold true anymore after
+        * splitting.
+        */
+       em_new = create_io_em(inode, em->start + pre, len,
+                             em->start + pre, em->block_start + pre, len,
+                             len, len, BTRFS_COMPRESS_NONE,
+                             BTRFS_ORDERED_REGULAR);
+       if (IS_ERR(em_new)) {
+               ret = PTR_ERR(em_new);
+               goto out;
+       }
+       free_extent_map(em_new);
+
+out:
+       free_extent_map(em);
+       btrfs_put_ordered_extent(ordered);
+
+       return errno_to_blk_status(ret);
+}
+
 /*
  * extent_io.c submission hook. This does the right thing for csum calculation
  * on write, or reading the csums from the tree before a read.
@@ -2252,7 +2394,16 @@ blk_status_t btrfs_submit_data_bio(struct inode *inode, struct bio *bio,
        if (btrfs_is_free_space_inode(BTRFS_I(inode)))
                metadata = BTRFS_WQ_ENDIO_FREE_SPACE;
 
-       if (bio_op(bio) != REQ_OP_WRITE) {
+       if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
+               struct page *page = bio_first_bvec_all(bio)->bv_page;
+               loff_t file_offset = page_offset(page);
+
+               ret = extract_ordered_extent(BTRFS_I(inode), bio, file_offset);
+               if (ret)
+                       goto out;
+       }
+
+       if (btrfs_op(bio) != BTRFS_MAP_WRITE) {
                ret = btrfs_bio_wq_end_io(fs_info, bio, metadata);
                if (ret)
                        goto out;
@@ -2754,6 +2905,9 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
                goto out;
        }
 
+       if (ordered_extent->disk)
+               btrfs_rewrite_logical_zoned(ordered_extent);
+
        btrfs_free_io_failure_record(inode, start, end);
 
        if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered_extent->flags)) {
@@ -3103,14 +3257,16 @@ void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info)
 }
 
 /**
- * btrfs_wait_on_delayed_iputs - wait on the delayed iputs to be done running
- * @fs_info - the fs_info for this fs
- * @return - EINTR if we were killed, 0 if nothing's pending
+ * Wait for flushing all delayed iputs
+ *
+ * @fs_info:  the filesystem
  *
  * This will wait on any delayed iputs that are currently running with KILLABLE
  * set.  Once they are all done running we will return, unless we are killed in
  * which case we return EINTR. This helps in user operations like fallocate etc
  * that might get blocked on the iputs.
+ *
+ * Return EINTR if we were killed, 0 if nothing's pending
  */
 int btrfs_wait_on_delayed_iputs(struct btrfs_fs_info *fs_info)
 {
@@ -4720,6 +4876,9 @@ again:
                ret = -ENOMEM;
                goto out;
        }
+       ret = set_page_extent_mapped(page);
+       if (ret < 0)
+               goto out_unlock;
 
        if (!PageUptodate(page)) {
                ret = btrfs_readpage(NULL, page);
@@ -4737,7 +4896,6 @@ again:
        wait_on_page_writeback(page);
 
        lock_extent_bits(io_tree, block_start, block_end, &cached_state);
-       set_page_extent_mapped(page);
 
        ordered = btrfs_lookup_ordered_extent(inode, block_start);
        if (ordered) {
@@ -5011,6 +5169,15 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)
                btrfs_drew_write_unlock(&root->snapshot_lock);
                btrfs_end_transaction(trans);
        } else {
+               struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+
+               if (btrfs_is_zoned(fs_info)) {
+                       ret = btrfs_wait_ordered_range(inode,
+                                       ALIGN(newsize, fs_info->sectorsize),
+                                       (u64)-1);
+                       if (ret)
+                               return ret;
+               }
 
                /*
                 * We're truncating a file that used to have good data down to
@@ -6373,7 +6540,7 @@ static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       err = btrfs_find_free_objectid(root, &objectid);
+       err = btrfs_get_free_objectid(root, &objectid);
        if (err)
                goto out_unlock;
 
@@ -6437,7 +6604,7 @@ static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       err = btrfs_find_free_objectid(root, &objectid);
+       err = btrfs_get_free_objectid(root, &objectid);
        if (err)
                goto out_unlock;
 
@@ -6582,7 +6749,7 @@ static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       err = btrfs_find_free_objectid(root, &objectid);
+       err = btrfs_get_free_objectid(root, &objectid);
        if (err)
                goto out_fail;
 
@@ -7106,9 +7273,6 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
  * @strict:    if true, omit optimizations that might force us into unnecessary
  *             cow. e.g., don't trust generation number.
  *
- * This function will flush ordered extents in the range to ensure proper
- * nocow checks for (nowait == false) case.
- *
  * Return:
  * >0  and update @len if we can do nocow write
  *  0  if we can't do nocow write
@@ -7616,6 +7780,9 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
        iomap->bdev = fs_info->fs_devices->latest_bdev;
        iomap->length = len;
 
+       if (write && btrfs_use_zone_append(BTRFS_I(inode), em))
+               iomap->flags |= IOMAP_F_ZONE_APPEND;
+
        free_extent_map(em);
 
        return 0;
@@ -7685,7 +7852,7 @@ static void btrfs_dio_private_put(struct btrfs_dio_private *dip)
        if (!refcount_dec_and_test(&dip->refs))
                return;
 
-       if (bio_op(dip->dio_bio) == REQ_OP_WRITE) {
+       if (btrfs_op(dip->dio_bio) == BTRFS_MAP_WRITE) {
                __endio_write_update_ordered(BTRFS_I(dip->inode),
                                             dip->logical_offset,
                                             dip->bytes,
@@ -7800,10 +7967,8 @@ static void __endio_write_update_ordered(struct btrfs_inode *inode,
                                        NULL);
                        btrfs_queue_work(wq, &ordered->work);
                }
-               /*
-                * If btrfs_dec_test_ordered_pending does not find any ordered
-                * extent in the range, we can exit.
-                */
+
+               /* No ordered extent found in the range, exit */
                if (ordered_offset == last_offset)
                        return;
                /*
@@ -7844,6 +8009,8 @@ static void btrfs_end_dio_bio(struct bio *bio)
        if (err)
                dip->dio_bio->bi_status = err;
 
+       btrfs_record_physical_zoned(dip->inode, dip->logical_offset, bio);
+
        bio_put(bio);
        btrfs_dio_private_put(dip);
 }
@@ -7853,7 +8020,7 @@ static inline blk_status_t btrfs_submit_dio_bio(struct bio *bio,
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_dio_private *dip = bio->bi_private;
-       bool write = bio_op(bio) == REQ_OP_WRITE;
+       bool write = btrfs_op(bio) == BTRFS_MAP_WRITE;
        blk_status_t ret;
 
        /* Check btrfs_submit_bio_hook() for rules about async submit. */
@@ -7903,7 +8070,7 @@ static struct btrfs_dio_private *btrfs_create_dio_private(struct bio *dio_bio,
                                                          struct inode *inode,
                                                          loff_t file_offset)
 {
-       const bool write = (bio_op(dio_bio) == REQ_OP_WRITE);
+       const bool write = (btrfs_op(dio_bio) == BTRFS_MAP_WRITE);
        const bool csum = !(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM);
        size_t dip_size;
        struct btrfs_dio_private *dip;
@@ -7933,7 +8100,7 @@ static struct btrfs_dio_private *btrfs_create_dio_private(struct bio *dio_bio,
 static blk_qc_t btrfs_submit_direct(struct inode *inode, struct iomap *iomap,
                struct bio *dio_bio, loff_t file_offset)
 {
-       const bool write = (bio_op(dio_bio) == REQ_OP_WRITE);
+       const bool write = (btrfs_op(dio_bio) == BTRFS_MAP_WRITE);
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        const bool raid56 = (btrfs_data_alloc_profile(fs_info) &
                             BTRFS_BLOCK_GROUP_RAID56_MASK);
@@ -7944,10 +8111,12 @@ static blk_qc_t btrfs_submit_direct(struct inode *inode, struct iomap *iomap,
        u64 submit_len;
        int clone_offset = 0;
        int clone_len;
+       u64 logical;
        int ret;
        blk_status_t status;
        struct btrfs_io_geometry geom;
        struct btrfs_dio_data *dio_data = iomap->private;
+       struct extent_map *em = NULL;
 
        dip = btrfs_create_dio_private(dio_bio, inode, file_offset);
        if (!dip) {
@@ -7976,12 +8145,18 @@ static blk_qc_t btrfs_submit_direct(struct inode *inode, struct iomap *iomap,
        submit_len = dio_bio->bi_iter.bi_size;
 
        do {
-               ret = btrfs_get_io_geometry(fs_info, btrfs_op(dio_bio),
-                                           start_sector << 9, submit_len,
-                                           &geom);
+               logical = start_sector << 9;
+               em = btrfs_get_chunk_map(fs_info, logical, submit_len);
+               if (IS_ERR(em)) {
+                       status = errno_to_blk_status(PTR_ERR(em));
+                       em = NULL;
+                       goto out_err_em;
+               }
+               ret = btrfs_get_io_geometry(fs_info, em, btrfs_op(dio_bio),
+                                           logical, submit_len, &geom);
                if (ret) {
                        status = errno_to_blk_status(ret);
-                       goto out_err;
+                       goto out_err_em;
                }
                ASSERT(geom.len <= INT_MAX);
 
@@ -7996,6 +8171,19 @@ static blk_qc_t btrfs_submit_direct(struct inode *inode, struct iomap *iomap,
                bio->bi_end_io = btrfs_end_dio_bio;
                btrfs_io_bio(bio)->logical = file_offset;
 
+               WARN_ON_ONCE(write && btrfs_is_zoned(fs_info) &&
+                            fs_info->max_zone_append_size &&
+                            bio_op(bio) != REQ_OP_ZONE_APPEND);
+
+               if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
+                       status = extract_ordered_extent(BTRFS_I(inode), bio,
+                                                       file_offset);
+                       if (status) {
+                               bio_put(bio);
+                               goto out_err;
+                       }
+               }
+
                ASSERT(submit_len >= clone_len);
                submit_len -= clone_len;
 
@@ -8026,19 +8214,24 @@ static blk_qc_t btrfs_submit_direct(struct inode *inode, struct iomap *iomap,
                        bio_put(bio);
                        if (submit_len > 0)
                                refcount_dec(&dip->refs);
-                       goto out_err;
+                       goto out_err_em;
                }
 
                dio_data->submitted += clone_len;
                clone_offset += clone_len;
                start_sector += clone_len >> 9;
                file_offset += clone_len;
+
+               free_extent_map(em);
        } while (submit_len > 0);
        return BLK_QC_T_NONE;
 
+out_err_em:
+       free_extent_map(em);
 out_err:
        dip->dio_bio->bi_status = status;
        btrfs_dio_private_put(dip);
+
        return BLK_QC_T_NONE;
 }
 
@@ -8120,7 +8313,7 @@ static int __btrfs_releasepage(struct page *page, gfp_t gfp_flags)
 {
        int ret = try_release_extent_mapping(page, gfp_flags);
        if (ret == 1)
-               detach_page_private(page);
+               clear_page_extent_mapped(page);
        return ret;
 }
 
@@ -8189,8 +8382,9 @@ static void btrfs_invalidatepage(struct page *page, unsigned int offset,
 
        if (!inode_evicting)
                lock_extent_bits(tree, page_start, page_end, &cached_state);
-again:
+
        start = page_start;
+again:
        ordered = btrfs_lookup_ordered_range(inode, start, page_end - start + 1);
        if (ordered) {
                found_ordered = true;
@@ -8279,7 +8473,7 @@ again:
        }
 
        ClearPageChecked(page);
-       detach_page_private(page);
+       clear_page_extent_mapped(page);
 }
 
 /*
@@ -8358,7 +8552,12 @@ again:
        wait_on_page_writeback(page);
 
        lock_extent_bits(io_tree, page_start, page_end, &cached_state);
-       set_page_extent_mapped(page);
+       ret2 = set_page_extent_mapped(page);
+       if (ret2 < 0) {
+               ret = vmf_error(ret2);
+               unlock_extent_cached(io_tree, page_start, page_end, &cached_state);
+               goto out_unlock;
+       }
 
        /*
         * we can't set the delalloc bits if there are pending ordered
@@ -8595,15 +8794,18 @@ out:
  */
 int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
                             struct btrfs_root *new_root,
-                            struct btrfs_root *parent_root,
-                            u64 new_dirid)
+                            struct btrfs_root *parent_root)
 {
        struct inode *inode;
        int err;
        u64 index = 0;
+       u64 ino;
+
+       err = btrfs_get_free_objectid(new_root, &ino);
+       if (err < 0)
+               return err;
 
-       inode = btrfs_new_inode(trans, new_root, NULL, "..", 2,
-                               new_dirid, new_dirid,
+       inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, ino, ino,
                                S_IFDIR | (~current_umask() & S_IRWXUGO),
                                &index);
        if (IS_ERR(inode))
@@ -9083,7 +9285,7 @@ static int btrfs_whiteout_for_rename(struct btrfs_trans_handle *trans,
        u64 objectid;
        u64 index;
 
-       ret = btrfs_find_free_objectid(root, &objectid);
+       ret = btrfs_get_free_objectid(root, &objectid);
        if (ret)
                return ret;
 
@@ -9490,11 +9692,11 @@ int btrfs_start_delalloc_snapshot(struct btrfs_root *root)
        return start_delalloc_inodes(root, &wbc, true, false);
 }
 
-int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr,
+int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, long nr,
                               bool in_reclaim_context)
 {
        struct writeback_control wbc = {
-               .nr_to_write = (nr == U64_MAX) ? LONG_MAX : (unsigned long)nr,
+               .nr_to_write = nr,
                .sync_mode = WB_SYNC_NONE,
                .range_start = 0,
                .range_end = LLONG_MAX,
@@ -9511,12 +9713,12 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr,
        mutex_lock(&fs_info->delalloc_root_mutex);
        spin_lock(&fs_info->delalloc_root_lock);
        list_splice_init(&fs_info->delalloc_roots, &splice);
-       while (!list_empty(&splice) && nr) {
+       while (!list_empty(&splice)) {
                /*
                 * Reset nr_to_write here so we know that we're doing a full
                 * flush.
                 */
-               if (nr == U64_MAX)
+               if (nr == LONG_MAX)
                        wbc.nr_to_write = LONG_MAX;
 
                root = list_first_entry(&splice, struct btrfs_root,
@@ -9579,7 +9781,7 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       err = btrfs_find_free_objectid(root, &objectid);
+       err = btrfs_get_free_objectid(root, &objectid);
        if (err)
                goto out_unlock;
 
@@ -9915,7 +10117,7 @@ static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
        if (IS_ERR(trans))
                return PTR_ERR(trans);
 
-       ret = btrfs_find_free_objectid(root, &objectid);
+       ret = btrfs_get_free_objectid(root, &objectid);
        if (ret)
                goto out;