diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2021-02-22 10:39:38 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-02-22 10:39:38 +0100 |
commit | 71f28d7e89bdd96f671959180ab78f9cce287927 (patch) | |
tree | 61379d90c1b89cdf60def60951289f2724494259 /fs | |
parent | 34d4be79d78569e6800c6fc59bfeb8b7c0ea2f5b (diff) | |
parent | 129e3317a6b283cb7bb10eb8cb0f531b603893c0 (diff) | |
download | barebox-71f28d7e89bdd96f671959180ab78f9cce287927.tar.gz barebox-71f28d7e89bdd96f671959180ab78f9cce287927.tar.xz |
Merge branch 'for-next/ext4'
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/ext4_common.c | 23 | ||||
-rw-r--r-- | fs/ext4/ext4_common.h | 4 | ||||
-rw-r--r-- | fs/ext4/ext4fs.c | 36 | ||||
-rw-r--r-- | fs/ext4/ext4fs.h | 31 | ||||
-rw-r--r-- | fs/ext4/ext_barebox.c | 8 | ||||
-rw-r--r-- | fs/ext4/ext_common.h | 10 |
6 files changed, 49 insertions, 63 deletions
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index c9f27f1278..4bfb55ad0d 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -43,10 +43,11 @@ static struct ext4_extent_header *ext4fs_get_extent_block(struct ext2_data *data uint32_t fileblock, int log2_blksz) { struct ext4_extent_idx *index; - unsigned long long block; + sector_t block; struct ext_filesystem *fs = data->fs; int blksz = EXT2_BLOCK_SIZE(data); - int i, ret; + ssize_t ret; + int i; while (1) { index = (struct ext4_extent_idx *)(ext_block + 1); @@ -77,10 +78,10 @@ static struct ext4_extent_header *ext4fs_get_extent_block(struct ext2_data *data } } -static int ext4fs_blockgroup(struct ext2_data *data, int group, +static ssize_t ext4fs_blockgroup(struct ext2_data *data, int group, struct ext2_block_group *blkgrp) { - long int blkno; + sector_t blkno; unsigned int blkoff, desc_per_blk; struct ext_filesystem *fs = data->fs; int desc_size = fs->gdsize; @@ -91,7 +92,7 @@ static int ext4fs_blockgroup(struct ext2_data *data, int group, group / desc_per_blk; blkoff = (group % desc_per_blk) * desc_size; - dev_dbg(fs->dev, "read %d group descriptor (blkno %ld blkoff %u)\n", + dev_dbg(fs->dev, "read %d group descriptor (blkno %llu blkoff %u)\n", group, blkno, blkoff); return ext4fs_devread(fs, blkno << LOG2_EXT2_BLOCK_SIZE(data), @@ -103,8 +104,9 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) struct ext2_block_group blkgrp; struct ext2_sblock *sblock = &data->sblock; struct ext_filesystem *fs = data->fs; - int inodes_per_block, ret; - long int blkno; + int inodes_per_block; + ssize_t ret; + sector_t blkno; unsigned int blkoff; /* It is easier to calculate if the first inode is 0. */ @@ -128,11 +130,11 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) } static int ext4fs_get_indir_block(struct ext2fs_node *node, - struct ext4fs_indir_block *indir, int blkno) + struct ext4fs_indir_block *indir, sector_t blkno) { struct ext_filesystem *fs = node->data->fs; int blksz; - int ret; + ssize_t ret; blksz = EXT2_BLOCK_SIZE(node->data); @@ -488,7 +490,8 @@ fail: int ext4fs_mount(struct ext_filesystem *fs) { struct ext2_data *data; - int ret, blksz; + ssize_t ret; + int blksz; data = zalloc(sizeof(struct ext2_data)); if (!data) diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h index 81fb67ef4c..f8ebd76266 100644 --- a/fs/ext4/ext4_common.h +++ b/fs/ext4/ext4_common.h @@ -48,8 +48,8 @@ static inline void *zalloc(size_t size) int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode); -int ext4fs_read_file(struct ext2fs_node *node, int pos, - unsigned int len, char *buf); +loff_t ext4fs_read_file(struct ext2fs_node *node, loff_t pos, + unsigned int len, char *buf); int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, struct ext2fs_node **foundnode, int *foundtype); int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c index 2d231d273a..54349aad3f 100644 --- a/fs/ext4/ext4fs.c +++ b/fs/ext4/ext4fs.c @@ -47,28 +47,32 @@ void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot) * Optimized read file API : collects and defers contiguous sector * reads into one potentially more efficient larger sequential read action */ -int ext4fs_read_file(struct ext2fs_node *node, int pos, +loff_t ext4fs_read_file(struct ext2fs_node *node, loff_t pos, unsigned int len, char *buf) { - int i; - int blockcnt; + loff_t i; + blkcnt_t blockcnt; int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data); - int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS); - unsigned int filesize = le32_to_cpu(node->inode.size); - short ret; + const int blockshift = log2blocksize + DISK_SECTOR_BITS; + const int blocksize = 1 << blockshift; + loff_t filesize = ext4_isize(node); + ssize_t ret; struct ext_filesystem *fs = node->data->fs; /* Adjust len so it we can't read past the end of the file. */ - if (len > filesize) - len = filesize; + if (len + pos > filesize) + len = filesize - pos; - blockcnt = ((len + pos) + blocksize - 1) / blocksize; + if (filesize <= pos) + return -EINVAL; - for (i = pos / blocksize; i < blockcnt; i++) { - int blknr; - int blockoff = pos % blocksize; - int blockend = blocksize; - int skipfirst = 0; + blockcnt = ((len + pos) + blocksize - 1) >> blockshift; + + for (i = pos >> blockshift; i < blockcnt; i++) { + sector_t blknr; + loff_t blockoff = pos - (blocksize * i); + loff_t blockend = blocksize; + loff_t skipfirst = 0; blknr = read_allocated_block(node, i); if (blknr < 0) @@ -78,7 +82,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) % blocksize; + blockend = (len + pos) - (blocksize * i); /* The last portion is exactly blocksize. */ if (!blockend) @@ -86,7 +90,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos, } /* First block. */ - if (i == pos / blocksize) { + if (i == pos >> blockshift) { skipfirst = blockoff; blockend -= skipfirst; } diff --git a/fs/ext4/ext4fs.h b/fs/ext4/ext4fs.h index 17a490a943..83ae9b87a4 100644 --- a/fs/ext4/ext4fs.h +++ b/fs/ext4/ext4fs.h @@ -74,39 +74,10 @@ struct ext4_extent_header { }; struct ext_filesystem { - /* Total Sector of partition */ - uint64_t total_sect; - /* Block size of partition */ - uint32_t blksz; /* Inode size of partition */ uint32_t inodesz; - /* Sectors per Block */ - uint32_t sect_perblk; /* Group Descriptor size */ uint16_t gdsize; - /* Group Descriptor Block Number */ - uint32_t gdtable_blkno; - /* Total block groups of partition */ - uint32_t no_blkgrp; - /* No of blocks required for bgdtable */ - uint32_t no_blk_pergdt; - /* Superblock */ - struct ext2_sblock *sb; - /* Block group descritpor table */ - struct ext2_block_group *bgd; - char *gdtable; - - /* Block Bitmap Related */ - unsigned char **blk_bmaps; - long int curr_blkno; - uint16_t first_pass_bbmap; - - /* Inode Bitmap Related */ - unsigned char **inode_bmaps; - int curr_inode_no; - uint16_t first_pass_ibmap; - - /* Journal Related */ /* Block Device Descriptor */ struct cdev *cdev; @@ -124,7 +95,7 @@ int ext4fs_mount(struct ext_filesystem *fs); void ext4fs_umount(struct ext_filesystem *fs); char *ext4fs_read_symlink(struct ext2fs_node *node); void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot); -int ext4fs_devread(struct ext_filesystem *fs, int sector, int byte_offset, int byte_len, char *buf); +ssize_t ext4fs_devread(struct ext_filesystem *fs, sector_t sector, int byte_offset, size_t byte_len, char *buf); long int read_allocated_block(struct ext2fs_node *node, int fileblock); #endif diff --git a/fs/ext4/ext_barebox.c b/fs/ext4/ext_barebox.c index 353ab44b29..8f318a49c0 100644 --- a/fs/ext4/ext_barebox.c +++ b/fs/ext4/ext_barebox.c @@ -27,15 +27,15 @@ #include <fcntl.h> #include "ext4_common.h" -int ext4fs_devread(struct ext_filesystem *fs, int __sector, int byte_offset, - int byte_len, char *buf) +ssize_t ext4fs_devread(struct ext_filesystem *fs, sector_t __sector, int byte_offset, + size_t byte_len, char *buf) { ssize_t size; uint64_t sector = __sector; size = cdev_read(fs->cdev, buf, byte_len, sector * SECTOR_SIZE + byte_offset, 0); if (size < 0) { - dev_err(fs->dev, "read error at sector %d: %s\n", __sector, + dev_err(fs->dev, "read error at sector %llu: %s\n", __sector, strerror(-size)); return size; } @@ -221,7 +221,7 @@ struct inode *ext_get_inode(struct super_block *sb, int ino) inode->i_ino = ino; inode->i_mode = le16_to_cpu(node->inode.mode); - inode->i_size = le32_to_cpu(node->inode.size); + inode->i_size = ext4_isize(node); switch (inode->i_mode & S_IFMT) { default: diff --git a/fs/ext4/ext_common.h b/fs/ext4/ext_common.h index a28f591bc4..37575d2a1a 100644 --- a/fs/ext4/ext_common.h +++ b/fs/ext4/ext_common.h @@ -232,5 +232,13 @@ struct ext2_data { struct ext4fs_indir_block indir1, indir2, indir3; }; -extern unsigned long part_offset; +static inline loff_t ext4_isize(struct ext2fs_node *node) +{ + if (S_ISREG(le16_to_cpu(node->inode.mode))) + return ((loff_t)le32_to_cpu(node->inode.size_high) << 32) | + le32_to_cpu(node->inode.size); + + return (loff_t) le32_to_cpu(node->inode.size); +} + #endif |