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) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * OMFS (as used by RIO Karma) file operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2005 Bob Copeland <me@bobcopeland.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/buffer_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/mpage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "omfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) static u32 omfs_max_extents(struct omfs_sb_info *sbi, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	return (sbi->s_sys_blocksize - offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 		sizeof(struct omfs_extent)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 		sizeof(struct omfs_extent_entry) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) void omfs_make_empty_table(struct buffer_head *bh, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	oe->e_next = ~cpu_to_be64(0ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	oe->e_extent_count = cpu_to_be32(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	oe->e_fill = cpu_to_be32(0x22),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	oe->e_entry.e_cluster = ~cpu_to_be64(0ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	oe->e_entry.e_blocks = ~cpu_to_be64(0ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) int omfs_shrink_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct omfs_extent *oe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct omfs_extent_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	u64 next, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	u32 extent_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	u32 max_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	/* traverse extent table, freeing each entry that is greater
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	 * than inode->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	next = inode->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	/* only support truncate -> 0 for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if (inode->i_size != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	bh = omfs_bread(inode->i_sb, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	max_extents = omfs_max_extents(sbi, OMFS_EXTENT_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			goto out_brelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		extent_count = be32_to_cpu(oe->e_extent_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		if (extent_count > max_extents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			goto out_brelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		last = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		next = be64_to_cpu(oe->e_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		entry = &oe->e_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		/* ignore last entry as it is the terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		for (; extent_count > 1; extent_count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			u64 start, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			start = be64_to_cpu(entry->e_cluster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			count = be64_to_cpu(entry->e_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			omfs_clear_range(inode->i_sb, start, (int) count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		omfs_make_empty_table(bh, (char *) oe - bh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		mark_buffer_dirty(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		if (last != inode->i_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			omfs_clear_range(inode->i_sb, last, sbi->s_mirrors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		if (next == ~0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		bh = omfs_bread(inode->i_sb, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		max_extents = omfs_max_extents(sbi, OMFS_EXTENT_CONT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) out_brelse:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static void omfs_truncate(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	omfs_shrink_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * Add new blocks to the current extent, or create new entries/continuations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * as necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			u64 *ret_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	struct omfs_extent_entry *terminator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	struct omfs_extent_entry *entry = &oe->e_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	u32 extent_count = be32_to_cpu(oe->e_extent_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	u64 new_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	u32 max_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	int new_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	/* reached the end of the extent table with no blocks mapped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 * there are three possibilities for adding: grow last extent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 * add a new extent to the current extent table, and add a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	 * continuation inode.  in last two cases need an allocator for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 * sbi->s_cluster_size
^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) 	/* TODO: handle holes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	/* should always have a terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (extent_count < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	/* trivially grow current extent, if next block is not taken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	terminator = entry + extent_count - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (extent_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		entry = terminator-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		new_block = be64_to_cpu(entry->e_cluster) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			be64_to_cpu(entry->e_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		if (omfs_allocate_block(inode->i_sb, new_block)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			be64_add_cpu(&entry->e_blocks, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			terminator->e_blocks = ~(cpu_to_be64(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 				be64_to_cpu(~terminator->e_blocks) + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	max_count = omfs_max_extents(sbi, OMFS_EXTENT_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	/* TODO: add a continuation block here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (be32_to_cpu(oe->e_extent_count) > max_count-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	/* try to allocate a new cluster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	ret = omfs_allocate_range(inode->i_sb, 1, sbi->s_clustersize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		&new_block, &new_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	/* copy terminator down an entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	entry = terminator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	terminator++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	memcpy(terminator, entry, sizeof(struct omfs_extent_entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	entry->e_cluster = cpu_to_be64(new_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	entry->e_blocks = cpu_to_be64((u64) new_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	terminator->e_blocks = ~(cpu_to_be64(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		be64_to_cpu(~terminator->e_blocks) + (u64) new_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	/* write in new entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	be32_add_cpu(&oe->e_extent_count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	*ret_block = new_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) out_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * Scans across the directory table for a given file block number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * If block not found, return 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static sector_t find_block(struct inode *inode, struct omfs_extent_entry *ent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			sector_t block, int count, int *left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	/* count > 1 because of terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	sector_t searched = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	for (; count > 1; count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		int numblocks = clus_to_blk(OMFS_SB(inode->i_sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			be64_to_cpu(ent->e_blocks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		if (block >= searched  &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		    block < searched + numblocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			 * found it at cluster + (block - searched)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			 * numblocks - (block - searched) is remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			*left = numblocks - (block - searched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			return clus_to_blk(OMFS_SB(inode->i_sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 				be64_to_cpu(ent->e_cluster)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				block - searched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		searched += numblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		ent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int omfs_get_block(struct inode *inode, sector_t block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			  struct buffer_head *bh_result, int create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	sector_t next, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	u64 new_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	u32 max_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	int extent_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	struct omfs_extent *oe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	struct omfs_extent_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	int max_blocks = bh_result->b_size >> inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	int remain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	bh = omfs_bread(inode->i_sb, inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	max_extents = omfs_max_extents(sbi, OMFS_EXTENT_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	next = inode->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			goto out_brelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		extent_count = be32_to_cpu(oe->e_extent_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		next = be64_to_cpu(oe->e_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		entry = &oe->e_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		if (extent_count > max_extents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			goto out_brelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		offset = find_block(inode, entry, block, extent_count, &remain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		if (offset > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			map_bh(bh_result, inode->i_sb, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			if (remain > max_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 				remain = max_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			bh_result->b_size = (remain << inode->i_blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			goto out_brelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		if (next == ~0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		bh = omfs_bread(inode->i_sb, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		max_extents = omfs_max_extents(sbi, OMFS_EXTENT_CONT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (create) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		ret = omfs_grow_extent(inode, oe, &new_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			mark_buffer_dirty(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			map_bh(bh_result, inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 					clus_to_blk(sbi, new_block));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) out_brelse:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	return ret;
^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) static int omfs_readpage(struct file *file, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	return block_read_full_page(page, omfs_get_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static void omfs_readahead(struct readahead_control *rac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	mpage_readahead(rac, omfs_get_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int omfs_writepage(struct page *page, struct writeback_control *wbc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	return block_write_full_page(page, omfs_get_block, wbc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) omfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	return mpage_writepages(mapping, wbc, omfs_get_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static void omfs_write_failed(struct address_space *mapping, loff_t to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	struct inode *inode = mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	if (to > inode->i_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		truncate_pagecache(inode, inode->i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		omfs_truncate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int omfs_write_begin(struct file *file, struct address_space *mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			loff_t pos, unsigned len, unsigned flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			struct page **pagep, void **fsdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	ret = block_write_begin(mapping, pos, len, flags, pagep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				omfs_get_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		omfs_write_failed(mapping, pos + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	return generic_block_bmap(mapping, block, omfs_get_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) const struct file_operations omfs_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	.llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	.read_iter = generic_file_read_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	.write_iter = generic_file_write_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	.mmap = generic_file_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	.fsync = generic_file_fsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	.splice_read = generic_file_splice_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int omfs_setattr(struct dentry *dentry, struct iattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	error = setattr_prepare(dentry, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if ((attr->ia_valid & ATTR_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	    attr->ia_size != i_size_read(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		error = inode_newsize_ok(inode, attr->ia_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		truncate_setsize(inode, attr->ia_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		omfs_truncate(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	setattr_copy(inode, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) const struct inode_operations omfs_file_inops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	.setattr = omfs_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) const struct address_space_operations omfs_aops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	.readpage = omfs_readpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	.readahead = omfs_readahead,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	.writepage = omfs_writepage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	.writepages = omfs_writepages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	.write_begin = omfs_write_begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	.write_end = generic_write_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	.bmap = omfs_bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)