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 */
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).