^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)