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)  *  linux/fs/hfs/extent.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 1995-1997  Paul H. Hargrove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * (C) 2003 Ardis Technologies <roman@ardistech.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * This file may be distributed under the terms of the GNU General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * This file contains the functions related to the extents B-tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "hfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) /*================ File-local functions ================*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * build_key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static void hfs_ext_build_key(hfs_btree_key *key, u32 cnid, u16 block, u8 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	key->key_len = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	key->ext.FkType = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	key->ext.FNum = cpu_to_be32(cnid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	key->ext.FABN = cpu_to_be16(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * hfs_ext_compare()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *   This is the comparison function used for the extents B-tree.  In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *   comparing extent B-tree entries, the file id is the most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *   significant field (compared as unsigned ints); the fork type is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *   the second most significant field (compared as unsigned chars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *   and the allocation block number field is the least significant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *   (compared as unsigned ints).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * Input Variable(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *   struct hfs_ext_key *key1: pointer to the first key to compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *   struct hfs_ext_key *key2: pointer to the second key to compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * Output Variable(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  *   NONE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  *   int: negative if key1<key2, positive if key1>key2, and 0 if key1==key2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * Preconditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  *   key1 and key2 point to "valid" (struct hfs_ext_key)s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * Postconditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *   This function has no side-effects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) int hfs_ext_keycmp(const btree_key *key1, const btree_key *key2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	__be32 fnum1, fnum2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	__be16 block1, block2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	fnum1 = key1->ext.FNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	fnum2 = key2->ext.FNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	if (fnum1 != fnum2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		return be32_to_cpu(fnum1) < be32_to_cpu(fnum2) ? -1 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (key1->ext.FkType != key2->ext.FkType)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		return key1->ext.FkType < key2->ext.FkType ? -1 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	block1 = key1->ext.FABN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	block2 = key2->ext.FABN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (block1 == block2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	return be16_to_cpu(block1) < be16_to_cpu(block2) ? -1 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * hfs_ext_find_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * Find a block within an extent record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static u16 hfs_ext_find_block(struct hfs_extent *ext, u16 off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	u16 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	for (i = 0; i < 3; ext++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		count = be16_to_cpu(ext->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		if (off < count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			return be16_to_cpu(ext->block) + off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		off -= count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	/* panic? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static int hfs_ext_block_count(struct hfs_extent *ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	u16 count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	for (i = 0; i < 3; ext++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		count += be16_to_cpu(ext->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static u16 hfs_ext_lastblock(struct hfs_extent *ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	ext += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	for (i = 0; i < 2; ext--, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		if (ext->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	return be16_to_cpu(ext->block) + be16_to_cpu(ext->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	hfs_ext_build_key(fd->search_key, inode->i_ino, HFS_I(inode)->cached_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			  HFS_IS_RSRC(inode) ?  HFS_FK_RSRC : HFS_FK_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	res = hfs_brec_find(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (HFS_I(inode)->flags & HFS_FLG_EXT_NEW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		if (res != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		/* Fail early and avoid ENOSPC during the btree operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		res = hfs_bmap_reserve(fd->tree, fd->tree->depth + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		hfs_brec_insert(fd, HFS_I(inode)->cached_extents, sizeof(hfs_extent_rec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		hfs_bnode_write(fd->bnode, HFS_I(inode)->cached_extents, fd->entryoffset, fd->entrylength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		HFS_I(inode)->flags &= ~HFS_FLG_EXT_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int hfs_ext_write_extent(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	struct hfs_find_data fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	if (HFS_I(inode)->flags & HFS_FLG_EXT_DIRTY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		res = hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		res = __hfs_ext_write_extent(inode, &fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		hfs_find_exit(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static inline int __hfs_ext_read_extent(struct hfs_find_data *fd, struct hfs_extent *extent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 					u32 cnid, u32 block, u8 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	hfs_ext_build_key(fd->search_key, cnid, block, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	fd->key->ext.FNum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	res = hfs_brec_find(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (res && res != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (fd->key->ext.FNum != fd->search_key->ext.FNum ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	    fd->key->ext.FkType != fd->search_key->ext.FkType)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (fd->entrylength != sizeof(hfs_extent_rec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	hfs_bnode_read(fd->bnode, extent, fd->entryoffset, sizeof(hfs_extent_rec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline int __hfs_ext_cache_extent(struct hfs_find_data *fd, struct inode *inode, u32 block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	if (HFS_I(inode)->flags & HFS_FLG_EXT_DIRTY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		res = __hfs_ext_write_extent(inode, fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			return res;
^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) 	res = __hfs_ext_read_extent(fd, HFS_I(inode)->cached_extents, inode->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 				    block, HFS_IS_RSRC(inode) ? HFS_FK_RSRC : HFS_FK_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		HFS_I(inode)->cached_start = be16_to_cpu(fd->key->ext.FABN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		HFS_I(inode)->cached_blocks = hfs_ext_block_count(HFS_I(inode)->cached_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		HFS_I(inode)->cached_start = HFS_I(inode)->cached_blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int hfs_ext_read_extent(struct inode *inode, u16 block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	struct hfs_find_data fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (block >= HFS_I(inode)->cached_start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	    block < HFS_I(inode)->cached_start + HFS_I(inode)->cached_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	res = hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		res = __hfs_ext_cache_extent(&fd, inode, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		hfs_find_exit(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static void hfs_dump_extent(struct hfs_extent *extent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	hfs_dbg(EXTENT, "   ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		hfs_dbg_cont(EXTENT, " %u:%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			     be16_to_cpu(extent[i].block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			     be16_to_cpu(extent[i].count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	hfs_dbg_cont(EXTENT, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int hfs_add_extent(struct hfs_extent *extent, u16 offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			  u16 alloc_block, u16 block_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	u16 count, start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	hfs_dump_extent(extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	for (i = 0; i < 3; extent++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		count = be16_to_cpu(extent->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		if (offset == count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			start = be16_to_cpu(extent->block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			if (alloc_block != start + count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 				if (++i >= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 					return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 				extent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 				extent->block = cpu_to_be16(alloc_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 				block_count += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			extent->count = cpu_to_be16(block_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		} else if (offset < count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		offset -= count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	/* panic? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int hfs_free_extents(struct super_block *sb, struct hfs_extent *extent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			    u16 offset, u16 block_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	u16 count, start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	hfs_dump_extent(extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	for (i = 0; i < 3; extent++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		count = be16_to_cpu(extent->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		if (offset == count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		else if (offset < count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		offset -= count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	/* panic? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		start = be16_to_cpu(extent->block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		if (count <= block_nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			hfs_clear_vbm_bits(sb, start, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			extent->block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			extent->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			block_nr -= count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			count -= block_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			hfs_clear_vbm_bits(sb, start + count, block_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			extent->count = cpu_to_be16(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			block_nr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		if (!block_nr || !i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		extent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		count = be16_to_cpu(extent->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int hfs_free_fork(struct super_block *sb, struct hfs_cat_file *file, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	struct hfs_find_data fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	u32 total_blocks, blocks, start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	u32 cnid = be32_to_cpu(file->FlNum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	struct hfs_extent *extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	int res, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (type == HFS_FK_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		total_blocks = be32_to_cpu(file->PyLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		extent = file->ExtRec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		total_blocks = be32_to_cpu(file->RPyLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		extent = file->RExtRec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	total_blocks /= HFS_SB(sb)->alloc_blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	if (!total_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		blocks += be16_to_cpu(extent[i].count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	res = hfs_free_extents(sb, extent, blocks, blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (total_blocks == blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	res = hfs_find_init(HFS_SB(sb)->ext_tree, &fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		res = __hfs_ext_read_extent(&fd, extent, cnid, total_blocks, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		start = be16_to_cpu(fd.key->ext.FABN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		hfs_free_extents(sb, extent, total_blocks - start, total_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		hfs_brec_remove(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		total_blocks = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	} while (total_blocks > blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	hfs_find_exit(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)  * hfs_get_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int hfs_get_block(struct inode *inode, sector_t block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		  struct buffer_head *bh_result, int create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	u16 dblock, ablock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	/* Convert inode block to disk allocation block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	ablock = (u32)block / HFS_SB(sb)->fs_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (block >= HFS_I(inode)->fs_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		if (!create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		if (block > HFS_I(inode)->fs_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		if (ablock >= HFS_I(inode)->alloc_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			res = hfs_extend_file(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 			if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 				return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		create = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (ablock < HFS_I(inode)->first_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		dblock = hfs_ext_find_block(HFS_I(inode)->first_extents, ablock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	mutex_lock(&HFS_I(inode)->extents_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	res = hfs_ext_read_extent(inode, ablock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		dblock = hfs_ext_find_block(HFS_I(inode)->cached_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 					    ablock - HFS_I(inode)->cached_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		mutex_unlock(&HFS_I(inode)->extents_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	mutex_unlock(&HFS_I(inode)->extents_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	map_bh(bh_result, sb, HFS_SB(sb)->fs_start +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	       dblock * HFS_SB(sb)->fs_div +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	       (u32)block % HFS_SB(sb)->fs_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (create) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		set_buffer_new(bh_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		HFS_I(inode)->phys_size += sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		HFS_I(inode)->fs_blocks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		inode_add_bytes(inode, sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) int hfs_extend_file(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	u32 start, len, goal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	mutex_lock(&HFS_I(inode)->extents_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	if (HFS_I(inode)->alloc_blocks == HFS_I(inode)->first_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		goal = hfs_ext_lastblock(HFS_I(inode)->first_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		res = hfs_ext_read_extent(inode, HFS_I(inode)->alloc_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		goal = hfs_ext_lastblock(HFS_I(inode)->cached_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	len = HFS_I(inode)->clump_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	start = hfs_vbm_search_free(sb, goal, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (!len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		res = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	hfs_dbg(EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	if (HFS_I(inode)->alloc_blocks == HFS_I(inode)->first_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		if (!HFS_I(inode)->first_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			hfs_dbg(EXTENT, "first extents\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			/* no extents yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			HFS_I(inode)->first_extents[0].block = cpu_to_be16(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			HFS_I(inode)->first_extents[0].count = cpu_to_be16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			/* try to append to extents in inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			res = hfs_add_extent(HFS_I(inode)->first_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 					     HFS_I(inode)->alloc_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 					     start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			if (res == -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 				goto insert_extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			hfs_dump_extent(HFS_I(inode)->first_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			HFS_I(inode)->first_blocks += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		res = hfs_add_extent(HFS_I(inode)->cached_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 				     HFS_I(inode)->alloc_blocks -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				     HFS_I(inode)->cached_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 				     start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			hfs_dump_extent(HFS_I(inode)->cached_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			HFS_I(inode)->flags |= HFS_FLG_EXT_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 			HFS_I(inode)->cached_blocks += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		} else if (res == -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			goto insert_extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	mutex_unlock(&HFS_I(inode)->extents_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		HFS_I(inode)->alloc_blocks += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		if (inode->i_ino < HFS_FIRSTUSER_CNID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			set_bit(HFS_FLG_ALT_MDB_DIRTY, &HFS_SB(sb)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		hfs_mark_mdb_dirty(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) insert_extent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	hfs_dbg(EXTENT, "insert new extent\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	res = hfs_ext_write_extent(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	memset(HFS_I(inode)->cached_extents, 0, sizeof(hfs_extent_rec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	HFS_I(inode)->cached_extents[0].block = cpu_to_be16(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	HFS_I(inode)->cached_extents[0].count = cpu_to_be16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	hfs_dump_extent(HFS_I(inode)->cached_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	HFS_I(inode)->flags |= HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	HFS_I(inode)->cached_start = HFS_I(inode)->alloc_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	HFS_I(inode)->cached_blocks = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) void hfs_file_truncate(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	struct hfs_find_data fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	u16 blk_cnt, alloc_cnt, start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	u32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	hfs_dbg(INODE, "truncate: %lu, %Lu -> %Lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		inode->i_ino, (long long)HFS_I(inode)->phys_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		inode->i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	if (inode->i_size > HFS_I(inode)->phys_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		struct address_space *mapping = inode->i_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		void *fsdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		/* XXX: Can use generic_cont_expand? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		size = inode->i_size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		res = pagecache_write_begin(NULL, mapping, size+1, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 					    &page, &fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 			res = pagecache_write_end(NULL, mapping, size+1, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 					page, fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			inode->i_size = HFS_I(inode)->phys_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	} else if (inode->i_size == HFS_I(inode)->phys_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	size = inode->i_size + HFS_SB(sb)->alloc_blksz - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	blk_cnt = size / HFS_SB(sb)->alloc_blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	alloc_cnt = HFS_I(inode)->alloc_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	if (blk_cnt == alloc_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	mutex_lock(&HFS_I(inode)->extents_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	res = hfs_find_init(HFS_SB(sb)->ext_tree, &fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		mutex_unlock(&HFS_I(inode)->extents_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		/* XXX: We lack error handling of hfs_file_truncate() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		if (alloc_cnt == HFS_I(inode)->first_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			hfs_free_extents(sb, HFS_I(inode)->first_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 					 alloc_cnt, alloc_cnt - blk_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 			hfs_dump_extent(HFS_I(inode)->first_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			HFS_I(inode)->first_blocks = blk_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		res = __hfs_ext_cache_extent(&fd, inode, alloc_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		start = HFS_I(inode)->cached_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		hfs_free_extents(sb, HFS_I(inode)->cached_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 				 alloc_cnt - start, alloc_cnt - blk_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		hfs_dump_extent(HFS_I(inode)->cached_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		if (blk_cnt > start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			HFS_I(inode)->flags |= HFS_FLG_EXT_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		alloc_cnt = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		HFS_I(inode)->cached_start = HFS_I(inode)->cached_blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		hfs_brec_remove(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	hfs_find_exit(&fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	mutex_unlock(&HFS_I(inode)->extents_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	HFS_I(inode)->alloc_blocks = blk_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	HFS_I(inode)->phys_size = inode->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	HFS_I(inode)->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	inode_set_bytes(inode, HFS_I(inode)->fs_blocks << sb->s_blocksize_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }