aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorRobin Dong <hao.bigrat@gmail.com>2011-07-17 23:43:42 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-07-17 23:43:42 -0400
commitd46203159ed376fdbe2b05aa57e58207bf27a8f9 (patch)
tree8bcbe5545066606b12d6cd250747471802520c0b /fs/ext4/extents.c
parent015861badd0db43d025bbb538f8fc62dfaf3f18d (diff)
downloadkernel_goldelico_gta04-d46203159ed376fdbe2b05aa57e58207bf27a8f9.zip
kernel_goldelico_gta04-d46203159ed376fdbe2b05aa57e58207bf27a8f9.tar.gz
kernel_goldelico_gta04-d46203159ed376fdbe2b05aa57e58207bf27a8f9.tar.bz2
ext4: avoid eh_entries overflow before insert extent_idx
If eh_entries is equal to (or greater than) eh_max, the operation of inserting new extent_idx will make number of entries overflow. So check eh_entries before inserting the new extent_idx. Although there is no bug case according the code (function ext4_ext_insert_index is called by ext4_ext_split and ext4_ext_split is called only if the index block has free space), the right logic should be "lookup the capacity before insertion". Signed-off-by: Robin Dong <sanbai@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index b8acfab..9bec432 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -741,6 +741,16 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
logical, le32_to_cpu(curp->p_idx->ei_block));
return -EIO;
}
+
+ if (unlikely(le16_to_cpu(curp->p_hdr->eh_entries)
+ >= le16_to_cpu(curp->p_hdr->eh_max))) {
+ EXT4_ERROR_INODE(inode,
+ "eh_entries %d >= eh_max %d!",
+ le16_to_cpu(curp->p_hdr->eh_entries),
+ le16_to_cpu(curp->p_hdr->eh_max));
+ return -EIO;
+ }
+
len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx;
if (logical > le32_to_cpu(curp->p_idx->ei_block)) {
/* insert after */
@@ -770,14 +780,6 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
ext4_idx_store_pblock(ix, ptr);
le16_add_cpu(&curp->p_hdr->eh_entries, 1);
- if (unlikely(le16_to_cpu(curp->p_hdr->eh_entries)
- > le16_to_cpu(curp->p_hdr->eh_max))) {
- EXT4_ERROR_INODE(inode,
- "eh_entries %d > eh_max %d!",
- le16_to_cpu(curp->p_hdr->eh_entries),
- le16_to_cpu(curp->p_hdr->eh_max));
- return -EIO;
- }
if (unlikely(ix > EXT_LAST_INDEX(curp->p_hdr))) {
EXT4_ERROR_INODE(inode, "ix > EXT_LAST_INDEX!");
return -EIO;