diff options
Diffstat (limited to 'fs/udf/truncate.c')
| -rw-r--r-- | fs/udf/truncate.c | 81 |
1 files changed, 31 insertions, 50 deletions
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index fe61be17cdab..65e19b4f9424 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include "udfdecl.h" | 22 | #include "udfdecl.h" |
| 23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
| 24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
| 25 | #include <linux/udf_fs.h> | ||
| 26 | #include <linux/buffer_head.h> | 25 | #include <linux/buffer_head.h> |
| 27 | 26 | ||
| 28 | #include "udf_i.h" | 27 | #include "udf_i.h" |
| @@ -180,6 +179,24 @@ void udf_discard_prealloc(struct inode *inode) | |||
| 180 | brelse(epos.bh); | 179 | brelse(epos.bh); |
| 181 | } | 180 | } |
| 182 | 181 | ||
| 182 | static void udf_update_alloc_ext_desc(struct inode *inode, | ||
| 183 | struct extent_position *epos, | ||
| 184 | u32 lenalloc) | ||
| 185 | { | ||
| 186 | struct super_block *sb = inode->i_sb; | ||
| 187 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
| 188 | |||
| 189 | struct allocExtDesc *aed = (struct allocExtDesc *) (epos->bh->b_data); | ||
| 190 | int len = sizeof(struct allocExtDesc); | ||
| 191 | |||
| 192 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | ||
| 193 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || sbi->s_udfrev >= 0x0201) | ||
| 194 | len += lenalloc; | ||
| 195 | |||
| 196 | udf_update_tag(epos->bh->b_data, len); | ||
| 197 | mark_buffer_dirty_inode(epos->bh, inode); | ||
| 198 | } | ||
| 199 | |||
| 183 | void udf_truncate_extents(struct inode *inode) | 200 | void udf_truncate_extents(struct inode *inode) |
| 184 | { | 201 | { |
| 185 | struct extent_position epos; | 202 | struct extent_position epos; |
| @@ -187,7 +204,6 @@ void udf_truncate_extents(struct inode *inode) | |||
| 187 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; | 204 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; |
| 188 | int8_t etype; | 205 | int8_t etype; |
| 189 | struct super_block *sb = inode->i_sb; | 206 | struct super_block *sb = inode->i_sb; |
| 190 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
| 191 | sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; | 207 | sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; |
| 192 | loff_t byte_offset; | 208 | loff_t byte_offset; |
| 193 | int adsize; | 209 | int adsize; |
| @@ -224,35 +240,15 @@ void udf_truncate_extents(struct inode *inode) | |||
| 224 | if (indirect_ext_len) { | 240 | if (indirect_ext_len) { |
| 225 | /* We managed to free all extents in the | 241 | /* We managed to free all extents in the |
| 226 | * indirect extent - free it too */ | 242 | * indirect extent - free it too */ |
| 227 | if (!epos.bh) | 243 | BUG_ON(!epos.bh); |
| 228 | BUG(); | ||
| 229 | udf_free_blocks(sb, inode, epos.block, | 244 | udf_free_blocks(sb, inode, epos.block, |
| 230 | 0, indirect_ext_len); | 245 | 0, indirect_ext_len); |
| 231 | } else { | 246 | } else if (!epos.bh) { |
| 232 | if (!epos.bh) { | 247 | iinfo->i_lenAlloc = lenalloc; |
| 233 | iinfo->i_lenAlloc = | 248 | mark_inode_dirty(inode); |
| 234 | lenalloc; | 249 | } else |
| 235 | mark_inode_dirty(inode); | 250 | udf_update_alloc_ext_desc(inode, |
| 236 | } else { | 251 | &epos, lenalloc); |
| 237 | struct allocExtDesc *aed = | ||
| 238 | (struct allocExtDesc *) | ||
| 239 | (epos.bh->b_data); | ||
| 240 | int len = | ||
| 241 | sizeof(struct allocExtDesc); | ||
| 242 | |||
| 243 | aed->lengthAllocDescs = | ||
| 244 | cpu_to_le32(lenalloc); | ||
| 245 | if (!UDF_QUERY_FLAG(sb, | ||
| 246 | UDF_FLAG_STRICT) || | ||
| 247 | sbi->s_udfrev >= 0x0201) | ||
| 248 | len += lenalloc; | ||
| 249 | |||
| 250 | udf_update_tag(epos.bh->b_data, | ||
| 251 | len); | ||
| 252 | mark_buffer_dirty_inode( | ||
| 253 | epos.bh, inode); | ||
| 254 | } | ||
| 255 | } | ||
| 256 | brelse(epos.bh); | 252 | brelse(epos.bh); |
| 257 | epos.offset = sizeof(struct allocExtDesc); | 253 | epos.offset = sizeof(struct allocExtDesc); |
| 258 | epos.block = eloc; | 254 | epos.block = eloc; |
| @@ -272,29 +268,14 @@ void udf_truncate_extents(struct inode *inode) | |||
| 272 | } | 268 | } |
| 273 | 269 | ||
| 274 | if (indirect_ext_len) { | 270 | if (indirect_ext_len) { |
| 275 | if (!epos.bh) | 271 | BUG_ON(!epos.bh); |
| 276 | BUG(); | ||
| 277 | udf_free_blocks(sb, inode, epos.block, 0, | 272 | udf_free_blocks(sb, inode, epos.block, 0, |
| 278 | indirect_ext_len); | 273 | indirect_ext_len); |
| 279 | } else { | 274 | } else if (!epos.bh) { |
| 280 | if (!epos.bh) { | 275 | iinfo->i_lenAlloc = lenalloc; |
| 281 | iinfo->i_lenAlloc = lenalloc; | 276 | mark_inode_dirty(inode); |
| 282 | mark_inode_dirty(inode); | 277 | } else |
| 283 | } else { | 278 | udf_update_alloc_ext_desc(inode, &epos, lenalloc); |
| 284 | struct allocExtDesc *aed = | ||
| 285 | (struct allocExtDesc *)(epos.bh->b_data); | ||
| 286 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | ||
| 287 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || | ||
| 288 | sbi->s_udfrev >= 0x0201) | ||
| 289 | udf_update_tag(epos.bh->b_data, | ||
| 290 | lenalloc + | ||
| 291 | sizeof(struct allocExtDesc)); | ||
| 292 | else | ||
| 293 | udf_update_tag(epos.bh->b_data, | ||
| 294 | sizeof(struct allocExtDesc)); | ||
| 295 | mark_buffer_dirty_inode(epos.bh, inode); | ||
| 296 | } | ||
| 297 | } | ||
| 298 | } else if (inode->i_size) { | 279 | } else if (inode->i_size) { |
| 299 | if (byte_offset) { | 280 | if (byte_offset) { |
| 300 | kernel_long_ad extent; | 281 | kernel_long_ad extent; |
