hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
kernel/fs/udf/truncate.c
....@@ -120,60 +120,42 @@
120120
121121 void udf_discard_prealloc(struct inode *inode)
122122 {
123
- struct extent_position epos = { NULL, 0, {0, 0} };
123
+ struct extent_position epos = {};
124
+ struct extent_position prev_epos = {};
124125 struct kernel_lb_addr eloc;
125126 uint32_t elen;
126127 uint64_t lbcount = 0;
127128 int8_t etype = -1, netype;
128
- int adsize;
129129 struct udf_inode_info *iinfo = UDF_I(inode);
130
+ int bsize = 1 << inode->i_blkbits;
130131
131132 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB ||
132
- inode->i_size == iinfo->i_lenExtents)
133
+ ALIGN(inode->i_size, bsize) == ALIGN(iinfo->i_lenExtents, bsize))
133134 return;
134
-
135
- if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
136
- adsize = sizeof(struct short_ad);
137
- else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
138
- adsize = sizeof(struct long_ad);
139
- else
140
- adsize = 0;
141135
142136 epos.block = iinfo->i_location;
143137
144138 /* Find the last extent in the file */
145
- while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
146
- etype = netype;
139
+ while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 0)) != -1) {
140
+ brelse(prev_epos.bh);
141
+ prev_epos = epos;
142
+ if (prev_epos.bh)
143
+ get_bh(prev_epos.bh);
144
+
145
+ etype = udf_next_aext(inode, &epos, &eloc, &elen, 1);
147146 lbcount += elen;
148147 }
149148 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
150
- epos.offset -= adsize;
151149 lbcount -= elen;
152
- extent_trunc(inode, &epos, &eloc, etype, elen, 0);
153
- if (!epos.bh) {
154
- iinfo->i_lenAlloc =
155
- epos.offset -
156
- udf_file_entry_alloc_offset(inode);
157
- mark_inode_dirty(inode);
158
- } else {
159
- struct allocExtDesc *aed =
160
- (struct allocExtDesc *)(epos.bh->b_data);
161
- aed->lengthAllocDescs =
162
- cpu_to_le32(epos.offset -
163
- sizeof(struct allocExtDesc));
164
- if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
165
- UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
166
- udf_update_tag(epos.bh->b_data, epos.offset);
167
- else
168
- udf_update_tag(epos.bh->b_data,
169
- sizeof(struct allocExtDesc));
170
- mark_buffer_dirty_inode(epos.bh, inode);
171
- }
150
+ udf_delete_aext(inode, prev_epos);
151
+ udf_free_blocks(inode->i_sb, inode, &eloc, 0,
152
+ DIV_ROUND_UP(elen, 1 << inode->i_blkbits));
172153 }
173154 /* This inode entry is in-memory only and thus we don't have to mark
174155 * the inode dirty */
175156 iinfo->i_lenExtents = lbcount;
176157 brelse(epos.bh);
158
+ brelse(prev_epos.bh);
177159 }
178160
179161 static void udf_update_alloc_ext_desc(struct inode *inode,