* [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB @ 2017-03-20 12:35 Antony Pavlov 2017-03-20 12:35 ` [PATCH 1/7] ext4: change structure fields to __le/__be types Antony Pavlov ` (7 more replies) 0 siblings, 8 replies; 9+ messages in thread From: Antony Pavlov @ 2017-03-20 12:35 UTC (permalink / raw) To: barebox At the moment barebox can't correctly handle ext4 filesystem volume greater than 4 GiB. This patchseries fixes the problem by adaption of U-Boot commits. How to reproduce the problem: $ git clone https://git.pengutronix.de/git/barebox $ cd barebox barebox$ dd if=/dev/zero bs=128M count=40 of=5G.img barebox$ /sbin/mkfs.ext4 -F 5G.img barebox$ mkdir mnt barebox$ sudo mount 5G.img mnt/ barebox$ sudo mkdir mnt/testdir barebox$ sudo touch mnt/testdir/testfile barebox$ ls mnt/testdir/testfile -l -rw-r--r-- 1 root root 0 Mar 20 14:53 mnt/testdir/testfile barebox$ sudo umount mnt/ barebox$ make sandbox_defconfig ... barebox$ make -j3 -s ... barebox$ ./barebox -i 5G.img ... barebox@barebox sandbox:/ mount /dev/fd0 /mnt/ ext4 ext40: EXT2 rev 1, inode_size 256 barebox@barebox sandbox:/ ls /mnt/testdir/testfile ls: /mnt/testdir/testfile: No such file or directory barebox@barebox sandbox:/ ls /mnt/ -l drwxrwxrwx 0 . drwxrwxrwx 0 .. drwx------ 16384 lost+found ?--------- 0 testdir On the other hand there is no problem with volumes less than 4 GiB: barebox$ dd if=/dev/zero bs=128M count=24 of=3G.img barebox$ /sbin/mkfs.ext4 -F 3G.img barebox$ sudo mount 3G.img mnt/ barebox$ sudo mkdir mnt/testdir barebox$ sudo touch mnt/testdir/testfile barebox$ ls mnt/testdir/testfile -l -rw-r--r-- 1 root root 0 Mar 20 15:05 mnt/testdir/testfile barebox$ sudo umount mnt/ barebox$ ./barebox -i 3G.img ... barebox@barebox sandbox:/ mount /dev/fd0 /mnt/ ext4 ext40: EXT2 rev 1, inode_size 256 barebox@barebox sandbox:/ ls /mnt/testdir/testfile /mnt/testdir/testfile barebox@barebox sandbox:/ ls /mnt/ -l drwxrwxrwx 0 . drwxrwxrwx 0 .. drwx------ 16384 lost+found drwxr-xr-x 4096 testdir Antony Pavlov (7): ext4: change structure fields to __le/__be types ext4: use kernel names for byte swaps ext4: drop unused and misdefined INODE_SIZE_FILESYSTEM macro ext4: fix wrong usage of le32_to_cpu() ext4: Update ext2/3/4 superblock, group descriptor and inode structures ext4: determine group descriptor size for 64bit feature ext4: Use correct descriptor size when reading the block group descriptor fs/ext4/ext4_common.c | 83 +++++++++++++---------- fs/ext4/ext4fs.c | 2 +- fs/ext4/ext4fs.h | 3 + fs/ext4/ext_barebox.c | 10 +-- fs/ext4/ext_common.h | 184 ++++++++++++++++++++++++++++++-------------------- 5 files changed, 168 insertions(+), 114 deletions(-) -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/7] ext4: change structure fields to __le/__be types 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov @ 2017-03-20 12:35 ` Antony Pavlov 2017-03-20 12:35 ` [PATCH 2/7] ext4: use kernel names for byte swaps Antony Pavlov ` (6 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Antony Pavlov @ 2017-03-20 12:35 UTC (permalink / raw) To: barebox This is an adoption of the U-Boot commit | commit 2a0b7a971aac682112cf676c6583196faafcb2b0 | Author: Michael Walle <michael@walle.cc> | Date: Mon Aug 29 10:46:43 2016 +0200 | | ext4: change structure fields to __le/__be types | | Change all the types of ext2/4 fields to little endian types and all the | JBD fields to big endian types. Now we can use sparse (make C=1) to check | for statements where we need byteswaps. | | Signed-off-by: Michael Walle <michael@walle.cc> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> --- fs/ext4/ext_common.h | 136 +++++++++++++++++++++++++-------------------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/fs/ext4/ext_common.h b/fs/ext4/ext_common.h index 704d8e66a..a8d86472e 100644 --- a/fs/ext4/ext_common.h +++ b/fs/ext4/ext_common.h @@ -79,92 +79,92 @@ /* The ext2 superblock. */ struct ext2_sblock { - uint32_t total_inodes; - uint32_t total_blocks; - uint32_t reserved_blocks; - uint32_t free_blocks; - uint32_t free_inodes; - uint32_t first_data_block; - uint32_t log2_block_size; - uint32_t log2_fragment_size; - uint32_t blocks_per_group; - uint32_t fragments_per_group; - uint32_t inodes_per_group; - uint32_t mtime; - uint32_t utime; - uint16_t mnt_count; - uint16_t max_mnt_count; - uint16_t magic; - uint16_t fs_state; - uint16_t error_handling; - uint16_t minor_revision_level; - uint32_t lastcheck; - uint32_t checkinterval; - uint32_t creator_os; - uint32_t revision_level; - uint16_t uid_reserved; - uint16_t gid_reserved; - uint32_t first_inode; - uint16_t inode_size; - uint16_t block_group_number; - uint32_t feature_compatibility; - uint32_t feature_incompat; - uint32_t feature_ro_compat; - uint32_t unique_id[4]; + __le32 total_inodes; + __le32 total_blocks; + __le32 reserved_blocks; + __le32 free_blocks; + __le32 free_inodes; + __le32 first_data_block; + __le32 log2_block_size; + __le32 log2_fragment_size; + __le32 blocks_per_group; + __le32 fragments_per_group; + __le32 inodes_per_group; + __le32 mtime; + __le32 utime; + __le16 mnt_count; + __le16 max_mnt_count; + __le16 magic; + __le16 fs_state; + __le16 error_handling; + __le16 minor_revision_level; + __le32 lastcheck; + __le32 checkinterval; + __le32 creator_os; + __le32 revision_level; + __le16 uid_reserved; + __le16 gid_reserved; + __le32 first_inode; + __le16 inode_size; + __le16 block_group_number; + __le32 feature_compatibility; + __le32 feature_incompat; + __le32 feature_ro_compat; + __le32 unique_id[4]; char volume_name[16]; char last_mounted_on[64]; - uint32_t compression_info; + __le32 compression_info; }; struct ext2_block_group { - __u32 block_id; /* Blocks bitmap block */ - __u32 inode_id; /* Inodes bitmap block */ - __u32 inode_table_id; /* Inodes table block */ - __u16 free_blocks; /* Free blocks count */ - __u16 free_inodes; /* Free inodes count */ - __u16 used_dir_cnt; /* Directories count */ - __u16 bg_flags; - __u32 bg_reserved[2]; - __u16 bg_itable_unused; /* Unused inodes count */ - __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/ + __le32 block_id; /* Blocks bitmap block */ + __le32 inode_id; /* Inodes bitmap block */ + __le32 inode_table_id; /* Inodes table block */ + __le16 free_blocks; /* Free blocks count */ + __le16 free_inodes; /* Free inodes count */ + __le16 used_dir_cnt; /* Directories count */ + __le16 bg_flags; + __le32 bg_reserved[2]; + __le16 bg_itable_unused; /* Unused inodes count */ + __le16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/ }; /* The ext2 inode. */ struct ext2_inode { - uint16_t mode; - uint16_t uid; - uint32_t size; - uint32_t atime; - uint32_t ctime; - uint32_t mtime; - uint32_t dtime; - uint16_t gid; - uint16_t nlinks; - uint32_t blockcnt; /* Blocks of 512 bytes!! */ - uint32_t flags; - uint32_t osd1; + __le16 mode; + __le16 uid; + __le32 size; + __le32 atime; + __le32 ctime; + __le32 mtime; + __le32 dtime; + __le16 gid; + __le16 nlinks; + __le32 blockcnt; /* Blocks of 512 bytes!! */ + __le32 flags; + __le32 osd1; union { struct datablocks { - uint32_t dir_blocks[INDIRECT_BLOCKS]; - uint32_t indir_block; - uint32_t double_indir_block; - uint32_t triple_indir_block; + __le32 dir_blocks[INDIRECT_BLOCKS]; + __le32 indir_block; + __le32 double_indir_block; + __le32 triple_indir_block; } blocks; char symlink[60]; } b; - uint32_t version; - uint32_t acl; - uint32_t dir_acl; - uint32_t fragment_addr; - uint32_t osd2[3]; + __le32 version; + __le32 acl; + __le32 dir_acl; + __le32 fragment_addr; + __le32 osd2[3]; }; /* The header of an ext2 directory entry. */ struct ext2_dirent { - uint32_t inode; - uint16_t direntlen; - uint8_t namelen; - uint8_t filetype; + __le32 inode; + __le16 direntlen; + __u8 namelen; + __u8 filetype; }; struct ext2fs_node { -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/7] ext4: use kernel names for byte swaps 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov 2017-03-20 12:35 ` [PATCH 1/7] ext4: change structure fields to __le/__be types Antony Pavlov @ 2017-03-20 12:35 ` Antony Pavlov 2017-03-20 12:35 ` [PATCH 3/7] ext4: drop unused and misdefined INODE_SIZE_FILESYSTEM macro Antony Pavlov ` (5 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Antony Pavlov @ 2017-03-20 12:35 UTC (permalink / raw) To: barebox This is an adoption of the U-Boot commit | commit 7f101be314da1f6f612a1b84822f791d6569946b | Author: Michael Walle <michael@walle.cc> | Date: Mon Aug 29 10:46:44 2016 +0200 | | ext4: use kernel names for byte swaps | | Instead of __{be,le}{16,32}_to_cpu use {be,le}{16,32}_to_cpu. | | Signed-off-by: Michael Walle <michael@walle.cc> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> --- fs/ext4/ext4_common.c | 60 +++++++++++++++++++++++++-------------------------- fs/ext4/ext4fs.c | 2 +- fs/ext4/ext_barebox.c | 10 ++++----- fs/ext4/ext_common.h | 6 +++--- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index 6c4083eae..f11ca6b32 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -86,7 +86,7 @@ static int ext4fs_blockgroup(struct ext2_data *data, int group, desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group); - blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 + + blkno = le32_to_cpu(data->sblock.first_data_block) + 1 + group / desc_per_blk; blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group); @@ -109,14 +109,14 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) /* It is easier to calculate if the first inode is 0. */ ino--; - ret = ext4fs_blockgroup(data, ino / __le32_to_cpu + ret = ext4fs_blockgroup(data, ino / le32_to_cpu (sblock->inodes_per_group), &blkgrp); if (ret) return ret; inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz; - blkno = __le32_to_cpu(blkgrp.inode_table_id) + - (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; + blkno = le32_to_cpu(blkgrp.inode_table_id) + + (ino % le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; blkoff = (ino % inodes_per_block) * fs->inodesz; /* Read the inode. */ ret = ext4fs_devread(fs, blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff, @@ -212,14 +212,14 @@ long int read_allocated_block(struct ext2fs_node *node, int fileblock) if (fileblock < INDIRECT_BLOCKS) { /* Direct blocks. */ - blknr = __le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]); + blknr = le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]); } else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) { /* Indirect. */ ret = ext4fs_get_indir_block(node, &data->indir1, - __le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz); + le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz); if (ret) return ret; - blknr = __le32_to_cpu(data->indir1.data[fileblock - INDIRECT_BLOCKS]); + blknr = le32_to_cpu(data->indir1.data[fileblock - INDIRECT_BLOCKS]); } else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4 * (blksz / 4 + 1)))) { /* Double indirect. */ @@ -227,16 +227,16 @@ long int read_allocated_block(struct ext2fs_node *node, int fileblock) long int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4); ret = ext4fs_get_indir_block(node, &data->indir1, - __le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz); + le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz); if (ret) return ret; ret = ext4fs_get_indir_block(node, &data->indir2, - __le32_to_cpu(data->indir1.data[rblock / perblock]) << log2_blksz); + le32_to_cpu(data->indir1.data[rblock / perblock]) << log2_blksz); if (ret) return ret; - blknr = __le32_to_cpu(data->indir2.data[rblock % perblock]); + blknr = le32_to_cpu(data->indir2.data[rblock % perblock]); } else { /* Triple indirect. */ rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 + @@ -245,21 +245,21 @@ long int read_allocated_block(struct ext2fs_node *node, int fileblock) perblock_parent = ((blksz / 4) * (blksz / 4)); ret = ext4fs_get_indir_block(node, &data->indir1, - __le32_to_cpu(inode->b.blocks.triple_indir_block) << log2_blksz); + le32_to_cpu(inode->b.blocks.triple_indir_block) << log2_blksz); if (ret) return ret; ret = ext4fs_get_indir_block(node, &data->indir2, - __le32_to_cpu(data->indir1.data[rblock / perblock_parent]) << log2_blksz); + le32_to_cpu(data->indir1.data[rblock / perblock_parent]) << log2_blksz); if (ret) return ret; ret = ext4fs_get_indir_block(node, &data->indir3, - __le32_to_cpu(data->indir2.data[rblock / perblock_child]) << log2_blksz); + le32_to_cpu(data->indir2.data[rblock / perblock_child]) << log2_blksz); if (ret) return ret; - blknr = __le32_to_cpu(data->indir3.data[rblock % perblock_child]); + blknr = le32_to_cpu(data->indir3.data[rblock % perblock_child]); } return blknr; @@ -282,7 +282,7 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, return ret; } /* Search the file. */ - while (fpos < __le32_to_cpu(diro->inode.size)) { + while (fpos < le32_to_cpu(diro->inode.size)) { struct ext2_dirent dirent; status = ext4fs_read_file(diro, fpos, @@ -308,7 +308,7 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, return -ENOMEM; fdiro->data = diro->data; - fdiro->ino = __le32_to_cpu(dirent.inode); + fdiro->ino = le32_to_cpu(dirent.inode); filename[dirent.namelen] = '\0'; @@ -323,7 +323,7 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, type = FILETYPE_REG; } else { ret = ext4fs_read_inode(diro->data, - __le32_to_cpu + le32_to_cpu (dirent.inode), &fdiro->inode); if (ret) { @@ -332,15 +332,15 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, } fdiro->inode_read = 1; - if ((__le16_to_cpu(fdiro->inode.mode) & + if ((le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) { type = FILETYPE_DIRECTORY; - } else if ((__le16_to_cpu(fdiro->inode.mode) + } else if ((le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) { type = FILETYPE_SYMLINK; - } else if ((__le16_to_cpu(fdiro->inode.mode) + } else if ((le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_REG) { type = FILETYPE_REG; @@ -357,7 +357,7 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, free(fdiro); } - fpos += __le16_to_cpu(dirent.direntlen); + fpos += le16_to_cpu(dirent.direntlen); } return -ENOENT; } @@ -373,16 +373,16 @@ char *ext4fs_read_symlink(struct ext2fs_node *node) if (ret) return NULL; } - symlink = zalloc(__le32_to_cpu(diro->inode.size) + 1); + symlink = zalloc(le32_to_cpu(diro->inode.size) + 1); if (!symlink) return 0; - if (__le32_to_cpu(diro->inode.size) < sizeof(diro->inode.b.symlink)) { + if (le32_to_cpu(diro->inode.size) < sizeof(diro->inode.b.symlink)) { strncpy(symlink, diro->inode.b.symlink, - __le32_to_cpu(diro->inode.size)); + le32_to_cpu(diro->inode.size)); } else { status = ext4fs_read_file(diro, 0, - __le32_to_cpu(diro->inode.size), + le32_to_cpu(diro->inode.size), symlink); if (status == 0) { free(symlink); @@ -390,7 +390,7 @@ char *ext4fs_read_symlink(struct ext2fs_node *node) } } - symlink[__le32_to_cpu(diro->inode.size)] = '\0'; + symlink[le32_to_cpu(diro->inode.size)] = '\0'; return symlink; } @@ -501,18 +501,18 @@ int ext4fs_mount(struct ext_filesystem *fs) goto fail; /* Make sure this is an ext2 filesystem. */ - if (__le16_to_cpu(data->sblock.magic) != EXT2_SUPER_MAGIC) { + if (le16_to_cpu(data->sblock.magic) != EXT2_SUPER_MAGIC) { ret = -EINVAL; goto fail; } - if (__le32_to_cpu(data->sblock.revision_level == 0)) + if (le32_to_cpu(data->sblock.revision_level == 0)) fs->inodesz = 128; else - fs->inodesz = __le16_to_cpu(data->sblock.inode_size); + fs->inodesz = le16_to_cpu(data->sblock.inode_size); dev_info(fs->dev, "EXT2 rev %d, inode_size %d\n", - __le32_to_cpu(data->sblock.revision_level), fs->inodesz); + le32_to_cpu(data->sblock.revision_level), fs->inodesz); data->diropen.data = data; data->diropen.ino = 2; diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c index 1b9af80f8..bfc5f27cc 100644 --- a/fs/ext4/ext4fs.c +++ b/fs/ext4/ext4fs.c @@ -54,7 +54,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos, int 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); + unsigned int filesize = le32_to_cpu(node->inode.size); int previous_block_number = -1; int delayed_start = 0; int delayed_extent = 0; diff --git a/fs/ext4/ext_barebox.c b/fs/ext4/ext_barebox.c index 5ec7ecd91..e40278a5b 100644 --- a/fs/ext4/ext_barebox.c +++ b/fs/ext4/ext_barebox.c @@ -56,7 +56,7 @@ static int ext_open(struct device_d *dev, FILE *file, const char *filename) if (ret) return ret; - file->size = __le32_to_cpu(inode->inode.size); + file->size = le32_to_cpu(inode->inode.size); file->priv = inode; return 0; @@ -129,7 +129,7 @@ static struct dirent *ext_readdir(struct device_d *dev, DIR *dir) int ret; char *filename; - if (ext4_dir->fpos >= __le32_to_cpu(diro->inode.size)) + if (ext4_dir->fpos >= le32_to_cpu(diro->inode.size)) return NULL; ret = ext4fs_read_file(diro, ext4_dir->fpos, sizeof(struct ext2_dirent), @@ -151,7 +151,7 @@ static struct dirent *ext_readdir(struct device_d *dev, DIR *dir) filename[dirent.namelen] = '\0'; - ext4_dir->fpos += __le16_to_cpu(dirent.direntlen); + ext4_dir->fpos += le16_to_cpu(dirent.direntlen); strcpy(dir->d.d_name, filename); @@ -186,8 +186,8 @@ static int ext_stat(struct device_d *dev, const char *filename, struct stat *s) if (ret) return ret; - s->st_size = __le32_to_cpu(node->inode.size); - s->st_mode = __le16_to_cpu(node->inode.mode); + s->st_size = le32_to_cpu(node->inode.size); + s->st_mode = le16_to_cpu(node->inode.mode); ext4fs_free_node(node, &fs->data->diropen); diff --git a/fs/ext4/ext_common.h b/fs/ext4/ext_common.h index a8d86472e..a02f0b333 100644 --- a/fs/ext4/ext_common.h +++ b/fs/ext4/ext_common.h @@ -59,13 +59,13 @@ #define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) /* Log2 size of ext2 block in 512 blocks. */ -#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu \ +#define LOG2_EXT2_BLOCK_SIZE(data) (le32_to_cpu \ (data->sblock.log2_block_size) + 1) /* Log2 size of ext2 block in bytes. */ -#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu \ +#define LOG2_BLOCK_SIZE(data) (le32_to_cpu \ (data->sblock.log2_block_size) + 10) -#define INODE_SIZE_FILESYSTEM(data) (__le32_to_cpu \ +#define INODE_SIZE_FILESYSTEM(data) (le32_to_cpu \ (data->sblock.inode_size)) #define EXT2_FT_DIR 2 -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/7] ext4: drop unused and misdefined INODE_SIZE_FILESYSTEM macro 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov 2017-03-20 12:35 ` [PATCH 1/7] ext4: change structure fields to __le/__be types Antony Pavlov 2017-03-20 12:35 ` [PATCH 2/7] ext4: use kernel names for byte swaps Antony Pavlov @ 2017-03-20 12:35 ` Antony Pavlov 2017-03-20 12:35 ` [PATCH 4/7] ext4: fix wrong usage of le32_to_cpu() Antony Pavlov ` (4 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Antony Pavlov @ 2017-03-20 12:35 UTC (permalink / raw) To: barebox Nota bene sblock.inode_size actually has __le16 type. Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> --- fs/ext4/ext_common.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/ext4/ext_common.h b/fs/ext4/ext_common.h index a02f0b333..63cd4d26c 100644 --- a/fs/ext4/ext_common.h +++ b/fs/ext4/ext_common.h @@ -65,8 +65,6 @@ /* Log2 size of ext2 block in bytes. */ #define LOG2_BLOCK_SIZE(data) (le32_to_cpu \ (data->sblock.log2_block_size) + 10) -#define INODE_SIZE_FILESYSTEM(data) (le32_to_cpu \ - (data->sblock.inode_size)) #define EXT2_FT_DIR 2 #define SUCCESS 1 -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/7] ext4: fix wrong usage of le32_to_cpu() 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov ` (2 preceding siblings ...) 2017-03-20 12:35 ` [PATCH 3/7] ext4: drop unused and misdefined INODE_SIZE_FILESYSTEM macro Antony Pavlov @ 2017-03-20 12:35 ` Antony Pavlov 2017-03-20 12:35 ` [PATCH 5/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures Antony Pavlov ` (3 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Antony Pavlov @ 2017-03-20 12:35 UTC (permalink / raw) To: barebox This is an adoption of the U-Boot commit | commit 011bc3342a485345f7136eed20e0477b8cd5580f | Author: Michael Walle <michael@walle.cc> | Date: Mon Aug 29 10:46:46 2016 +0200 | | ext4: fix wrong usage of le32_to_cpu() | | le32_to_cpu() must only convert the revision_level and not the boolean | result. | | Signed-off-by: Michael Walle <michael@walle.cc> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> --- fs/ext4/ext4_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index f11ca6b32..9cbe3dbb1 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -506,7 +506,7 @@ int ext4fs_mount(struct ext_filesystem *fs) goto fail; } - if (le32_to_cpu(data->sblock.revision_level == 0)) + if (le32_to_cpu(data->sblock.revision_level) == 0) fs->inodesz = 128; else fs->inodesz = le16_to_cpu(data->sblock.inode_size); -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 5/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov ` (3 preceding siblings ...) 2017-03-20 12:35 ` [PATCH 4/7] ext4: fix wrong usage of le32_to_cpu() Antony Pavlov @ 2017-03-20 12:35 ` Antony Pavlov 2017-03-20 12:35 ` [PATCH 6/7] ext4: determine group descriptor size for 64bit feature Antony Pavlov ` (2 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: Antony Pavlov @ 2017-03-20 12:35 UTC (permalink / raw) To: barebox This is an adoption of the U-Boot commit | commit 3ee2f977f3649bcc1d0de86356145e8e6999575a | Author: Stefan Brüns <stefan.bruens@rwth-aachen.de> | Date: Sat Sep 17 02:10:06 2016 +0200 | | ext4: Update ext2/3/4 superblock, group descriptor and inode structures | | Most importantly, the superblock provides the used group descriptor size, | which is required for the EXT4_FEATURE_INCOMPAT_64BIT. | | Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> --- fs/ext4/ext_common.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/fs/ext4/ext_common.h b/fs/ext4/ext_common.h index 63cd4d26c..e82b56b86 100644 --- a/fs/ext4/ext_common.h +++ b/fs/ext4/ext_common.h @@ -112,6 +112,33 @@ struct ext2_sblock { char volume_name[16]; char last_mounted_on[64]; __le32 compression_info; + uint8_t prealloc_blocks; + uint8_t prealloc_dir_blocks; + __le16 reserved_gdt_blocks; + uint8_t journal_uuid[16]; + __le32 journal_inode; + __le32 journal_dev; + __le32 last_orphan; + __le32 hash_seed[4]; + uint8_t default_hash_version; + uint8_t journal_backup_type; + __le16 descriptor_size; + __le32 default_mount_options; + __le32 first_meta_block_group; + __le32 mkfs_time; + __le32 journal_blocks[17]; + __le32 total_blocks_high; + __le32 reserved_blocks_high; + __le32 free_blocks_high; + __le16 min_extra_inode_size; + __le16 want_extra_inode_size; + __le32 flags; + __le16 raid_stride; + __le16 mmp_interval; + __le64 mmp_block; + __le32 raid_stripe_width; + uint8_t log2_groups_per_flex; + uint8_t checksum_type; }; struct ext2_block_group { @@ -122,9 +149,23 @@ struct ext2_block_group { __le16 free_inodes; /* Free inodes count */ __le16 used_dir_cnt; /* Directories count */ __le16 bg_flags; - __le32 bg_reserved[2]; + __le32 bg_exclude_bitmap; + __le16 bg_block_id_csum; + __le16 bg_inode_id_csum; __le16 bg_itable_unused; /* Unused inodes count */ - __le16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/ + __le16 bg_checksum; /* crc16(s_uuid+group_num+group_desc)*/ + /* following fields only exist if descriptor size is 64 */ + __le32 block_id_high; + __le32 inode_id_high; + __le32 inode_table_id_high; + __le16 free_blocks_high; + __le16 free_inodes_high; + __le16 used_dir_cnt_high; + __le16 bg_itable_unused_high; + __le32 bg_exclude_bitmap_high; + __le16 bg_block_id_csum_high; + __le16 bg_inode_id_csum_high; + __le32 bg_reserved; }; /* The ext2 inode. */ @@ -138,7 +179,7 @@ struct ext2_inode { __le32 dtime; __le16 gid; __le16 nlinks; - __le32 blockcnt; /* Blocks of 512 bytes!! */ + __le32 blockcnt; /* Blocks of either 512 or block_size bytes */ __le32 flags; __le32 osd1; union { @@ -149,10 +190,11 @@ struct ext2_inode { __le32 triple_indir_block; } blocks; char symlink[60]; + char inline_data[60]; } b; __le32 version; __le32 acl; - __le32 dir_acl; + __le32 size_high; /* previously dir_acl, but never used */ __le32 fragment_addr; __le32 osd2[3]; }; -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 6/7] ext4: determine group descriptor size for 64bit feature 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov ` (4 preceding siblings ...) 2017-03-20 12:35 ` [PATCH 5/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures Antony Pavlov @ 2017-03-20 12:35 ` Antony Pavlov 2017-03-20 12:35 ` [PATCH 7/7] ext4: Use correct descriptor size when reading the block group descriptor Antony Pavlov 2017-03-22 6:57 ` [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Sascha Hauer 7 siblings, 0 replies; 9+ messages in thread From: Antony Pavlov @ 2017-03-20 12:35 UTC (permalink / raw) To: barebox This is an adoption of the U-Boot commits | commit fc214ef90910159f33fbe92a6cb77839a27fa8a6 | Author: Stefan Brüns <stefan.bruens@rwth-aachen.de> | Date: Sat Sep 17 02:10:07 2016 +0200 | | ext4: determine group descriptor size for 64bit feature | | If EXT4_FEATURE_INCOMPAT_64BIT is set, the descriptor can be read from | the superblocks, otherwise it defaults to 32. | | Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> | commit 3cc5bbb8e68dc67b7c3d2fdebef69408e5271469 | Author: Stefan Brüns <stefan.bruens@rwth-aachen.de> | Date: Tue Dec 27 02:35:08 2016 +0100 | | fs/ext4: Initialize group descriptor size for revision level 0 filesystems | | genext2fs creates revision level 0 filesystems, which are not readable | by u-boot due to the initialized group descriptor size field. | f798b1dda1c5de818b806189e523d1b75db7e72d | | Reported-by: Kever Yang <kever.yang@rock-chips.com> | Reported-by: FrostyBytes@protonmail.com | Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> | Tested-by: Kever Yang <kever.yang@rock-chips.com> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> --- fs/ext4/ext4_common.c | 21 ++++++++++++++++----- fs/ext4/ext4fs.h | 3 +++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index 9cbe3dbb1..f35eebc21 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -506,13 +506,24 @@ int ext4fs_mount(struct ext_filesystem *fs) goto fail; } - if (le32_to_cpu(data->sblock.revision_level) == 0) + if (le32_to_cpu(data->sblock.revision_level) == 0) { fs->inodesz = 128; - else - fs->inodesz = le16_to_cpu(data->sblock.inode_size); + fs->gdsize = 32; + } else { + debug("EXT4 features COMPAT: %08x INCOMPAT: %08x RO_COMPAT: %08x\n", + le32_to_cpu(data->sblock.feature_compatibility), + le32_to_cpu(data->sblock.feature_incompat), + le32_to_cpu(data->sblock.feature_ro_compat)); - dev_info(fs->dev, "EXT2 rev %d, inode_size %d\n", - le32_to_cpu(data->sblock.revision_level), fs->inodesz); + fs->inodesz = le16_to_cpu(data->sblock.inode_size); + fs->gdsize = le32_to_cpu(data->sblock.feature_incompat) & + EXT4_FEATURE_INCOMPAT_64BIT ? + le16_to_cpu(data->sblock.descriptor_size) : 32; + } + + dev_info(fs->dev, "EXT2 rev %d, inode_size %d, descriptor size %d\n", + le32_to_cpu(data->sblock.revision_level), + fs->inodesz, fs->gdsize); data->diropen.data = data; data->diropen.ino = 2; diff --git a/fs/ext4/ext4fs.h b/fs/ext4/ext4fs.h index ead212d97..17a490a94 100644 --- a/fs/ext4/ext4fs.h +++ b/fs/ext4/ext4fs.h @@ -28,6 +28,7 @@ #define EXT4_EXT_MAGIC 0xf30a #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 #define EXT4_INDIRECT_BLOCKS 12 #define EXT4_BG_INODE_UNINIT 0x0001 @@ -81,6 +82,8 @@ struct ext_filesystem { 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 */ -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 7/7] ext4: Use correct descriptor size when reading the block group descriptor 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov ` (5 preceding siblings ...) 2017-03-20 12:35 ` [PATCH 6/7] ext4: determine group descriptor size for 64bit feature Antony Pavlov @ 2017-03-20 12:35 ` Antony Pavlov 2017-03-22 6:57 ` [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Sascha Hauer 7 siblings, 0 replies; 9+ messages in thread From: Antony Pavlov @ 2017-03-20 12:35 UTC (permalink / raw) To: barebox This is an adoption of the U-Boot commit | commit f798b1dda1c5de818b806189e523d1b75db7e72d | Author: Stefan Brüns <stefan.bruens@rwth-aachen.de> | Date: Sat Sep 17 02:10:09 2016 +0200 | | ext4: Use correct descriptor size when reading the block group descriptor | | The correct descriptor size must be used when calculating offsets, and | also to read the correct amount of data. | | Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> --- fs/ext4/ext4_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index f35eebc21..55e837b4b 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -83,19 +83,19 @@ static int ext4fs_blockgroup(struct ext2_data *data, int group, long int blkno; unsigned int blkoff, desc_per_blk; struct ext_filesystem *fs = data->fs; + int desc_size = fs->gdsize; - desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group); + desc_per_blk = EXT2_BLOCK_SIZE(data) / desc_size; blkno = le32_to_cpu(data->sblock.first_data_block) + 1 + group / desc_per_blk; - blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group); + blkoff = (group % desc_per_blk) * desc_size; dev_dbg(fs->dev, "read %d group descriptor (blkno %ld blkoff %u)\n", group, blkno, blkoff); return ext4fs_devread(fs, blkno << LOG2_EXT2_BLOCK_SIZE(data), - blkoff, sizeof(struct ext2_block_group), - (char *)blkgrp); + blkoff, desc_size, (char *)blkgrp); } int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov ` (6 preceding siblings ...) 2017-03-20 12:35 ` [PATCH 7/7] ext4: Use correct descriptor size when reading the block group descriptor Antony Pavlov @ 2017-03-22 6:57 ` Sascha Hauer 7 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2017-03-22 6:57 UTC (permalink / raw) To: Antony Pavlov; +Cc: barebox On Mon, Mar 20, 2017 at 03:35:25PM +0300, Antony Pavlov wrote: > At the moment barebox can't correctly handle ext4 filesystem volume > greater than 4 GiB. Applied all, thanks Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-03-22 6:58 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-03-20 12:35 [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Antony Pavlov 2017-03-20 12:35 ` [PATCH 1/7] ext4: change structure fields to __le/__be types Antony Pavlov 2017-03-20 12:35 ` [PATCH 2/7] ext4: use kernel names for byte swaps Antony Pavlov 2017-03-20 12:35 ` [PATCH 3/7] ext4: drop unused and misdefined INODE_SIZE_FILESYSTEM macro Antony Pavlov 2017-03-20 12:35 ` [PATCH 4/7] ext4: fix wrong usage of le32_to_cpu() Antony Pavlov 2017-03-20 12:35 ` [PATCH 5/7] ext4: Update ext2/3/4 superblock, group descriptor and inode structures Antony Pavlov 2017-03-20 12:35 ` [PATCH 6/7] ext4: determine group descriptor size for 64bit feature Antony Pavlov 2017-03-20 12:35 ` [PATCH 7/7] ext4: Use correct descriptor size when reading the block group descriptor Antony Pavlov 2017-03-22 6:57 ` [PATCH 0/7] fix ext4 support for volumes greater than 4 GiB Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox