1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * truncate.c 4 * 5 * PURPOSE 6 * Truncate handling routines for the OSTA-UDF(tm) filesystem. 7 * 8 * COPYRIGHT 9 * (C) 1999-2004 Ben Fennema 10 * (C) 1999 Stelias Computing Inc 11 * 12 * HISTORY 13 * 14 * 02/24/99 blf Created. 15 * 16 */ 17 18 #include "udfdecl.h" 19 #include <linux/fs.h> 20 #include <linux/mm.h> 21 22 #include "udf_i.h" 23 #include "udf_sb.h" 24 25 static void extent_trunc(struct inode *inode, struct extent_position *epos, 26 struct kernel_lb_addr *eloc, int8_t etype, uint32_t elen, 27 uint32_t nelen) 28 { 29 struct kernel_lb_addr neloc = {}; 30 int last_block = (elen + inode->i_sb->s_blocksize - 1) >> 31 inode->i_sb->s_blocksize_bits; 32 int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> 33 inode->i_sb->s_blocksize_bits; 34 35 if (nelen) { 36 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { 37 udf_free_blocks(inode->i_sb, inode, eloc, 0, 38 last_block); 39 etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30); 40 } else 41 neloc = *eloc; 42 nelen = (etype << 30) | nelen; 43 } 44 45 if (elen != nelen) { 46 udf_write_aext(inode, epos, &neloc, nelen, 0); 47 if (last_block > first_block) { 48 if (etype == (EXT_RECORDED_ALLOCATED >> 30)) 49 mark_inode_dirty(inode); 50 51 if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) 52 udf_free_blocks(inode->i_sb, inode, eloc, 53 first_block, 54 last_block - first_block); 55 } 56 } 57 } 58 59 /* 60 * Truncate the last extent to match i_size. This function assumes 61 * that preallocation extent is already truncated. 62 */ 63 void udf_truncate_tail_extent(struct inode *inode) 64 { 65 struct extent_position epos = {}; 66 struct kernel_lb_addr eloc; 67 uint32_t elen, nelen; 68 uint64_t lbcount = 0; 69 int8_t etype = -1, netype; 70 int adsize; 71 struct udf_inode_info *iinfo = UDF_I(inode); 72 int ret; 73 74 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB || 75 inode->i_size == iinfo->i_lenExtents) 76 return; 77 /* Are we going to delete the file anyway? */ 78 if (inode->i_nlink == 0) 79 return; 80 81 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 82 adsize = sizeof(struct short_ad); 83 else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) 84 adsize = sizeof(struct long_ad); 85 else 86 BUG(); 87 88 /* Find the last extent in the file */ 89 while (1) { 90 ret = udf_next_aext(inode, &epos, &eloc, &elen, &netype, 1); 91 if (ret <= 0) 92 break; 93 etype = netype; 94 lbcount += elen; 95 if (lbcount > inode->i_size) { 96 if (lbcount - inode->i_size >= inode->i_sb->s_blocksize) 97 udf_warn(inode->i_sb, 98 "Too long extent after EOF in inode %u: i_size: %lld lbcount: %lld extent %u+%u\n", 99 (unsigned)inode->i_ino, 100 (long long)inode->i_size, 101 (long long)lbcount, 102 (unsigned)eloc.logicalBlockNum, 103 (unsigned)elen); 104 nelen = elen - (lbcount - inode->i_size); 105 epos.offset -= adsize; 106 extent_trunc(inode, &epos, &eloc, etype, elen, nelen); 107 epos.offset += adsize; 108 if (udf_next_aext(inode, &epos, &eloc, &elen, 109 &netype, 1) > 0) 110 udf_err(inode->i_sb, 111 "Extent after EOF in inode %u\n", 112 (unsigned)inode->i_ino); 113 break; 114 } 115 } 116 /* This inode entry is in-memory only and thus we don't have to mark 117 * the inode dirty */ 118 if (ret == 0) 119 iinfo->i_lenExtents = inode->i_size; 120 brelse(epos.bh); 121 } 122 123 void udf_discard_prealloc(struct inode *inode) 124 { 125 struct extent_position epos = {}; 126 struct extent_position prev_epos = {}; 127 struct kernel_lb_addr eloc; 128 uint32_t elen; 129 uint64_t lbcount = 0; 130 int8_t etype = -1; 131 struct udf_inode_info *iinfo = UDF_I(inode); 132 int bsize = i_blocksize(inode); 133 int8_t tmpetype = -1; 134 int ret; 135 136 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB || 137 ALIGN(inode->i_size, bsize) == ALIGN(iinfo->i_lenExtents, bsize)) 138 return; 139 140 epos.block = iinfo->i_location; 141 142 /* Find the last extent in the file */ 143 while (1) { 144 ret = udf_next_aext(inode, &epos, &eloc, &elen, &tmpetype, 0); 145 if (ret < 0) 146 goto out; 147 if (ret == 0) 148 break; 149 brelse(prev_epos.bh); 150 prev_epos = epos; 151 if (prev_epos.bh) 152 get_bh(prev_epos.bh); 153 154 ret = udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1); 155 if (ret < 0) 156 goto out; 157 lbcount += elen; 158 } 159 160 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { 161 lbcount -= elen; 162 udf_delete_aext(inode, prev_epos); 163 udf_free_blocks(inode->i_sb, inode, &eloc, 0, 164 DIV_ROUND_UP(elen, bsize)); 165 } 166 /* This inode entry is in-memory only and thus we don't have to mark 167 * the inode dirty */ 168 iinfo->i_lenExtents = lbcount; 169 out: 170 brelse(epos.bh); 171 brelse(prev_epos.bh); 172 } 173 174 static void udf_update_alloc_ext_desc(struct inode *inode, 175 struct extent_position *epos, 176 u32 lenalloc) 177 { 178 struct super_block *sb = inode->i_sb; 179 struct udf_sb_info *sbi = UDF_SB(sb); 180 181 struct allocExtDesc *aed = (struct allocExtDesc *) (epos->bh->b_data); 182 int len = sizeof(struct allocExtDesc); 183 184 aed->lengthAllocDescs = cpu_to_le32(lenalloc); 185 if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || sbi->s_udfrev >= 0x0201) 186 len += lenalloc; 187 188 udf_update_tag(epos->bh->b_data, len); 189 mark_buffer_dirty_inode(epos->bh, inode); 190 } 191 192 /* 193 * Truncate extents of inode to inode->i_size. This function can be used only 194 * for making file shorter. For making file longer, udf_extend_file() has to 195 * be used. 196 */ 197 int udf_truncate_extents(struct inode *inode) 198 { 199 struct extent_position epos; 200 struct kernel_lb_addr eloc, neloc = {}; 201 uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; 202 int8_t etype; 203 struct super_block *sb = inode->i_sb; 204 sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; 205 loff_t byte_offset; 206 int adsize; 207 struct udf_inode_info *iinfo = UDF_I(inode); 208 int ret = 0; 209 210 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 211 adsize = sizeof(struct short_ad); 212 else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) 213 adsize = sizeof(struct long_ad); 214 else 215 BUG(); 216 217 ret = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset, &etype); 218 if (ret < 0) 219 return ret; 220 byte_offset = (offset << sb->s_blocksize_bits) + 221 (inode->i_size & (sb->s_blocksize - 1)); 222 if (ret == 0) { 223 /* We should extend the file? */ 224 WARN_ON(byte_offset); 225 return 0; 226 } 227 epos.offset -= adsize; 228 extent_trunc(inode, &epos, &eloc, etype, elen, byte_offset); 229 epos.offset += adsize; 230 if (byte_offset) 231 lenalloc = epos.offset; 232 else 233 lenalloc = epos.offset - adsize; 234 235 if (!epos.bh) 236 lenalloc -= udf_file_entry_alloc_offset(inode); 237 else 238 lenalloc -= sizeof(struct allocExtDesc); 239 240 while ((ret = udf_current_aext(inode, &epos, &eloc, 241 &elen, &etype, 0)) > 0) { 242 if (etype == (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) { 243 udf_write_aext(inode, &epos, &neloc, nelen, 0); 244 if (indirect_ext_len) { 245 /* We managed to free all extents in the 246 * indirect extent - free it too */ 247 BUG_ON(!epos.bh); 248 udf_free_blocks(sb, NULL, &epos.block, 249 0, indirect_ext_len); 250 } else if (!epos.bh) { 251 iinfo->i_lenAlloc = lenalloc; 252 mark_inode_dirty(inode); 253 } else 254 udf_update_alloc_ext_desc(inode, 255 &epos, lenalloc); 256 brelse(epos.bh); 257 epos.offset = sizeof(struct allocExtDesc); 258 epos.block = eloc; 259 epos.bh = sb_bread(sb, 260 udf_get_lb_pblock(sb, &eloc, 0)); 261 /* Error reading indirect block? */ 262 if (!epos.bh) 263 return -EIO; 264 if (elen) 265 indirect_ext_len = 266 (elen + sb->s_blocksize - 1) >> 267 sb->s_blocksize_bits; 268 else 269 indirect_ext_len = 1; 270 } else { 271 extent_trunc(inode, &epos, &eloc, etype, elen, 0); 272 epos.offset += adsize; 273 } 274 } 275 276 if (ret < 0) { 277 brelse(epos.bh); 278 return ret; 279 } 280 281 if (indirect_ext_len) { 282 BUG_ON(!epos.bh); 283 udf_free_blocks(sb, NULL, &epos.block, 0, indirect_ext_len); 284 } else if (!epos.bh) { 285 iinfo->i_lenAlloc = lenalloc; 286 mark_inode_dirty(inode); 287 } else 288 udf_update_alloc_ext_desc(inode, &epos, lenalloc); 289 iinfo->i_lenExtents = inode->i_size; 290 291 brelse(epos.bh); 292 return 0; 293 } 294