aboutsummaryrefslogtreecommitdiff
path: root/fs/udf/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r--fs/udf/inode.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 5c1120a5fa4..76e54779b7a 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1237,8 +1237,8 @@ int udf_setsize(struct inode *inode, loff_t newsize)
return err;
}
set_size:
- truncate_setsize(inode, newsize);
up_write(&iinfo->i_data_sem);
+ truncate_setsize(inode, newsize);
} else {
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
down_write(&iinfo->i_data_sem);
@@ -1255,9 +1255,9 @@ set_size:
udf_get_block);
if (err)
return err;
+ truncate_setsize(inode, newsize);
down_write(&iinfo->i_data_sem);
udf_clear_extent_cache(inode);
- truncate_setsize(inode, newsize);
udf_truncate_extents(inode);
up_write(&iinfo->i_data_sem);
}
@@ -1495,15 +1495,19 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
}
- /*
- * Sanity check length of allocation descriptors and extended attrs to
- * avoid integer overflows
- */
- if (iinfo->i_lenEAttr > inode->i_sb->s_blocksize || iinfo->i_lenAlloc > inode->i_sb->s_blocksize)
- return;
- /* Now do exact checks */
- if (udf_file_entry_alloc_offset(inode) + iinfo->i_lenAlloc > inode->i_sb->s_blocksize)
- return;
+ /* Sanity checks for files in ICB so that we don't get confused later */
+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
+ /*
+ * For file in ICB data is stored in allocation descriptor
+ * so sizes should match
+ */
+ if (iinfo->i_lenAlloc != inode->i_size)
+ return;
+ /* File in ICB has to fit in there... */
+ if (inode->i_size > inode->i_sb->s_blocksize -
+ udf_file_entry_alloc_offset(inode))
+ return;
+ }
switch (fe->icbTag.fileType) {
case ICBTAG_FILE_TYPE_DIRECTORY: