.. | .. |
---|
120 | 120 | |
---|
121 | 121 | void udf_discard_prealloc(struct inode *inode) |
---|
122 | 122 | { |
---|
123 | | - struct extent_position epos = { NULL, 0, {0, 0} }; |
---|
| 123 | + struct extent_position epos = {}; |
---|
| 124 | + struct extent_position prev_epos = {}; |
---|
124 | 125 | struct kernel_lb_addr eloc; |
---|
125 | 126 | uint32_t elen; |
---|
126 | 127 | uint64_t lbcount = 0; |
---|
127 | 128 | int8_t etype = -1, netype; |
---|
128 | | - int adsize; |
---|
129 | 129 | struct udf_inode_info *iinfo = UDF_I(inode); |
---|
| 130 | + int bsize = 1 << inode->i_blkbits; |
---|
130 | 131 | |
---|
131 | 132 | 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)) |
---|
133 | 134 | 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; |
---|
141 | 135 | |
---|
142 | 136 | epos.block = iinfo->i_location; |
---|
143 | 137 | |
---|
144 | 138 | /* 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); |
---|
147 | 146 | lbcount += elen; |
---|
148 | 147 | } |
---|
149 | 148 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { |
---|
150 | | - epos.offset -= adsize; |
---|
151 | 149 | 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)); |
---|
172 | 153 | } |
---|
173 | 154 | /* This inode entry is in-memory only and thus we don't have to mark |
---|
174 | 155 | * the inode dirty */ |
---|
175 | 156 | iinfo->i_lenExtents = lbcount; |
---|
176 | 157 | brelse(epos.bh); |
---|
| 158 | + brelse(prev_epos.bh); |
---|
177 | 159 | } |
---|
178 | 160 | |
---|
179 | 161 | static void udf_update_alloc_ext_desc(struct inode *inode, |
---|