summaryrefslogtreecommitdiffstats
path: root/disk-utils/mkfs.cramfs.c
diff options
context:
space:
mode:
authorSigned-off-by: Roy Peled2009-02-04 14:56:54 +0100
committerKarel Zak2009-02-04 14:56:54 +0100
commitfbaec83bc0fda4341862cc60ac9796277235e4b9 (patch)
tree827eeedf2c3108341ef423f4f81b23b4beafb389 /disk-utils/mkfs.cramfs.c
parentmount: non-setuid (POSIX file capabilities) support (diff)
downloadkernel-qcow2-util-linux-fbaec83bc0fda4341862cc60ac9796277235e4b9.tar.gz
kernel-qcow2-util-linux-fbaec83bc0fda4341862cc60ac9796277235e4b9.tar.xz
kernel-qcow2-util-linux-fbaec83bc0fda4341862cc60ac9796277235e4b9.zip
mkfs.cramfs: add endianness support to cramfs tools
cramfs is an endianness dependent file system. So far, the cramfs utilities did not support cramfs images of different endianness than the host machine. A separate utility, cramfsswap, was required in order to change the endianness of the image before and after using cramfs utilities. The extra utility introduced extra maintenance and an additional step in the process. This patch adds endianness support to mkfs.cramfs and fsck.cramfs. fsck.cramfs now automatically detects the image endianness, and can work on images of either endianness. mkfs.cramfs now accepts a new optional parameter (-N) that allows creating the cramfs image in either endianness. Signed-off-by: Roy Peled <the.roy.peled@gmail.com> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'disk-utils/mkfs.cramfs.c')
-rw-r--r--disk-utils/mkfs.cramfs.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/disk-utils/mkfs.cramfs.c b/disk-utils/mkfs.cramfs.c
index 1138bfdcc..5ac2c5b97 100644
--- a/disk-utils/mkfs.cramfs.c
+++ b/disk-utils/mkfs.cramfs.c
@@ -38,6 +38,7 @@
#include <zlib.h>
#include "cramfs.h"
+#include "cramfs_common.h"
#include "md5.h"
#include "nls.h"
@@ -55,6 +56,7 @@ static int verbose = 0;
static unsigned int blksize; /* settable via -b option */
static long total_blocks = 0, total_nodes = 1; /* pre-count the root node */
static int image_length = 0;
+static int cramfs_is_big_endian = 0; /* target is big endian */
/*
* If opt_holes is set, then mkcramfs can create explicit holes in the
@@ -121,7 +123,7 @@ usage(int status) {
FILE *stream = status ? stderr : stdout;
fprintf(stream,
- _("usage: %s [-h] [-v] [-b blksize] [-e edition] [-i file] "
+ _("usage: %s [-h] [-v] [-b blksize] [-e edition] [-N endian] [-i file] "
"[-n name] dirname outfile\n"
" -h print this help\n"
" -v be verbose\n"
@@ -129,6 +131,7 @@ usage(int status) {
"(non-zero exit status)\n"
" -b blksize use this blocksize, must equal page size\n"
" -e edition set edition number (part of fsid)\n"
+ " -N endian set cramfs endianness (big|little|host), default host\n"
" -i file insert a file image into the filesystem "
"(requires >= 2.4.0)\n"
" -n name set name of cramfs filesystem\n"
@@ -454,17 +457,22 @@ static unsigned int write_superblock(struct entry *root, char *base, int size)
super->root.size = root->size;
super->root.offset = offset >> 2;
+ super_toggle_endianness(cramfs_is_big_endian, super);
+ inode_from_host(cramfs_is_big_endian, &super->root, &super->root);
+
return offset;
}
static void set_data_offset(struct entry *entry, char *base, unsigned long offset)
{
struct cramfs_inode *inode = (struct cramfs_inode *) (base + entry->dir_offset);
+ inode_to_host(cramfs_is_big_endian, inode, inode);
if (offset >= (1 << (2 + CRAMFS_OFFSET_WIDTH))) {
fprintf(stderr, _("filesystem too big. Exiting.\n"));
exit(8);
}
inode->offset = (offset >> 2);
+ inode_from_host(cramfs_is_big_endian, inode, inode);
}
@@ -523,6 +531,7 @@ static unsigned int write_directory_structure(struct entry *entry, char *base, u
entry_stack[stack_entries] = entry;
stack_entries++;
}
+ inode_from_host(cramfs_is_big_endian, inode, inode);
entry = entry->next;
}
@@ -630,7 +639,7 @@ do_compress(char *base, unsigned int offset, unsigned char const *name,
exit(8);
}
- *(u32 *) (base + offset) = curr;
+ *(u32 *) (base + offset) = u32_toggle_endianness(cramfs_is_big_endian, curr);
offset += 4;
} while (size);
@@ -734,6 +743,7 @@ int main(int argc, char **argv)
char const *dirname, *outfile;
u32 crc = crc32(0L, Z_NULL, 0);
int c;
+ cramfs_is_big_endian = HOST_IS_BIG_ENDIAN; /* default is to use host order */
blksize = getpagesize();
total_blocks = 0;
@@ -750,7 +760,7 @@ int main(int argc, char **argv)
textdomain(PACKAGE);
/* command line options */
- while ((c = getopt(argc, argv, "hb:Ee:i:n:psVvz")) != EOF) {
+ while ((c = getopt(argc, argv, "hb:Ee:i:n:N:psVvz")) != EOF) {
switch (c) {
case 'h':
usage(0);
@@ -765,6 +775,20 @@ int main(int argc, char **argv)
case 'e':
opt_edition = atoi(optarg);
break;
+ case 'N':
+ if (strcmp(optarg, "big") == 0) {
+ cramfs_is_big_endian = 1;
+ }
+ else if (strcmp(optarg, "little") == 0) {
+ cramfs_is_big_endian = 0;
+ }
+ else if (strcmp(optarg, "host") == 0); /* default */
+ else {
+ perror("invalid endianness given. Must be 'big', 'little', or 'host'");
+ exit(16);
+ }
+
+ break;
case 'i':
opt_image = optarg;
if (lstat(opt_image, &st) < 0) {
@@ -891,7 +915,7 @@ int main(int argc, char **argv)
/* Put the checksum in. */
crc = crc32(crc, (unsigned char *) (rom_image+opt_pad), (offset-opt_pad));
- ((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = crc;
+ ((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = u32_toggle_endianness(cramfs_is_big_endian, crc);
if (verbose)
printf(_("CRC: %x\n"), crc);