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