diff options
Diffstat (limited to 'fs/udf/truncate.c')
-rw-r--r-- | fs/udf/truncate.c | 113 |
1 files changed, 39 insertions, 74 deletions
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index b2002da0a5c0..7fc3912885a5 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
@@ -32,13 +32,11 @@ static void extent_trunc(struct inode *inode, struct extent_position *epos, | |||
32 | kernel_lb_addr eloc, int8_t etype, uint32_t elen, | 32 | kernel_lb_addr eloc, int8_t etype, uint32_t elen, |
33 | uint32_t nelen) | 33 | uint32_t nelen) |
34 | { | 34 | { |
35 | kernel_lb_addr neloc = { 0, 0 }; | 35 | kernel_lb_addr neloc = {}; |
36 | int last_block = | 36 | int last_block = (elen + inode->i_sb->s_blocksize - 1) >> |
37 | (elen + inode->i_sb->s_blocksize - | 37 | inode->i_sb->s_blocksize_bits; |
38 | 1) >> inode->i_sb->s_blocksize_bits; | 38 | int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> |
39 | int first_block = | 39 | inode->i_sb->s_blocksize_bits; |
40 | (nelen + inode->i_sb->s_blocksize - | ||
41 | 1) >> inode->i_sb->s_blocksize_bits; | ||
42 | 40 | ||
43 | if (nelen) { | 41 | if (nelen) { |
44 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { | 42 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { |
@@ -70,7 +68,7 @@ static void extent_trunc(struct inode *inode, struct extent_position *epos, | |||
70 | */ | 68 | */ |
71 | void udf_truncate_tail_extent(struct inode *inode) | 69 | void udf_truncate_tail_extent(struct inode *inode) |
72 | { | 70 | { |
73 | struct extent_position epos = { NULL, 0, {0, 0} }; | 71 | struct extent_position epos = {}; |
74 | kernel_lb_addr eloc; | 72 | kernel_lb_addr eloc; |
75 | uint32_t elen, nelen; | 73 | uint32_t elen, nelen; |
76 | uint64_t lbcount = 0; | 74 | uint64_t lbcount = 0; |
@@ -156,16 +154,16 @@ void udf_discard_prealloc(struct inode *inode) | |||
156 | extent_trunc(inode, &epos, eloc, etype, elen, 0); | 154 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
157 | if (!epos.bh) { | 155 | if (!epos.bh) { |
158 | UDF_I_LENALLOC(inode) = | 156 | UDF_I_LENALLOC(inode) = |
159 | epos.offset - udf_file_entry_alloc_offset(inode); | 157 | epos.offset - udf_file_entry_alloc_offset(inode); |
160 | mark_inode_dirty(inode); | 158 | mark_inode_dirty(inode); |
161 | } else { | 159 | } else { |
162 | struct allocExtDesc *aed = | 160 | struct allocExtDesc *aed = |
163 | (struct allocExtDesc *)(epos.bh->b_data); | 161 | (struct allocExtDesc *)(epos.bh->b_data); |
164 | aed->lengthAllocDescs = | 162 | aed->lengthAllocDescs = |
165 | cpu_to_le32(epos.offset - | 163 | cpu_to_le32(epos.offset - |
166 | sizeof(struct allocExtDesc)); | 164 | sizeof(struct allocExtDesc)); |
167 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) | 165 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
168 | || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 166 | UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
169 | udf_update_tag(epos.bh->b_data, epos.offset); | 167 | udf_update_tag(epos.bh->b_data, epos.offset); |
170 | else | 168 | else |
171 | udf_update_tag(epos.bh->b_data, | 169 | udf_update_tag(epos.bh->b_data, |
@@ -182,7 +180,7 @@ void udf_discard_prealloc(struct inode *inode) | |||
182 | void udf_truncate_extents(struct inode *inode) | 180 | void udf_truncate_extents(struct inode *inode) |
183 | { | 181 | { |
184 | struct extent_position epos; | 182 | struct extent_position epos; |
185 | kernel_lb_addr eloc, neloc = { 0, 0 }; | 183 | kernel_lb_addr eloc, neloc = {}; |
186 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; | 184 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; |
187 | int8_t etype; | 185 | int8_t etype; |
188 | struct super_block *sb = inode->i_sb; | 186 | struct super_block *sb = inode->i_sb; |
@@ -198,9 +196,8 @@ void udf_truncate_extents(struct inode *inode) | |||
198 | BUG(); | 196 | BUG(); |
199 | 197 | ||
200 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); | 198 | etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); |
201 | byte_offset = | 199 | byte_offset = (offset << sb->s_blocksize_bits) + |
202 | (offset << sb->s_blocksize_bits) + | 200 | (inode->i_size & (sb->s_blocksize - 1)); |
203 | (inode->i_size & (sb->s_blocksize - 1)); | ||
204 | if (etype != -1) { | 201 | if (etype != -1) { |
205 | epos.offset -= adsize; | 202 | epos.offset -= adsize; |
206 | extent_trunc(inode, &epos, eloc, etype, elen, byte_offset); | 203 | extent_trunc(inode, &epos, eloc, etype, elen, byte_offset); |
@@ -215,9 +212,7 @@ void udf_truncate_extents(struct inode *inode) | |||
215 | else | 212 | else |
216 | lenalloc -= sizeof(struct allocExtDesc); | 213 | lenalloc -= sizeof(struct allocExtDesc); |
217 | 214 | ||
218 | while ((etype = | 215 | while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1) { |
219 | udf_current_aext(inode, &epos, &eloc, &elen, | ||
220 | 0)) != -1) { | ||
221 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { | 216 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { |
222 | udf_write_aext(inode, &epos, neloc, nelen, 0); | 217 | udf_write_aext(inode, &epos, neloc, nelen, 0); |
223 | if (indirect_ext_len) { | 218 | if (indirect_ext_len) { |
@@ -229,52 +224,35 @@ void udf_truncate_extents(struct inode *inode) | |||
229 | 0, indirect_ext_len); | 224 | 0, indirect_ext_len); |
230 | } else { | 225 | } else { |
231 | if (!epos.bh) { | 226 | if (!epos.bh) { |
232 | UDF_I_LENALLOC(inode) = | 227 | UDF_I_LENALLOC(inode) = lenalloc; |
233 | lenalloc; | ||
234 | mark_inode_dirty(inode); | 228 | mark_inode_dirty(inode); |
235 | } else { | 229 | } else { |
236 | struct allocExtDesc *aed = | 230 | struct allocExtDesc *aed = |
237 | (struct allocExtDesc | 231 | (struct allocExtDesc *)(epos.bh->b_data); |
238 | *)(epos.bh->b_data); | ||
239 | aed->lengthAllocDescs = | 232 | aed->lengthAllocDescs = |
240 | cpu_to_le32(lenalloc); | 233 | cpu_to_le32(lenalloc); |
241 | if (!UDF_QUERY_FLAG | 234 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || |
242 | (sb, UDF_FLAG_STRICT) | 235 | UDF_SB_UDFREV(sb) >= 0x0201) |
243 | || UDF_SB_UDFREV(sb) >= | 236 | udf_update_tag(epos.bh->b_data, |
244 | 0x0201) | 237 | lenalloc + |
245 | udf_update_tag(epos.bh-> | 238 | sizeof(struct allocExtDesc)); |
246 | b_data, | ||
247 | lenalloc | ||
248 | + | ||
249 | sizeof | ||
250 | (struct | ||
251 | allocExtDesc)); | ||
252 | else | 239 | else |
253 | udf_update_tag(epos.bh-> | 240 | udf_update_tag(epos.bh->b_data, |
254 | b_data, | 241 | sizeof(struct allocExtDesc)); |
255 | sizeof | 242 | mark_buffer_dirty_inode(epos.bh, inode); |
256 | (struct | ||
257 | allocExtDesc)); | ||
258 | mark_buffer_dirty_inode(epos.bh, | ||
259 | inode); | ||
260 | } | 243 | } |
261 | } | 244 | } |
262 | brelse(epos.bh); | 245 | brelse(epos.bh); |
263 | epos.offset = sizeof(struct allocExtDesc); | 246 | epos.offset = sizeof(struct allocExtDesc); |
264 | epos.block = eloc; | 247 | epos.block = eloc; |
265 | epos.bh = | 248 | epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, eloc, 0)); |
266 | udf_tread(sb, | ||
267 | udf_get_lb_pblock(sb, eloc, 0)); | ||
268 | if (elen) | 249 | if (elen) |
269 | indirect_ext_len = (elen + | 250 | indirect_ext_len = (elen + sb->s_blocksize -1) >> |
270 | sb->s_blocksize - | 251 | sb->s_blocksize_bits; |
271 | 1) >> sb-> | ||
272 | s_blocksize_bits; | ||
273 | else | 252 | else |
274 | indirect_ext_len = 1; | 253 | indirect_ext_len = 1; |
275 | } else { | 254 | } else { |
276 | extent_trunc(inode, &epos, eloc, etype, elen, | 255 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
277 | 0); | ||
278 | epos.offset += adsize; | 256 | epos.offset += adsize; |
279 | } | 257 | } |
280 | } | 258 | } |
@@ -292,16 +270,13 @@ void udf_truncate_extents(struct inode *inode) | |||
292 | struct allocExtDesc *aed = | 270 | struct allocExtDesc *aed = |
293 | (struct allocExtDesc *)(epos.bh->b_data); | 271 | (struct allocExtDesc *)(epos.bh->b_data); |
294 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | 272 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); |
295 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) | 273 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || |
296 | || UDF_SB_UDFREV(sb) >= 0x0201) | 274 | UDF_SB_UDFREV(sb) >= 0x0201) |
297 | udf_update_tag(epos.bh->b_data, | 275 | udf_update_tag(epos.bh->b_data, |
298 | lenalloc + | 276 | lenalloc + sizeof(struct allocExtDesc)); |
299 | sizeof(struct | ||
300 | allocExtDesc)); | ||
301 | else | 277 | else |
302 | udf_update_tag(epos.bh->b_data, | 278 | udf_update_tag(epos.bh->b_data, |
303 | sizeof(struct | 279 | sizeof(struct allocExtDesc)); |
304 | allocExtDesc)); | ||
305 | mark_buffer_dirty_inode(epos.bh, inode); | 280 | mark_buffer_dirty_inode(epos.bh, inode); |
306 | } | 281 | } |
307 | } | 282 | } |
@@ -314,21 +289,14 @@ void udf_truncate_extents(struct inode *inode) | |||
314 | * no extent above inode->i_size => truncate is | 289 | * no extent above inode->i_size => truncate is |
315 | * extending the file by 'offset' blocks. | 290 | * extending the file by 'offset' blocks. |
316 | */ | 291 | */ |
317 | if ((!epos.bh | 292 | if ((!epos.bh && |
318 | && epos.offset == | 293 | epos.offset == udf_file_entry_alloc_offset(inode)) || |
319 | udf_file_entry_alloc_offset(inode)) || (epos.bh | 294 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { |
320 | && epos. | ||
321 | offset == | ||
322 | sizeof | ||
323 | (struct | ||
324 | allocExtDesc))) | ||
325 | { | ||
326 | /* File has no extents at all or has empty last | 295 | /* File has no extents at all or has empty last |
327 | * indirect extent! Create a fake extent... */ | 296 | * indirect extent! Create a fake extent... */ |
328 | extent.extLocation.logicalBlockNum = 0; | 297 | extent.extLocation.logicalBlockNum = 0; |
329 | extent.extLocation.partitionReferenceNum = 0; | 298 | extent.extLocation.partitionReferenceNum = 0; |
330 | extent.extLength = | 299 | extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; |
331 | EXT_NOT_RECORDED_NOT_ALLOCATED; | ||
332 | } else { | 300 | } else { |
333 | epos.offset -= adsize; | 301 | epos.offset -= adsize; |
334 | etype = udf_next_aext(inode, &epos, | 302 | etype = udf_next_aext(inode, &epos, |
@@ -337,10 +305,7 @@ void udf_truncate_extents(struct inode *inode) | |||
337 | extent.extLength |= etype << 30; | 305 | extent.extLength |= etype << 30; |
338 | } | 306 | } |
339 | udf_extend_file(inode, &epos, &extent, | 307 | udf_extend_file(inode, &epos, &extent, |
340 | offset + | 308 | offset + ((inode->i_size & (sb->s_blocksize - 1)) != 0)); |
341 | ((inode-> | ||
342 | i_size & (sb->s_blocksize - 1)) != | ||
343 | 0)); | ||
344 | } | 309 | } |
345 | } | 310 | } |
346 | UDF_I_LENEXTENTS(inode) = inode->i_size; | 311 | UDF_I_LENEXTENTS(inode) = inode->i_size; |