diff options
Diffstat (limited to 'fs/udf/truncate.c')
-rw-r--r-- | fs/udf/truncate.c | 100 |
1 files changed, 60 insertions, 40 deletions
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 7fc3912885a5..fe61be17cdab 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
@@ -74,17 +74,18 @@ void udf_truncate_tail_extent(struct inode *inode) | |||
74 | uint64_t lbcount = 0; | 74 | uint64_t lbcount = 0; |
75 | int8_t etype = -1, netype; | 75 | int8_t etype = -1, netype; |
76 | int adsize; | 76 | int adsize; |
77 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
77 | 78 | ||
78 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || | 79 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB || |
79 | inode->i_size == UDF_I_LENEXTENTS(inode)) | 80 | inode->i_size == iinfo->i_lenExtents) |
80 | return; | 81 | return; |
81 | /* Are we going to delete the file anyway? */ | 82 | /* Are we going to delete the file anyway? */ |
82 | if (inode->i_nlink == 0) | 83 | if (inode->i_nlink == 0) |
83 | return; | 84 | return; |
84 | 85 | ||
85 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 86 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
86 | adsize = sizeof(short_ad); | 87 | adsize = sizeof(short_ad); |
87 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | 88 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
88 | adsize = sizeof(long_ad); | 89 | adsize = sizeof(long_ad); |
89 | else | 90 | else |
90 | BUG(); | 91 | BUG(); |
@@ -117,7 +118,7 @@ void udf_truncate_tail_extent(struct inode *inode) | |||
117 | } | 118 | } |
118 | /* This inode entry is in-memory only and thus we don't have to mark | 119 | /* This inode entry is in-memory only and thus we don't have to mark |
119 | * the inode dirty */ | 120 | * the inode dirty */ |
120 | UDF_I_LENEXTENTS(inode) = inode->i_size; | 121 | iinfo->i_lenExtents = inode->i_size; |
121 | brelse(epos.bh); | 122 | brelse(epos.bh); |
122 | } | 123 | } |
123 | 124 | ||
@@ -129,19 +130,20 @@ void udf_discard_prealloc(struct inode *inode) | |||
129 | uint64_t lbcount = 0; | 130 | uint64_t lbcount = 0; |
130 | int8_t etype = -1, netype; | 131 | int8_t etype = -1, netype; |
131 | int adsize; | 132 | int adsize; |
133 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
132 | 134 | ||
133 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || | 135 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB || |
134 | inode->i_size == UDF_I_LENEXTENTS(inode)) | 136 | inode->i_size == iinfo->i_lenExtents) |
135 | return; | 137 | return; |
136 | 138 | ||
137 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 139 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
138 | adsize = sizeof(short_ad); | 140 | adsize = sizeof(short_ad); |
139 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | 141 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
140 | adsize = sizeof(long_ad); | 142 | adsize = sizeof(long_ad); |
141 | else | 143 | else |
142 | adsize = 0; | 144 | adsize = 0; |
143 | 145 | ||
144 | epos.block = UDF_I_LOCATION(inode); | 146 | epos.block = iinfo->i_location; |
145 | 147 | ||
146 | /* Find the last extent in the file */ | 148 | /* Find the last extent in the file */ |
147 | while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { | 149 | while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { |
@@ -153,8 +155,9 @@ void udf_discard_prealloc(struct inode *inode) | |||
153 | lbcount -= elen; | 155 | lbcount -= elen; |
154 | extent_trunc(inode, &epos, eloc, etype, elen, 0); | 156 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
155 | if (!epos.bh) { | 157 | if (!epos.bh) { |
156 | UDF_I_LENALLOC(inode) = | 158 | iinfo->i_lenAlloc = |
157 | epos.offset - udf_file_entry_alloc_offset(inode); | 159 | epos.offset - |
160 | udf_file_entry_alloc_offset(inode); | ||
158 | mark_inode_dirty(inode); | 161 | mark_inode_dirty(inode); |
159 | } else { | 162 | } else { |
160 | struct allocExtDesc *aed = | 163 | struct allocExtDesc *aed = |
@@ -163,7 +166,7 @@ void udf_discard_prealloc(struct inode *inode) | |||
163 | cpu_to_le32(epos.offset - | 166 | cpu_to_le32(epos.offset - |
164 | sizeof(struct allocExtDesc)); | 167 | sizeof(struct allocExtDesc)); |
165 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || | 168 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || |
166 | UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 169 | UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) |
167 | udf_update_tag(epos.bh->b_data, epos.offset); | 170 | udf_update_tag(epos.bh->b_data, epos.offset); |
168 | else | 171 | else |
169 | udf_update_tag(epos.bh->b_data, | 172 | udf_update_tag(epos.bh->b_data, |
@@ -173,7 +176,7 @@ void udf_discard_prealloc(struct inode *inode) | |||
173 | } | 176 | } |
174 | /* This inode entry is in-memory only and thus we don't have to mark | 177 | /* This inode entry is in-memory only and thus we don't have to mark |
175 | * the inode dirty */ | 178 | * the inode dirty */ |
176 | UDF_I_LENEXTENTS(inode) = lbcount; | 179 | iinfo->i_lenExtents = lbcount; |
177 | brelse(epos.bh); | 180 | brelse(epos.bh); |
178 | } | 181 | } |
179 | 182 | ||
@@ -184,13 +187,15 @@ void udf_truncate_extents(struct inode *inode) | |||
184 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; | 187 | uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; |
185 | int8_t etype; | 188 | int8_t etype; |
186 | struct super_block *sb = inode->i_sb; | 189 | struct super_block *sb = inode->i_sb; |
190 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
187 | sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; | 191 | sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; |
188 | loff_t byte_offset; | 192 | loff_t byte_offset; |
189 | int adsize; | 193 | int adsize; |
194 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
190 | 195 | ||
191 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 196 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
192 | adsize = sizeof(short_ad); | 197 | adsize = sizeof(short_ad); |
193 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | 198 | else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
194 | adsize = sizeof(long_ad); | 199 | adsize = sizeof(long_ad); |
195 | else | 200 | else |
196 | BUG(); | 201 | BUG(); |
@@ -212,7 +217,8 @@ void udf_truncate_extents(struct inode *inode) | |||
212 | else | 217 | else |
213 | lenalloc -= sizeof(struct allocExtDesc); | 218 | lenalloc -= sizeof(struct allocExtDesc); |
214 | 219 | ||
215 | while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1) { | 220 | while ((etype = udf_current_aext(inode, &epos, &eloc, |
221 | &elen, 0)) != -1) { | ||
216 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { | 222 | if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { |
217 | udf_write_aext(inode, &epos, neloc, nelen, 0); | 223 | udf_write_aext(inode, &epos, neloc, nelen, 0); |
218 | if (indirect_ext_len) { | 224 | if (indirect_ext_len) { |
@@ -224,35 +230,43 @@ void udf_truncate_extents(struct inode *inode) | |||
224 | 0, indirect_ext_len); | 230 | 0, indirect_ext_len); |
225 | } else { | 231 | } else { |
226 | if (!epos.bh) { | 232 | if (!epos.bh) { |
227 | UDF_I_LENALLOC(inode) = lenalloc; | 233 | iinfo->i_lenAlloc = |
234 | lenalloc; | ||
228 | mark_inode_dirty(inode); | 235 | mark_inode_dirty(inode); |
229 | } else { | 236 | } else { |
230 | struct allocExtDesc *aed = | 237 | struct allocExtDesc *aed = |
231 | (struct allocExtDesc *)(epos.bh->b_data); | 238 | (struct allocExtDesc *) |
239 | (epos.bh->b_data); | ||
240 | int len = | ||
241 | sizeof(struct allocExtDesc); | ||
242 | |||
232 | aed->lengthAllocDescs = | 243 | aed->lengthAllocDescs = |
233 | cpu_to_le32(lenalloc); | 244 | cpu_to_le32(lenalloc); |
234 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || | 245 | if (!UDF_QUERY_FLAG(sb, |
235 | UDF_SB_UDFREV(sb) >= 0x0201) | 246 | UDF_FLAG_STRICT) || |
236 | udf_update_tag(epos.bh->b_data, | 247 | sbi->s_udfrev >= 0x0201) |
237 | lenalloc + | 248 | len += lenalloc; |
238 | sizeof(struct allocExtDesc)); | 249 | |
239 | else | 250 | udf_update_tag(epos.bh->b_data, |
240 | udf_update_tag(epos.bh->b_data, | 251 | len); |
241 | sizeof(struct allocExtDesc)); | 252 | mark_buffer_dirty_inode( |
242 | mark_buffer_dirty_inode(epos.bh, inode); | 253 | epos.bh, inode); |
243 | } | 254 | } |
244 | } | 255 | } |
245 | brelse(epos.bh); | 256 | brelse(epos.bh); |
246 | epos.offset = sizeof(struct allocExtDesc); | 257 | epos.offset = sizeof(struct allocExtDesc); |
247 | epos.block = eloc; | 258 | epos.block = eloc; |
248 | epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, eloc, 0)); | 259 | epos.bh = udf_tread(sb, |
260 | udf_get_lb_pblock(sb, eloc, 0)); | ||
249 | if (elen) | 261 | if (elen) |
250 | indirect_ext_len = (elen + sb->s_blocksize -1) >> | 262 | indirect_ext_len = |
263 | (elen + sb->s_blocksize - 1) >> | ||
251 | sb->s_blocksize_bits; | 264 | sb->s_blocksize_bits; |
252 | else | 265 | else |
253 | indirect_ext_len = 1; | 266 | indirect_ext_len = 1; |
254 | } else { | 267 | } else { |
255 | extent_trunc(inode, &epos, eloc, etype, elen, 0); | 268 | extent_trunc(inode, &epos, eloc, etype, |
269 | elen, 0); | ||
256 | epos.offset += adsize; | 270 | epos.offset += adsize; |
257 | } | 271 | } |
258 | } | 272 | } |
@@ -264,19 +278,20 @@ void udf_truncate_extents(struct inode *inode) | |||
264 | indirect_ext_len); | 278 | indirect_ext_len); |
265 | } else { | 279 | } else { |
266 | if (!epos.bh) { | 280 | if (!epos.bh) { |
267 | UDF_I_LENALLOC(inode) = lenalloc; | 281 | iinfo->i_lenAlloc = lenalloc; |
268 | mark_inode_dirty(inode); | 282 | mark_inode_dirty(inode); |
269 | } else { | 283 | } else { |
270 | struct allocExtDesc *aed = | 284 | struct allocExtDesc *aed = |
271 | (struct allocExtDesc *)(epos.bh->b_data); | 285 | (struct allocExtDesc *)(epos.bh->b_data); |
272 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); | 286 | aed->lengthAllocDescs = cpu_to_le32(lenalloc); |
273 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || | 287 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || |
274 | UDF_SB_UDFREV(sb) >= 0x0201) | 288 | sbi->s_udfrev >= 0x0201) |
275 | udf_update_tag(epos.bh->b_data, | 289 | udf_update_tag(epos.bh->b_data, |
276 | lenalloc + sizeof(struct allocExtDesc)); | 290 | lenalloc + |
291 | sizeof(struct allocExtDesc)); | ||
277 | else | 292 | else |
278 | udf_update_tag(epos.bh->b_data, | 293 | udf_update_tag(epos.bh->b_data, |
279 | sizeof(struct allocExtDesc)); | 294 | sizeof(struct allocExtDesc)); |
280 | mark_buffer_dirty_inode(epos.bh, inode); | 295 | mark_buffer_dirty_inode(epos.bh, inode); |
281 | } | 296 | } |
282 | } | 297 | } |
@@ -290,13 +305,16 @@ void udf_truncate_extents(struct inode *inode) | |||
290 | * extending the file by 'offset' blocks. | 305 | * extending the file by 'offset' blocks. |
291 | */ | 306 | */ |
292 | if ((!epos.bh && | 307 | if ((!epos.bh && |
293 | epos.offset == udf_file_entry_alloc_offset(inode)) || | 308 | epos.offset == |
294 | (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { | 309 | udf_file_entry_alloc_offset(inode)) || |
310 | (epos.bh && epos.offset == | ||
311 | sizeof(struct allocExtDesc))) { | ||
295 | /* File has no extents at all or has empty last | 312 | /* File has no extents at all or has empty last |
296 | * indirect extent! Create a fake extent... */ | 313 | * indirect extent! Create a fake extent... */ |
297 | extent.extLocation.logicalBlockNum = 0; | 314 | extent.extLocation.logicalBlockNum = 0; |
298 | extent.extLocation.partitionReferenceNum = 0; | 315 | extent.extLocation.partitionReferenceNum = 0; |
299 | extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; | 316 | extent.extLength = |
317 | EXT_NOT_RECORDED_NOT_ALLOCATED; | ||
300 | } else { | 318 | } else { |
301 | epos.offset -= adsize; | 319 | epos.offset -= adsize; |
302 | etype = udf_next_aext(inode, &epos, | 320 | etype = udf_next_aext(inode, &epos, |
@@ -305,10 +323,12 @@ void udf_truncate_extents(struct inode *inode) | |||
305 | extent.extLength |= etype << 30; | 323 | extent.extLength |= etype << 30; |
306 | } | 324 | } |
307 | udf_extend_file(inode, &epos, &extent, | 325 | udf_extend_file(inode, &epos, &extent, |
308 | offset + ((inode->i_size & (sb->s_blocksize - 1)) != 0)); | 326 | offset + |
327 | ((inode->i_size & | ||
328 | (sb->s_blocksize - 1)) != 0)); | ||
309 | } | 329 | } |
310 | } | 330 | } |
311 | UDF_I_LENEXTENTS(inode) = inode->i_size; | 331 | iinfo->i_lenExtents = inode->i_size; |
312 | 332 | ||
313 | brelse(epos.bh); | 333 | brelse(epos.bh); |
314 | } | 334 | } |