fix ext4 support for volumes greater than 4 GiB
cover fix ext4 support for volumes greater than 4 GiB
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(-)
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH 1/7 ext4: change structure fields to __le/__be types
This is an adoption of the U-Boot commit
| commit 2a0b7a971aac682112cf676c6583196faafcb2b0 | Author: Michael Walle <[email protected]> | 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 <[email protected]>
--- fs/ext4/ext_common.h | 136 +++++++++++++++++++++++++-------------------------- 1 file changed, 68 insertions(+), 68 deletions(-)
fs/ext4/ext_common.h +68 -68
@@ -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 {
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH 2/7 ext4: use kernel names for byte swaps
In reply to Antony PavlovThis is an adoption of the U-Boot commit
| commit 7f101be314da1f6f612a1b84822f791d6569946b | Author: Michael Walle <[email protected]> | 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 <[email protected]>
--- 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(-)
fs/ext4/ext4_common.c +30 -30
@@ -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 ;
fs/ext4/ext4fs.c +1 -1
@@ -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 ;
fs/ext4/ext_barebox.c +5 -5
@@ -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);
fs/ext4/ext_common.h +3 -3
@@ -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
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH 3/7 ext4: drop unused and misdefined INODE_SIZE_FILESYSTEM macro
In reply to Antony PavlovNota bene sblock.inode_size actually has __le16 type.
--- fs/ext4/ext_common.h | 2 -- 1 file changed, 2 deletions(-)
fs/ext4/ext_common.h +0 -2
@@ -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
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH 4/7 ext4: fix wrong usage of le32_to_cpu()
In reply to Antony PavlovThis is an adoption of the U-Boot commit
| commit 011bc3342a485345f7136eed20e0477b8cd5580f | Author: Michael Walle <[email protected]> | 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 <[email protected]>
--- fs/ext4/ext4_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/ext4_common.c +1 -1
@@ -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);
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH 5/7 ext4: Update ext2/3/4 superblock, group descriptor and inode structures
In reply to Antony PavlovThis is an adoption of the U-Boot commit
| commit 3ee2f977f3649bcc1d0de86356145e8e6999575a | Author: Stefan Brüns <[email protected]> | 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 <[email protected]>
--- fs/ext4/ext_common.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-)
fs/ext4/ext_common.h +46 -4
@@ -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 ]; };
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH 6/7 ext4: determine group descriptor size for 64bit feature
In reply to Antony PavlovThis is an adoption of the U-Boot commits
| commit fc214ef90910159f33fbe92a6cb77839a27fa8a6 | Author: Stefan Brüns <[email protected]> | 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 <[email protected]>
| commit 3cc5bbb8e68dc67b7c3d2fdebef69408e5271469 | Author: Stefan Brüns <[email protected]> | 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 <[email protected]> | Reported-by: [email protected] | Signed-off-by: Stefan Brüns <[email protected]> | Tested-by: Kever Yang <[email protected]>
--- fs/ext4/ext4_common.c | 21 ++++++++++++++++----- fs/ext4/ext4fs.h | 3 +++ 2 files changed, 19 insertions(+), 5 deletions(-)
fs/ext4/ext4_common.c +16 -5
@@ -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 ;
fs/ext4/ext4fs.h +3 -0
@@ -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 */
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH 7/7 ext4: Use correct descriptor size when reading the block group descriptor
In reply to Antony PavlovThis is an adoption of the U-Boot commit
| commit f798b1dda1c5de818b806189e523d1b75db7e72d | Author: Stefan Brüns <[email protected]> | 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 <[email protected]>
--- fs/ext4/ext4_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/ext4/ext4_common.c +4 -4
@@ -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)
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
Sascha Hauer
AppliedQuoted 2 lines · Antony Pavlov
At the moment barebox can't correctly handle ext4 filesystem volume greater than 4 GiB.
Applied all, thanks
Sascha
Signature · 9 lines
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 [email protected] http://lists.infradead.org/mailman/listinfo/barebox