The fscrypt_extent_info will be tied to the extent_map lifetime, so it
will be created when we create the IO em, or it'll already exist in the
NOCOW case.  Use this fscrypt_info when creating the ordered extent to
make sure everything is passed through properly.

Signed-off-by: Josef Bacik <jo...@toxicpanda.com>
---
 fs/btrfs/inode.c | 62 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 43 insertions(+), 19 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a1fa5b6f3790..7d859e327485 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1160,9 +1160,8 @@ static void submit_one_async_extent(struct async_chunk 
*async_chunk,
                ret = PTR_ERR(em);
                goto out_free_reserve;
        }
-       free_extent_map(em);
 
-       ordered = btrfs_alloc_ordered_extent(inode, NULL,
+       ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info,
                                       start,                   /* file_offset 
*/
                                       async_extent->ram_size,  /* num_bytes */
                                       async_extent->ram_size,  /* ram_bytes */
@@ -1171,6 +1170,7 @@ static void submit_one_async_extent(struct async_chunk 
*async_chunk,
                                       0,                       /* offset */
                                       1 << BTRFS_ORDERED_COMPRESSED,
                                       async_extent->compress_type);
+       free_extent_map(em);
        if (IS_ERR(ordered)) {
                btrfs_drop_extent_map_range(inode, start, end, false);
                ret = PTR_ERR(ordered);
@@ -1424,13 +1424,13 @@ static noinline int cow_file_range(struct btrfs_inode 
*inode,
                        ret = PTR_ERR(em);
                        goto out_reserve;
                }
-               free_extent_map(em);
 
-               ordered = btrfs_alloc_ordered_extent(inode, NULL,
+               ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info,
                                        start, ram_size, ram_size, ins.objectid,
                                        cur_alloc_size, 0,
                                        1 << BTRFS_ORDERED_REGULAR,
                                        BTRFS_COMPRESS_NONE);
+               free_extent_map(em);
                if (IS_ERR(ordered)) {
                        ret = PTR_ERR(ordered);
                        goto out_drop_extent_cache;
@@ -2003,6 +2003,8 @@ static noinline int run_delalloc_nocow(struct btrfs_inode 
*inode,
                struct btrfs_key found_key;
                struct btrfs_file_extent_item *fi;
                struct extent_buffer *leaf;
+               struct extent_map *em = NULL;
+               struct fscrypt_extent_info *fscrypt_info = NULL;
                u64 extent_end;
                u64 ram_bytes;
                u64 nocow_end;
@@ -2143,7 +2145,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode 
*inode,
                is_prealloc = extent_type == BTRFS_FILE_EXTENT_PREALLOC;
                if (is_prealloc) {
                        u64 orig_start = found_key.offset - 
nocow_args.extent_offset;
-                       struct extent_map *em;
 
                        em = create_io_em(inode, cur_offset, 
nocow_args.num_bytes,
                                          orig_start,
@@ -2157,16 +2158,32 @@ static noinline int run_delalloc_nocow(struct 
btrfs_inode *inode,
                                ret = PTR_ERR(em);
                                goto error;
                        }
-                       free_extent_map(em);
+                       fscrypt_info = em->fscrypt_info;
+               } else if (IS_ENCRYPTED(&inode->vfs_inode)) {
+                       /*
+                        * We only want to do this lookup if we're encrypted,
+                        * otherwise fsrypt_info will be null and we can avoid
+                        * this lookup.
+                        */
+                       em = btrfs_get_extent(inode, NULL, 0, cur_offset,
+                                             nocow_args.num_bytes);
+                       if (IS_ERR(em)) {
+                               btrfs_dec_nocow_writers(nocow_bg);
+                               ret = PTR_ERR(em);
+                               goto error;
+                       }
+                       fscrypt_info = em->fscrypt_info;
                }
 
-               ordered = btrfs_alloc_ordered_extent(inode, NULL, cur_offset,
-                               nocow_args.num_bytes, nocow_args.num_bytes,
-                               nocow_args.disk_bytenr, nocow_args.num_bytes, 0,
+               ordered = btrfs_alloc_ordered_extent(inode, fscrypt_info,
+                               cur_offset, nocow_args.num_bytes,
+                               nocow_args.num_bytes, nocow_args.disk_bytenr,
+                               nocow_args.num_bytes, 0,
                                is_prealloc
                                ? (1 << BTRFS_ORDERED_PREALLOC)
                                : (1 << BTRFS_ORDERED_NOCOW),
                                BTRFS_COMPRESS_NONE);
+               free_extent_map(em);
                btrfs_dec_nocow_writers(nocow_bg);
                if (IS_ERR(ordered)) {
                        if (is_prealloc) {
@@ -7022,6 +7039,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode 
*inode,
 
 static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
                                                  struct btrfs_dio_data 
*dio_data,
+                                                 struct extent_map *orig_em,
                                                  const u64 start,
                                                  const u64 len,
                                                  const u64 orig_start,
@@ -7033,6 +7051,7 @@ static struct extent_map *btrfs_create_dio_extent(struct 
btrfs_inode *inode,
 {
        struct extent_map *em = NULL;
        struct btrfs_ordered_extent *ordered;
+       struct fscrypt_extent_info *fscrypt_info = NULL;
 
        if (type != BTRFS_ORDERED_NOCOW) {
                em = create_io_em(inode, start, len, orig_start, block_start,
@@ -7041,9 +7060,13 @@ static struct extent_map *btrfs_create_dio_extent(struct 
btrfs_inode *inode,
                                  type);
                if (IS_ERR(em))
                        goto out;
+               fscrypt_info = em->fscrypt_info;
+       } else {
+               fscrypt_info = orig_em->fscrypt_info;
        }
-       ordered = btrfs_alloc_ordered_extent(inode, NULL, start, len, len,
-                                            block_start, block_len, 0,
+
+       ordered = btrfs_alloc_ordered_extent(inode, fscrypt_info, start, len,
+                                            len, block_start, block_len, 0,
                                             (1 << type) |
                                             (1 << BTRFS_ORDERED_DIRECT),
                                             BTRFS_COMPRESS_NONE);
@@ -7080,9 +7103,10 @@ static struct extent_map *btrfs_new_extent_direct(struct 
btrfs_inode *inode,
        if (ret)
                return ERR_PTR(ret);
 
-       em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset, start,
-                                    ins.objectid, ins.offset, ins.offset,
-                                    ins.offset, BTRFS_ORDERED_REGULAR);
+       em = btrfs_create_dio_extent(inode, dio_data, NULL, start, ins.offset,
+                                    start, ins.objectid, ins.offset,
+                                    ins.offset, ins.offset,
+                                    BTRFS_ORDERED_REGULAR);
        btrfs_dec_block_group_reservations(fs_info, ins.objectid);
        if (IS_ERR(em))
                btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset,
@@ -7426,9 +7450,9 @@ static int btrfs_get_blocks_direct_write(struct 
extent_map **map,
                }
                space_reserved = true;
 
-               em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, 
len,
-                                             orig_start, block_start,
-                                             len, orig_block_len,
+               em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, em,
+                                             start, len, orig_start,
+                                             block_start, len, orig_block_len,
                                              ram_bytes, type);
                btrfs_dec_nocow_writers(bg);
                if (type == BTRFS_ORDERED_PREALLOC) {
@@ -10512,14 +10536,14 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, 
struct iov_iter *from,
                ret = PTR_ERR(em);
                goto out_free_reserved;
        }
-       free_extent_map(em);
 
-       ordered = btrfs_alloc_ordered_extent(inode, NULL, start,
+       ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info, start,
                                       num_bytes, ram_bytes, ins.objectid,
                                       ins.offset, encoded->unencoded_offset,
                                       (1 << BTRFS_ORDERED_ENCODED) |
                                       (1 << BTRFS_ORDERED_COMPRESSED),
                                       compression);
+       free_extent_map(em);
        if (IS_ERR(ordered)) {
                btrfs_drop_extent_map_range(inode, start, end, false);
                ret = PTR_ERR(ordered);
-- 
2.41.0

Reply via email to