| .. | .. |
|---|
| 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, |
|---|