From: Anton Blanchard Date: Thu, 8 Jul 2010 19:03:35 +0000 (+0000) Subject: Add optional ino_size filesystem backend function X-Git-Tag: yaboot-1.3.17-rc1~12 X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=commitdiff_plain;h=f9631a4c18c659a6144a697e0c629fe63a44970f Add optional ino_size filesystem backend function Our initrd loader is very fragile and the main reason is that it doesn't know the size of the initrd. We end up claiming 1MB at a time and failing completely if the new region isn't contiguous with the previous one. Now that firmware is often at 32MB (real-base), and kernels have grown much bigger (CONFIG_FUNCTION_TRACER and CONFIG_RELOCATABLE are two big reasons), we see this failure a lot. Create a function ino_size (similar to the silo bootloader) and implement it for tftp and ext2 backends. Signed-off-by: Anton Blanchard Signed-off-by: Tony Breeds --- diff --git a/include/fs.h b/include/fs.h index 1ff7986..7f7847c 100644 --- a/include/fs.h +++ b/include/fs.h @@ -44,6 +44,8 @@ struct fs_t { unsigned int newpos); int (*close)( struct boot_file_t* file); + + unsigned int (*ino_size)(struct boot_file_t *file); }; extern const struct fs_t *fs_of; diff --git a/second/fs_ext2.c b/second/fs_ext2.c index d24450d..c86907e 100644 --- a/second/fs_ext2.c +++ b/second/fs_ext2.c @@ -54,6 +54,7 @@ static int ext2_read( struct boot_file_t* file, static int ext2_seek( struct boot_file_t* file, unsigned int newpos); static int ext2_close( struct boot_file_t* file); +static unsigned int ext2_ino_size(struct boot_file_t *file); struct fs_t ext2_filesystem = { @@ -61,7 +62,8 @@ struct fs_t ext2_filesystem = ext2_open, ext2_read, ext2_seek, - ext2_close + ext2_close, + ext2_ino_size, }; /* IO manager structure for the ext2 library */ @@ -564,6 +566,16 @@ ext2_close( struct boot_file_t* file) return 0; } +static unsigned int ext2_ino_size(struct boot_file_t *file) +{ + struct ext2_inode ei; + + if (ext2fs_read_inode(fs, file->inode, &ei)) + return 0; + + return ei.i_size; +} + static errcode_t linux_open (const char *name, int flags, io_channel * channel) { io_channel io; diff --git a/second/fs_of.c b/second/fs_of.c index 2e5feb9..5961cfe 100644 --- a/second/fs_of.c +++ b/second/fs_of.c @@ -58,6 +58,7 @@ static int of_net_open(struct boot_file_t* file, struct partition_t* part, struct boot_fspec_t* fspec); static int of_net_read(struct boot_file_t* file, unsigned int size, void* buffer); static int of_net_seek(struct boot_file_t* file, unsigned int newpos); +static unsigned int of_net_ino_size(struct boot_file_t* file); struct fs_t of_filesystem = @@ -75,7 +76,8 @@ struct fs_t of_net_filesystem = of_net_open, of_net_read, of_net_seek, - of_close + of_close, + of_net_ino_size, }; static int @@ -283,6 +285,12 @@ of_close(struct boot_file_t* file) return 0; } +static unsigned int +of_net_ino_size(struct boot_file_t* file) +{ + return file->len; +} + /* * Local variables: * c-file-style: "k&r"