diff -urN -X dontdiff linux-2.4.17/fs/cramfs/inode.c linux-curr/fs/cramfs/inode.c --- linux-2.4.17/fs/cramfs/inode.c Fri Dec 21 09:41:55 2001 +++ linux-curr/fs/cramfs/inode.c Wed Jan 2 17:07:29 2002 @@ -22,6 +22,7 @@ #include #include +#include #define CRAMFS_SB_MAGIC u.cramfs_sb.magic #define CRAMFS_SB_SIZE u.cramfs_sb.size @@ -39,7 +40,7 @@ /* These two macros may change in future, to provide better st_ino semantics. */ -#define CRAMINO(x) ((x)->offset?(x)->offset<<2:1) +#define CRAMINO(x) (GET_CRAM_OFFSET(x) ? GET_CRAM_OFFSET(x)<<2 : 1) #define OFFSET(x) ((x)->i_ino) static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode) @@ -47,10 +48,10 @@ struct inode * inode = new_inode(sb); if (inode) { - inode->i_mode = cramfs_inode->mode; - inode->i_uid = cramfs_inode->uid; - inode->i_size = cramfs_inode->size; - inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; + inode->i_mode = le16_to_cpu(cramfs_inode->mode); + inode->i_uid = le16_to_cpu(cramfs_inode->uid); + inode->i_size = CRAM_SWAB_24(cramfs_inode->size); + inode->i_blocks = (CRAM_SWAB_24(cramfs_inode->size)-1)/512 + 1; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_gid = cramfs_inode->gid; inode->i_ino = CRAMINO(cramfs_inode); @@ -70,7 +71,8 @@ inode->i_data.a_ops = &cramfs_aops; } else { inode->i_size = 0; - init_special_inode(inode, inode->i_mode, cramfs_inode->size); + init_special_inode(inode, inode->i_mode, + CRAM_SWAB_24(cramfs_inode->size)); } } return inode; @@ -209,43 +211,43 @@ up(&read_mutex); /* Do sanity checks on the superblock */ - if (super.magic != CRAMFS_MAGIC) { + if (le32_to_cpu(super.magic) != CRAMFS_MAGIC) { /* check at 512 byte offset */ memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super)); - if (super.magic != CRAMFS_MAGIC) { + if (le32_to_cpu(super.magic) != CRAMFS_MAGIC) { printk(KERN_ERR "cramfs: wrong magic\n"); goto out; } } /* get feature flags first */ - if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { + if (le32_to_cpu(super.flags) & ~CRAMFS_SUPPORTED_FLAGS) { printk(KERN_ERR "cramfs: unsupported filesystem features\n"); goto out; } /* Check that the root inode is in a sane state */ - if (!S_ISDIR(super.root.mode)) { + if (!S_ISDIR(le16_to_cpu(super.root.mode))) { printk(KERN_ERR "cramfs: root is not a directory\n"); goto out; } - root_offset = super.root.offset << 2; - if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) { - sb->CRAMFS_SB_SIZE=super.size; - sb->CRAMFS_SB_BLOCKS=super.fsid.blocks; - sb->CRAMFS_SB_FILES=super.fsid.files; + root_offset = GET_CRAM_OFFSET(&(super.root)) << 2; + if (le32_to_cpu(super.flags) & CRAMFS_FLAG_FSID_VERSION_2) { + sb->CRAMFS_SB_SIZE=le32_to_cpu(super.size); + sb->CRAMFS_SB_BLOCKS=le32_to_cpu(super.fsid.blocks); + sb->CRAMFS_SB_FILES=le32_to_cpu(super.fsid.files); } else { sb->CRAMFS_SB_SIZE=1<<28; sb->CRAMFS_SB_BLOCKS=0; sb->CRAMFS_SB_FILES=0; } - sb->CRAMFS_SB_MAGIC=super.magic; - sb->CRAMFS_SB_FLAGS=super.flags; + sb->CRAMFS_SB_MAGIC = le32_to_cpu(super.magic); + sb->CRAMFS_SB_FLAGS = le32_to_cpu(super.flags); if (root_offset == 0) printk(KERN_INFO "cramfs: empty filesystem"); - else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && - ((root_offset != sizeof(struct cramfs_super)) && - (root_offset != 512 + sizeof(struct cramfs_super)))) + else if (!(le32_to_cpu(super.flags) & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) + && ((root_offset != sizeof(struct cramfs_super)) && + (root_offset != 512 + sizeof(struct cramfs_super)))) { printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset); goto out; @@ -307,7 +309,7 @@ * and the name padded out to 4-byte boundaries * with zeroes. */ - namelen = de->namelen << 2; + namelen = GET_CRAM_NAMELEN(de) << 2; nextoffset = offset + sizeof(*de) + namelen; for (;;) { if (!namelen) @@ -316,7 +318,8 @@ break; namelen--; } - error = filldir(dirent, name, namelen, offset, CRAMINO(de), de->mode >> 12); + error = filldir(dirent, name, namelen, offset, CRAMINO(de), + le16_to_cpu(de->mode) >> 12); if (error) break; @@ -349,7 +352,7 @@ if (sorted && (dentry->d_name.name[0] < name[0])) break; - namelen = de->namelen << 2; + namelen = GET_CRAM_NAMELEN(de) << 2; offset += sizeof(*de) + namelen; /* Quick check that the name is roughly the right length */ @@ -396,8 +399,10 @@ start_offset = OFFSET(inode) + maxblock*4; down(&read_mutex); if (page->index) - start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4); - compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - start_offset); + start_offset = le32_to_cpu(*(u32 *) + cramfs_read(sb, blkptr_offset - 4, 4)); + compr_len = le32_to_cpu(*(u32 *) + cramfs_read(sb, blkptr_offset, 4)) - start_offset; up(&read_mutex); pgdata = kmap(page); if (compr_len == 0) diff -urN -X dontdiff linux-2.4.17/include/linux/cramfs_fs.h linux-curr/include/linux/cramfs_fs.h --- linux-2.4.17/include/linux/cramfs_fs.h Thu Jul 19 16:14:53 2001 +++ linux-curr/include/linux/cramfs_fs.h Wed Jan 2 17:12:31 2002 @@ -81,6 +81,31 @@ */ #define CRAMFS_SUPPORTED_FLAGS (0x7ff) +/* + * Since cramfs (according to docs) should always be stored little endian, + * provide macros to swab the bitfields (mkcramfs uses this file too). + */ +#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__) +#define CRAM_SWAB_24(x) ( ( (0x00FF0000 & (x)) >> 16 ) | \ + ( (0x0000FF00 & (x)) ) | \ + ( (0x000000FF & (x)) << 16 ) ) +#define GET_CRAM_NAMELEN(x) (((u8*)(x))[8] & 63) +#define GET_CRAM_OFFSET(x) ((CRAM_SWAB_24(((u32*)(x))[2] & 0x00FFFFFF)<<2) | \ + ((((u32*)(x))[2] & 0xC0000000)>>30) ) +#define SET_CRAM_OFFSET(x,y) ( ((u32*)(x))[2] = (((y)&3)<<30) | \ + CRAM_SWAB_24( ( ((y) & 0x03FFFFFF) >> 2) ) | \ + (((u32)(((u8*)(x))[8] & 0x3F)) << 24) ) +#define SET_CRAM_NAMELEN(x,y) ( ((u8*)(x))[8] = ( ((0x3F & (y))) | \ + (0xC0 & ((u8*)(x))[8]) ) ) + +#else +#define CRAM_SWAB_24(x) (x) +#define GET_CRAM_NAMELEN(x) ((x)->namelen) +#define GET_CRAM_OFFSET(x) ((x)->offset) +#define SET_CRAM_OFFSET(x,y) ((x)->offset = y) +#define SET_CRAM_NAMELEN(x,y) ((x)->namelen = y) +#endif + /* Uncompression interfaces to the underlying zlib */ int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen); int cramfs_uncompress_init(void); diff -urN -X dontdiff linux-2.4.17/scripts/cramfs/bitopts.h linux-curr/scripts/cramfs/bitopts.h --- linux-2.4.17/scripts/cramfs/bitopts.h Wed Dec 31 16:00:00 1969 +++ linux-curr/scripts/cramfs/bitopts.h Wed Jan 2 16:49:23 2002 @@ -0,0 +1,18 @@ +#include +#include + +/* maybe eventually remove anything we don't need (be macros) */ + +#if ( BYTE_ORDER == LITTLE_ENDIAN ) +#define le16_to_cpu(x) (x) +#define le32_to_cpu(x) (x) +#define be16_to_cpu(x) bswap_16(x) +#define be32_to_cpu(x) bswap_32(x) +#elif ( BYTE_ORDER == BIG_ENDIAN ) +#define le16_to_cpu(x) bswap_16(x) +#define le32_to_cpu(x) bswap_32(x) +#define be16_to_cpu(x) (x) +#define be32_to_cpu(x) (x) +#else +#error "cramfs only works on little-endian and big-endian systems" +#endif diff -urN -X dontdiff linux-2.4.17/scripts/cramfs/cramfsck.c linux-curr/scripts/cramfs/cramfsck.c --- linux-2.4.17/scripts/cramfs/cramfsck.c Thu Jul 19 16:14:53 2001 +++ linux-curr/scripts/cramfs/cramfsck.c Wed Jan 2 16:49:07 2002 @@ -52,6 +52,7 @@ #include #include #include +#include "bitopts.h" static const char *progname = "cramfsck"; @@ -105,17 +106,19 @@ { char info[10]; - if (S_ISCHR(i->mode) || (S_ISBLK(i->mode))) { + if (S_ISCHR(le16_to_cpu(i->mode)) || (S_ISBLK(le16_to_cpu(i->mode)))) { /* major/minor numbers can be as high as 2^12 or 4096 */ - snprintf(info, 10, "%4d,%4d", major(i->size), minor(i->size)); + snprintf(info, 10, "%4d,%4d", major(CRAM_SWAB_24(i->size)), + minor(CRAM_SWAB_24(i->size))); } else { /* size be as high as 2^24 or 16777216 */ - snprintf(info, 10, "%9d", i->size); + snprintf(info, 10, "%9d", CRAM_SWAB_24(i->size)); } printf("%c %04o %s %5d:%-3d %s\n", - type, i->mode & ~S_IFMT, info, i->uid, i->gid, name); + type, le16_to_cpu(i->mode) & ~S_IFMT, info, le16_to_cpu(i->uid), + i->gid, name); } /* @@ -157,8 +160,8 @@ { unsigned long offset; - offset = super->root.offset << 2; - if (super->magic != CRAMFS_MAGIC) + offset = GET_CRAM_OFFSET(&(super->root)) << 2; + if (le32_to_cpu(super->magic) != CRAMFS_MAGIC) return NULL; if (memcmp(super->signature, CRAMFS_SIGNATURE, sizeof(super->signature)) != 0) return NULL; @@ -191,22 +194,23 @@ static void change_file_status(char *path, struct cramfs_inode *i) { struct utimbuf epoch = { 0, 0 }; + unsigned short mode = le16_to_cpu(i->mode); if (euid == 0) { - if (lchown(path, i->uid, i->gid) < 0) { + if (lchown(path, le16_to_cpu(i->uid), i->gid) < 0) { perror(path); exit(8); } - if (S_ISLNK(i->mode)) + if (S_ISLNK(mode)) return; - if ((S_ISUID | S_ISGID) & i->mode) { - if (chmod(path, i->mode) < 0) { + if ((S_ISUID | S_ISGID) & mode) { + if (chmod(path, mode) < 0) { perror(path); exit(8); } } } - if (S_ISLNK(i->mode)) + if (S_ISLNK(mode)) return; if (utime(path, &epoch) < 0) { perror(path); @@ -216,9 +220,9 @@ static void do_symlink(char *path, struct cramfs_inode *i) { - unsigned long offset = i->offset << 2; + unsigned long offset = GET_CRAM_OFFSET(i) << 2; unsigned long curr = offset + 4; - unsigned long next = *(u32 *) romfs_read(offset); + unsigned long next = le32_to_cpu(*(u32 *) romfs_read(offset)); unsigned long size; if (next > end_data) { @@ -226,7 +230,7 @@ } size = uncompress_block(romfs_read(curr), next - curr); - if (size != i->size) { + if (size != CRAM_SWAB_24(i->size)) { fprintf(stderr, "%s: size error in symlink `%s'\n", filename, path); exit(4); @@ -255,21 +259,23 @@ { dev_t devtype = 0; char type; + unsigned short mode = le16_to_cpu(i->mode); - if (S_ISCHR(i->mode)) { - devtype = i->size; + if (S_ISCHR(mode)) { + devtype = CRAM_SWAB_24(i->size); type = 'c'; } - else if (S_ISBLK(i->mode)) { - devtype = i->size; + else if (S_ISBLK(mode)) { + devtype = CRAM_SWAB_24(i->size); type = 'b'; } - else if (S_ISFIFO(i->mode)) + else if (S_ISFIFO(mode)) type = 'p'; - else if (S_ISSOCK(i->mode)) + else if (S_ISSOCK(mode)) type = 's'; else { - fprintf(stderr, "%s: bogus mode on `%s' (%o)\n", filename, path, i->mode); + fprintf(stderr, "%s: bogus mode on `%s' (%o)\n", filename, + path, mode); exit(4); } @@ -278,7 +284,7 @@ } if (opt_extract) { - if (mknod(path, i->mode, devtype) < 0) { + if (mknod(path, mode, devtype) < 0) { perror(path); exit(8); } @@ -292,7 +298,7 @@ do { unsigned long out = PAGE_CACHE_SIZE; - unsigned long next = *(u32 *) romfs_read(offset); + unsigned long next = le32_to_cpu(*(u32 *) romfs_read(offset)); if (next > end_data) { end_data = next; @@ -334,9 +340,11 @@ static void expand_fs(int pathlen, char *path, struct cramfs_inode *inode) { - if (S_ISDIR(inode->mode)) { - int count = inode->size; - unsigned long offset = inode->offset << 2; + unsigned short mode = le16_to_cpu(inode->mode); + + if (S_ISDIR(mode)) { + int count = CRAM_SWAB_24(inode->size); + unsigned long offset = GET_CRAM_OFFSET(inode) << 2; char *newpath = malloc(pathlen + 256); if (count > 0 && offset < start_inode) { @@ -350,13 +358,13 @@ print_node('d', inode, path); } if (opt_extract) { - mkdir(path, inode->mode); + mkdir(path, mode); change_file_status(path, inode); } while (count > 0) { struct cramfs_inode *child = iget(offset); int size; - int newlen = child->namelen << 2; + int newlen = GET_CRAM_NAMELEN(child) << 2; size = sizeof(struct cramfs_inode) + newlen; count -= size; @@ -379,9 +387,9 @@ } return; } - if (S_ISREG(inode->mode)) { + if (S_ISREG(mode)) { int fd = 0; - unsigned long offset = inode->offset << 2; + unsigned long offset = GET_CRAM_OFFSET(inode) << 2; if (offset > 0 && offset < start_data) { start_data = offset; @@ -390,10 +398,10 @@ print_node('f', inode, path); } if (opt_extract) { - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, inode->mode); + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, mode); } - if (inode->size) { - do_uncompress(fd, offset, inode->size); + if (CRAM_SWAB_24(inode->size)) { + do_uncompress(fd, offset, CRAM_SWAB_24(inode->size)); } if (opt_extract) { close(fd); @@ -401,8 +409,8 @@ } return; } - if (S_ISLNK(inode->mode)) { - unsigned long offset = inode->offset << 2; + if (S_ISLNK(mode)) { + unsigned long offset = GET_CRAM_OFFSET(inode) << 2; if (offset < start_data) { start_data = offset; @@ -499,12 +507,12 @@ } /* XXX - this could be cleaner... */ - if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) { + if (le32_to_cpu(((struct cramfs_super *) buf)->magic) == CRAMFS_MAGIC) { start = 0; super = (struct cramfs_super *) buf; } else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) && - ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC))) + ((le32_to_cpu(((struct cramfs_super *) (buf + PAD_SIZE))->magic) == CRAMFS_MAGIC))) { start = PAD_SIZE; super = (struct cramfs_super *) (buf + PAD_SIZE); @@ -514,21 +522,22 @@ exit(4); } - if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) { + if (le32_to_cpu(super->flags) & CRAMFS_FLAG_FSID_VERSION_2) { /* length test */ - if (length < super->size) { + if (length < le32_to_cpu(super->size)) { fprintf(stderr, "%s: invalid cramfs--file length too short\n", filename); exit(4); } - else if (length > super->size) { + else if (length > le32_to_cpu(super->size)) { fprintf(stderr, "%s: warning--file length too long, padded image?\n", filename); } /* CRC test */ - crc_old = super->fsid.crc; - super->fsid.crc = crc32(0L, Z_NULL, 0); + crc_old = le32_to_cpu(super->fsid.crc); + super->fsid.crc = le32_to_cpu(crc32(0L, Z_NULL, 0)); crc_new = crc32(0L, Z_NULL, 0); - crc_new = crc32(crc_new, (unsigned char *) buf+start, super->size - start); + crc_new = crc32(crc_new, (unsigned char *) buf+start, + le32_to_cpu(super->size) - start); if (crc_new != crc_old) { fprintf(stderr, "%s: invalid cramfs--crc error\n", filename); exit(4); @@ -541,11 +550,11 @@ #ifdef INCLUDE_FS_TESTS super = (struct cramfs_super *) malloc(sizeof(struct cramfs_super)); - if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) { + if (le32_to_cpu(((struct cramfs_super *) buf)->magic) == CRAMFS_MAGIC) { memcpy(super, buf, sizeof(struct cramfs_super)); } else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) && - ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC))) + ((le32_to_cpu(((struct cramfs_super *) (buf + PAD_SIZE))->magic) == CRAMFS_MAGIC))) { memcpy(super, (buf + PAD_SIZE), sizeof(struct cramfs_super)); } @@ -576,8 +585,8 @@ fprintf(stderr, "%s: invalid cramfs--directory data end (%ld) != file data start (%ld)\n", filename, end_inode, start_data); exit(4); } - if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) { - if (end_data > super->size) { + if (le32_to_cpu(super->flags) & CRAMFS_FLAG_FSID_VERSION_2) { + if (end_data > le32_to_cpu(super->size)) { fprintf(stderr, "%s: invalid cramfs--invalid file data offset\n", filename); exit(4); } diff -urN -X dontdiff linux-2.4.17/scripts/cramfs/mkcramfs.c linux-curr/scripts/cramfs/mkcramfs.c --- linux-2.4.17/scripts/cramfs/mkcramfs.c Thu Jul 19 16:14:53 2001 +++ linux-curr/scripts/cramfs/mkcramfs.c Wed Jan 2 16:49:17 2002 @@ -32,6 +32,7 @@ #include #include #include +#include "bitopts.h" #define PAD_SIZE 512 /* only 0 and 512 supported by kernel */ @@ -317,19 +318,20 @@ offset += opt_pad; } - super->magic = CRAMFS_MAGIC; - super->flags = CRAMFS_FLAG_FSID_VERSION_2 | CRAMFS_FLAG_SORTED_DIRS; + super->magic = le32_to_cpu(CRAMFS_MAGIC); + super->flags = le32_to_cpu(CRAMFS_FLAG_FSID_VERSION_2 | + CRAMFS_FLAG_SORTED_DIRS); if (opt_holes) - super->flags |= CRAMFS_FLAG_HOLES; + super->flags |= le32_to_cpu(CRAMFS_FLAG_HOLES); if (image_length > 0) - super->flags |= CRAMFS_FLAG_SHIFTED_ROOT_OFFSET; - super->size = size; + super->flags |= le32_to_cpu(CRAMFS_FLAG_SHIFTED_ROOT_OFFSET); + super->size = le32_to_cpu(size); memcpy(super->signature, CRAMFS_SIGNATURE, sizeof(super->signature)); - super->fsid.crc = crc32(0L, Z_NULL, 0); - super->fsid.edition = opt_edition; - super->fsid.blocks = total_blocks; - super->fsid.files = total_nodes; + super->fsid.crc = le32_to_cpu(crc32(0L, Z_NULL, 0)); + super->fsid.edition = le32_to_cpu(opt_edition); + super->fsid.blocks = le32_to_cpu(total_blocks); + super->fsid.files = le32_to_cpu(total_nodes); memset(super->name, 0x00, sizeof(super->name)); if (opt_name) @@ -337,11 +339,11 @@ else strncpy(super->name, "Compressed", sizeof(super->name)); - super->root.mode = root->mode; - super->root.uid = root->uid; + super->root.mode = le16_to_cpu(root->mode); + super->root.uid = le16_to_cpu(root->uid); super->root.gid = root->gid; - super->root.size = root->size; - super->root.offset = offset >> 2; + super->root.size = CRAM_SWAB_24(root->size); + SET_CRAM_OFFSET(&(super->root), offset >> 2); return offset; } @@ -356,7 +358,7 @@ fprintf(stderr, "filesystem too big. Exiting.\n"); exit(8); } - inode->offset = (offset >> 2); + SET_CRAM_OFFSET(inode, offset >> 2); } @@ -379,10 +381,10 @@ entry->dir_offset = offset; - inode->mode = entry->mode; - inode->uid = entry->uid; + inode->mode = le16_to_cpu(entry->mode); + inode->uid = le16_to_cpu(entry->uid); inode->gid = entry->gid; - inode->size = entry->size; + inode->size = CRAM_SWAB_24(entry->size); inode->offset = 0; /* Non-empty directories, regfiles and symlinks will write over inode->offset later. */ @@ -395,7 +397,7 @@ *(base + offset + len) = '\0'; len++; } - inode->namelen = len >> 2; + SET_CRAM_NAMELEN(inode, len >> 2); offset += len; /* TODO: this may get it wrong for chars >= 0x80. @@ -503,7 +505,7 @@ exit(8); } - *(u32 *) (base + offset) = curr; + *(u32 *) (base + offset) = le32_to_cpu(curr); offset += 4; } while (size); @@ -652,6 +654,10 @@ exit(16); } fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) { + perror(outfile); + exit(8); + } root_entry = calloc(1, sizeof(struct entry)); if (!root_entry) { @@ -725,7 +731,8 @@ /* Put the checksum in. */ crc = crc32(crc, (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 = + le32_to_cpu(crc); printf("CRC: %x\n", crc); /* Check to make sure we allocated enough space. */