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.c100
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}