All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andi Drebes <lists-receive@programmierforen.de>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jeff Garzik <jeff@garzik.org>, J?rn Engel <joern@logfs.org>,
	linux-fsdevel@vger.kernel.org, Karel Zak <kzak@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Christoph Hellwig <hch@infradead.org>,
	Phillip Lougher <phillip@lougher.demon.co.uk>
Subject: Re: [PATCH 1/2] Make cramfs little endian only
Date: Thu, 6 Dec 2007 23:37:32 +0100	[thread overview]
Message-ID: <200712062337.32854.lists-receive@programmierforen.de> (raw)
In-Reply-To: <alpine.LFD.0.9999.0712060926160.13796@woody.linux-foundation.org>

> But then you just make sure that the little-endian bits are the same, and 
> now you're *done*.
Yes, you're perfectly right. Sorry for not getting it. I hope the next
time I will understand faster.

> > For little endian machines, the data arranged in the following way:
> > 
> > |o02.o01.n06.n05.n04.n03.n02.n01|o10.o09.o08.o07.o06.o05.o04.o03|
> > |o18.o17.o16.o15.o14.o13.o12.o11|o26.o25.o24.o23.o22.o21.o20.o19| 
> 
> That's a singularly confused way or looking at it. 
Yep. I saw everything with big-endian eyes and confused myself.
Shouldn't have happened.

> Yes it does. Try it.
I tried it. It does it. Here's the new patch (hopefully the last one
for this issue)...

Checked with sparse using C=2 and CF="-D__CHECK_ENDIAN__".
Tested on an i386 box.
Tested on an Ultrasparc IIi box.

Signed-off-by: Andi Drebes <andi@programmierforen.de>
---
 fs/cramfs/inode.c         |  119 ++++++++++++++++++++++++++++++---------------
 include/linux/cramfs_fs.h |   22 ++++----
 2 files changed, 91 insertions(+), 50 deletions(-)

diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 350680f..30dc640 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -4,6 +4,10 @@
  * Copyright (C) 1999 Linus Torvalds.
  *
  * This file is released under the GPL.
+ *
+ * Changelog:
+ *	11/07 - Andi Drebes <andi@programmierforen.de>
+ *	Made cramfs little endian only.
  */
 
 /*
@@ -34,13 +38,46 @@ static const struct address_space_operations cramfs_aops;
 
 static DEFINE_MUTEX(read_mutex);
 
+#define CRAMFS_NAMELEN_MASK ((1ul << CRAMFS_NAMELEN_WIDTH)-1)
+#define CRAMFS_MODE_MASK ((1ul << CRAMFS_MODE_WIDTH)-1)
+#define CRAMFS_SIZE_MASK ((1ul << CRAMFS_SIZE_WIDTH)-1)
+
+static inline u32 cramfs_mode(struct cramfs_inode *inode)
+{
+	return le32_to_cpu(inode->mode_uid) & CRAMFS_MODE_MASK;
+}
+
+static inline u32 cramfs_uid(struct cramfs_inode *inode)
+{
+	return le32_to_cpu(inode->mode_uid) >> CRAMFS_MODE_WIDTH;
+}
+
+static inline u32 cramfs_size(struct cramfs_inode *inode)
+{
+	return le32_to_cpu(inode->size_gid) & CRAMFS_SIZE_MASK;
+}
+
+static inline u32 cramfs_gid(struct cramfs_inode *inode)
+{
+	return le32_to_cpu(inode->size_gid) >> CRAMFS_SIZE_WIDTH;
+}
+
+static inline u32 cramfs_offset(struct cramfs_inode *inode)
+{
+	return le32_to_cpu(inode->namelen_offset) >> CRAMFS_NAMELEN_WIDTH;
+}
+
+static inline u32 cramfs_namelen(struct cramfs_inode *inode)
+{
+	return le32_to_cpu(inode->namelen_offset) & CRAMFS_NAMELEN_MASK;
+}
 
 /* These two macros may change in future, to provide better st_ino
    semantics. */
-#define CRAMINO(x)	(((x)->offset && (x)->size)?(x)->offset<<2:1)
+#define CRAMINO(x)	((cramfs_offset(x) && cramfs_size(x)) ? \
+			 cramfs_offset(x) << 2 : 1)
 #define OFFSET(x)	((x)->i_ino)
 
-
 static int cramfs_iget5_test(struct inode *inode, void *opaque)
 {
 	struct cramfs_inode *cramfs_inode = opaque;
@@ -53,13 +90,13 @@ static int cramfs_iget5_test(struct inode *inode, void *opaque)
 
 	/* all empty directories, char, block, pipe, and sock, share inode #1 */
 
-	if ((inode->i_mode != cramfs_inode->mode) ||
-	    (inode->i_gid != cramfs_inode->gid) ||
-	    (inode->i_uid != cramfs_inode->uid))
+	if ((inode->i_mode != cramfs_mode(cramfs_inode)) ||
+	    (inode->i_gid != cramfs_gid(cramfs_inode)) ||
+	    (inode->i_uid != cramfs_uid(cramfs_inode)))
 		return 0; /* does not match */
 
 	if ((S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) &&
-	    (inode->i_rdev != old_decode_dev(cramfs_inode->size)))
+	    (inode->i_rdev != old_decode_dev(cramfs_size(cramfs_inode))))
 		return 0; /* does not match */
 
 	return 1; /* matches */
@@ -69,11 +106,11 @@ static int cramfs_iget5_set(struct inode *inode, void *opaque)
 {
 	static struct timespec zerotime;
 	struct cramfs_inode *cramfs_inode = opaque;
-	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_gid = cramfs_inode->gid;
+	inode->i_mode = cramfs_mode(cramfs_inode);
+	inode->i_uid = cramfs_uid(cramfs_inode);
+	inode->i_size = cramfs_size(cramfs_inode);
+	inode->i_blocks = (cramfs_size(cramfs_inode) - 1) / 512 + 1;
+	inode->i_gid = cramfs_gid(cramfs_inode);
 	/* Struct copy intentional */
 	inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime;
 	inode->i_ino = CRAMINO(cramfs_inode);
@@ -94,7 +131,7 @@ static int cramfs_iget5_set(struct inode *inode, void *opaque)
 		inode->i_size = 0;
 		inode->i_blocks = 0;
 		init_special_inode(inode, inode->i_mode,
-			old_decode_dev(cramfs_inode->size));
+			old_decode_dev(cramfs_size(cramfs_inode)));
 	}
 	return 0;
 }
@@ -256,53 +293,57 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
 	mutex_unlock(&read_mutex);
 
 	/* Do sanity checks on the superblock */
-	if (super.magic != CRAMFS_MAGIC) {
-		/* check for wrong endianess */
-		if (super.magic == CRAMFS_MAGIC_WEND) {
-			if (!silent)
-				printk(KERN_ERR "cramfs: wrong endianess\n");
-			goto out;
-		}
-
+	if (le32_to_cpu(super.magic) != CRAMFS_MAGIC &&
+	    le32_to_cpu(super.magic) != CRAMFS_MAGIC_WEND) {
 		/* check at 512 byte offset */
 		mutex_lock(&read_mutex);
 		memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super));
 		mutex_unlock(&read_mutex);
-		if (super.magic != CRAMFS_MAGIC) {
-			if (super.magic == CRAMFS_MAGIC_WEND && !silent)
-				printk(KERN_ERR "cramfs: wrong endianess\n");
-			else if (!silent)
+
+		if (le32_to_cpu(super.magic) == CRAMFS_MAGIC_WEND)
+			goto other_endian;
+		else if (le32_to_cpu(super.magic) != CRAMFS_MAGIC) {
+			if (!silent)
 				printk(KERN_ERR "cramfs: wrong magic\n");
+
 			goto out;
 		}
 	}
+	/* check for wrong endianess */
+	else if (le32_to_cpu(super.magic) == CRAMFS_MAGIC_WEND) {
+other_endian:
+		if (!silent)
+			printk(KERN_ERR "cramfs: filesystems in big endian format are not supported any longer.\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(cramfs_mode(&super.root))) {
 		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) {
-		sbi->size=super.size;
-		sbi->blocks=super.fsid.blocks;
-		sbi->files=super.fsid.files;
+	root_offset = cramfs_offset(&super.root) << 2;
+	if (__le32_to_cpu(super.flags) & CRAMFS_FLAG_FSID_VERSION_2) {
+		sbi->size = le32_to_cpu(super.size);
+		sbi->blocks = le32_to_cpu(super.fsid.blocks);
+		sbi->files = le32_to_cpu(super.fsid.files);
 	} else {
 		sbi->size=1<<28;
 		sbi->blocks=0;
 		sbi->files=0;
 	}
-	sbi->magic=super.magic;
-	sbi->flags=super.flags;
+	sbi->magic = le32_to_cpu(super.magic);
+	sbi->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) &&
+	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))))
 	{
@@ -383,10 +424,10 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 		 * and the name padded out to 4-byte boundaries
 		 * with zeroes.
 		 */
-		namelen = de->namelen << 2;
+		namelen = cramfs_namelen(de) << 2;
 		memcpy(buf, name, namelen);
 		ino = CRAMINO(de);
-		mode = de->mode;
+		mode = cramfs_mode(de);
 		mutex_unlock(&read_mutex);
 		nextoffset = offset + sizeof(*de) + namelen;
 		for (;;) {
@@ -432,7 +473,7 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s
 		if (sorted && (dentry->d_name.name[0] < name[0]))
 			break;
 
-		namelen = de->namelen << 2;
+		namelen = cramfs_namelen(de) << 2;
 		offset += sizeof(*de) + namelen;
 
 		/* Quick check that the name is roughly the right length */
@@ -484,8 +525,8 @@ static int cramfs_readpage(struct file *file, struct page * page)
 		start_offset = OFFSET(inode) + maxblock*4;
 		mutex_lock(&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(*(__le32 *) cramfs_read(sb, blkptr_offset-4, 4));
+		compr_len = le32_to_cpu(*(__le32 *) cramfs_read(sb, blkptr_offset, 4)) - start_offset;
 		mutex_unlock(&read_mutex);
 		pgdata = kmap(page);
 		if (compr_len == 0)
diff --git a/include/linux/cramfs_fs.h b/include/linux/cramfs_fs.h
index 3be4e5a..66aba06 100644
--- a/include/linux/cramfs_fs.h
+++ b/include/linux/cramfs_fs.h
@@ -28,9 +28,9 @@
  * Reasonably terse representation of the inode data.
  */
 struct cramfs_inode {
-	__u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH;
+	__le32 mode_uid;
 	/* SIZE for device files is i_rdev */
-	__u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH;
+	__le32 size_gid;
 	/* NAMELEN is the length of the file name, divided by 4 and
            rounded up.  (cramfs doesn't support hard links.) */
 	/* OFFSET: For symlinks and non-empty regular files, this
@@ -39,24 +39,24 @@ struct cramfs_inode {
 	   see README).  For non-empty directories it is the offset
 	   (divided by 4) of the inode of the first file in that
 	   directory.  For anything else, offset is zero. */
-	__u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH;
+	__le32 namelen_offset;
 };
 
 struct cramfs_info {
-	__u32 crc;
-	__u32 edition;
-	__u32 blocks;
-	__u32 files;
+	__le32 crc;
+	__le32 edition;
+	__le32 blocks;
+	__le32 files;
 };
 
 /*
  * Superblock information at the beginning of the FS.
  */
 struct cramfs_super {
-	__u32 magic;			/* 0x28cd3d45 - random number */
-	__u32 size;			/* length in bytes */
-	__u32 flags;			/* feature flags */
-	__u32 future;			/* reserved for future use */
+	__le32 magic;			/* 0x28cd3d45 - random number */
+	__le32 size;			/* length in bytes */
+	__le32 flags;			/* feature flags */
+	__le32 future;			/* reserved for future use */
 	__u8 signature[16];		/* "Compressed ROMFS" */
 	struct cramfs_info fsid;	/* unique filesystem info */
 	__u8 name[16];			/* user-defined name */

  reply	other threads:[~2007-12-06 22:37 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-04 11:59 [PATCH 0/2] Make cramfs little endian only Andi Drebes
2007-12-04 12:01 ` [PATCH 1/2] " Andi Drebes
2007-12-04 15:34   ` Jörn Engel
2007-12-04 20:37     ` Andi Drebes
2007-12-04 20:58       ` Linus Torvalds
2007-12-04 21:31         ` Andi Drebes
2007-12-04 22:35           ` Linus Torvalds
2007-12-04 22:58             ` Jeff Garzik
2007-12-05 21:57               ` Andi Drebes
2007-12-05 22:21                 ` Linus Torvalds
2007-12-05 22:41                   ` Jörn Engel
2007-12-06 16:38                     ` Andi Drebes
2007-12-06 16:27                   ` Andi Drebes
2007-12-06 16:47                     ` Jörn Engel
2007-12-06 17:35                       ` Linus Torvalds
2007-12-06 17:31                     ` Linus Torvalds
2007-12-06 22:37                       ` Andi Drebes [this message]
2007-12-04 20:11   ` Andrew Morton
2007-12-04 20:58     ` Andi Drebes
2007-12-04 12:02 ` [PATCH 2/2] Update documentation Andi Drebes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200712062337.32854.lists-receive@programmierforen.de \
    --to=lists-receive@programmierforen.de \
    --cc=akpm@linux-foundation.org \
    --cc=hch@infradead.org \
    --cc=jeff@garzik.org \
    --cc=joern@logfs.org \
    --cc=kzak@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=phillip@lougher.demon.co.uk \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.