summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2021-02-22 10:39:38 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2021-02-22 10:39:38 +0100
commit71f28d7e89bdd96f671959180ab78f9cce287927 (patch)
tree61379d90c1b89cdf60def60951289f2724494259 /fs
parent34d4be79d78569e6800c6fc59bfeb8b7c0ea2f5b (diff)
parent129e3317a6b283cb7bb10eb8cb0f531b603893c0 (diff)
downloadbarebox-71f28d7e89bdd96f671959180ab78f9cce287927.tar.gz
barebox-71f28d7e89bdd96f671959180ab78f9cce287927.tar.xz
Merge branch 'for-next/ext4'
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/ext4_common.c23
-rw-r--r--fs/ext4/ext4_common.h4
-rw-r--r--fs/ext4/ext4fs.c36
-rw-r--r--fs/ext4/ext4fs.h31
-rw-r--r--fs/ext4/ext_barebox.c8
-rw-r--r--fs/ext4/ext_common.h10
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