]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/ext4/extents.c
btrfs: Get rid of the confusing btrfs_file_extent_inline_len
[mirror_ubuntu-bionic-kernel.git] / fs / ext4 / extents.c
index c941251ac0c008587b1aaee10fb52e27a50e684a..d014fdc8db459b2c386eaa6d626cb8b35acf8daf 100644 (file)
@@ -530,10 +530,14 @@ __read_extent_tree_block(const char *function, unsigned int line,
        }
        if (buffer_verified(bh) && !(flags & EXT4_EX_FORCE_CACHE))
                return bh;
-       err = __ext4_ext_check(function, line, inode,
-                              ext_block_hdr(bh), depth, pblk);
-       if (err)
-               goto errout;
+       if (!ext4_has_feature_journal(inode->i_sb) ||
+           (inode->i_ino !=
+            le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) {
+               err = __ext4_ext_check(function, line, inode,
+                                      ext_block_hdr(bh), depth, pblk);
+               if (err)
+                       goto errout;
+       }
        set_buffer_verified(bh);
        /*
         * If this is a leaf block, cache all of its entries
@@ -881,6 +885,12 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
 
        eh = ext_inode_hdr(inode);
        depth = ext_depth(inode);
+       if (depth < 0 || depth > EXT4_MAX_EXTENT_DEPTH) {
+               EXT4_ERROR_INODE(inode, "inode has invalid extent depth: %d",
+                                depth);
+               ret = -EFSCORRUPTED;
+               goto err;
+       }
 
        if (path) {
                ext4_ext_drop_refs(path);
@@ -1041,6 +1051,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
        __le32 border;
        ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
        int err = 0;
+       size_t ext_size = 0;
 
        /* make decision: where to split? */
        /* FIXME: now decision is simplest: at current extent */
@@ -1132,6 +1143,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                le16_add_cpu(&neh->eh_entries, m);
        }
 
+       /* zero out unused area in the extent block */
+       ext_size = sizeof(struct ext4_extent_header) +
+               sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries);
+       memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
        ext4_extent_block_csum_set(inode, neh);
        set_buffer_uptodate(bh);
        unlock_buffer(bh);
@@ -1211,6 +1226,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                                sizeof(struct ext4_extent_idx) * m);
                        le16_add_cpu(&neh->eh_entries, m);
                }
+               /* zero out unused area in the extent block */
+               ext_size = sizeof(struct ext4_extent_header) +
+                  (sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries));
+               memset(bh->b_data + ext_size, 0,
+                       inode->i_sb->s_blocksize - ext_size);
                ext4_extent_block_csum_set(inode, neh);
                set_buffer_uptodate(bh);
                unlock_buffer(bh);
@@ -1276,6 +1296,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
        ext4_fsblk_t newblock, goal = 0;
        struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
        int err = 0;
+       size_t ext_size = 0;
 
        /* Try to prepend new index to old one */
        if (ext_depth(inode))
@@ -1301,9 +1322,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
                goto out;
        }
 
+       ext_size = sizeof(EXT4_I(inode)->i_data);
        /* move top-level index/leaf into new block */
-       memmove(bh->b_data, EXT4_I(inode)->i_data,
-               sizeof(EXT4_I(inode)->i_data));
+       memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size);
+       /* zero out unused area in the extent block */
+       memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
 
        /* set size of new block */
        neh = ext_block_hdr(bh);
@@ -3737,8 +3760,8 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle,
         * illegal.
         */
        if (ee_block != map->m_lblk || ee_len > map->m_len) {
-#ifdef EXT4_DEBUG
-               ext4_warning("Inode (%ld) finished: extent logical block %llu,"
+#ifdef CONFIG_EXT4_DEBUG
+               ext4_warning(inode->i_sb, "Inode (%ld) finished: extent logical block %llu,"
                             " len %u; IO logical block %llu, len %u",
                             inode->i_ino, (unsigned long long)ee_block, ee_len,
                             (unsigned long long)map->m_lblk, map->m_len);
@@ -5346,8 +5369,9 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
        stop = le32_to_cpu(extent->ee_block);
 
        /*
-        * In case of left shift, Don't start shifting extents until we make
-        * sure the hole is big enough to accommodate the shift.
+       * For left shifts, make sure the hole on the left is big enough to
+       * accommodate the shift.  For right shifts, make sure the last extent
+       * won't be shifted beyond EXT_MAX_BLOCKS.
        */
        if (SHIFT == SHIFT_LEFT) {
                path = ext4_find_extent(inode, start - 1, &path,
@@ -5367,9 +5391,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
 
                if ((start == ex_start && shift > ex_start) ||
                    (shift > start - ex_end)) {
-                       ext4_ext_drop_refs(path);
-                       kfree(path);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out;
+               }
+       } else {
+               if (shift > EXT_MAX_BLOCKS -
+                   (stop + ext4_ext_get_actual_len(extent))) {
+                       ret = -EINVAL;
+                       goto out;
                }
        }