Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }