aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/truncate.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/truncate.c')
-rw-r--r--fs/udf/truncate.c113
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 */
71void udf_truncate_tail_extent(struct inode *inode) 69void 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)
182void udf_truncate_extents(struct inode *inode) 180void 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;