The following patchset enables cramfs to mount images that were
created on a machine whose endianness differs from the mounting
machine's one.Tested on an i386 box.
A discussion about this feature can be found here:
http://marc.info/?l=linux-fsdevel&m=119438573309330&w=2
Andi
-
I checked everything twice, except the patch numbers.
Sorry about that.The right version of the patchset should look like this:
[PATCH 1/2] cramfs: Add mount option "swapendian"
[PATCH 2/2] cramfs: update README fileAndi
-
This patch updates the readme file according to the
new mount option "swapendian".Signed-off-by: Andi Drebes <andi@programmierforen.de>
---
fs/cramfs/README | 21 +++++++++------------
1 files changed, 9 insertions(+), 12 deletions(-)diff --git a/fs/cramfs/README b/fs/cramfs/README
index 445d1c2..acbbdc4 100644
--- a/fs/cramfs/README
+++ b/fs/cramfs/README
@@ -1,3 +1,12 @@
+Mount options
+-------------
+
+Currently, there is only one mount option available for cramfs:
+
+swapendian:
+ causes the filesystem's metadata to be converted from
+ non-host-endianness to host-endianness.
+
Notes on Filesystem Layout
--------------------------@@ -108,18 +117,6 @@ kernels, not even necessarily kernels of the same architecture if
PAGE_CACHE_SIZE is subject to change between kernel versions
(currently possible with arm and ia64).-The remaining options try to make cramfs more sharable.
-
-One part of that is addressing endianness. The two options here are
-`always use little-endian' (like ext2fs) or `writer chooses
-endianness; kernel adapts at runtime'. Little-endian wins because of
-code simplicity and little CPU overhead even on big-endian machines.
-
-The cost of swabbing is changing the code to use the le32_to_cpu
-etc. macros as used by ext2fs. We don't need to swab the compressed
-data, only the superblock, inodes and block pointers.
-
-
The other part of making cramfs more sharable is choosing a block
size. The options are:-
This patch introduces the mount option "swapendian" for cramfs.
When this option is set, cramfs is able to mount an image that
was created on a machine whose endianness differs from the mounting
machine's one.
If somebody tries to mount an image with another endianness but
forgets to set this option, cramfs will give a hint for it.Signed-off-by: Andi Drebes <andi@programmierforen.de>
---
fs/cramfs/inode.c | 112 +++++++++++++++++++++++++++++++----------
include/linux/cramfs_endian.h | 58 +++++++++++++++++++++
include/linux/cramfs_fs_sb.h | 1 +
3 files changed, 144 insertions(+), 27 deletions(-)diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 350680f..8da03b0 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>
+ * Added mount option "swapendian"
*//*
@@ -18,6 +22,7 @@
#include <linux/string.h>
#include <linux/blkdev.h>
#include <linux/cramfs_fs.h>
+#include <linux/cramfs_endian.h>
#include <linux/slab.h>
#include <linux/cramfs_fs_sb.h>
#include <linux/buffer_head.h>
@@ -157,19 +162,24 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
blocknr = offset >> PAGE_CACHE_SHIFT;
offset &= PAGE_CACHE_SIZE - 1;- /* Check if an existing buffer already has the data.. */
- for (i = 0; i < READ_BUFFERS; i++) {
- unsigned int blk_offset;
-
- if (buffer_dev[i] != sb)
- continue;
- if (blocknr < buffer_blocknr[i])
- continue;
- blk_offset = (blocknr - buffer_blocknr[i]) << PAGE_CACHE_SHIFT;
- blk_offset += offset;
- if (blk_offset + len > BUFFER_SIZE)
- continue;
- return read_buffers[i] + blk_offset;
+ /* Caching is disabled if the filesystem's
+ and the machine's endianness differ. */
+ if(likely(CRAMFS_SB(sb)->endian))
...
Codingstyle: extra space after "if", keep brace on the same line.
Same goes for most of this patch.Unlikely not likely to be a good idea. It clutters up the code for a
minimal gain on host-endian filesystems (and I doubt you can measure
that even in micro-benchmarks) and forcibly mispredicts every branch for
cross-endian filesystems.The name "endian" could be replaces with something more descriptive.
You could remove most of this by removing the mount option and simply
You're using Xe32_to_cpu on host-endian numbers? Sparse won't be happy.
Better make it a static inline function for type safety. Possibly even
dito.
Jörn
--
The rabbit runs faster than the fox, because the rabbit is rinning for
his life while the fox is only running for his dinner.
-- Aesop
-
Please don't do it this way.
It would be *much* better to just standardize on one endianness, and be
done with it. That way there are no config options, no confusion, and the
code is smaller, simpler, and faster. Because nn unconditional byte swap
is generally faster than a conditional non-byte-swap!So can you please just make it little-endian?
There can't be that many big-endian machines that really care about old
cramfs images..Linus
-
This is a valid objection. The problem is that the endianness for cramfs
has never been standardized. Now there are filesystem images in both little
and big endian out there. I encountered this problem first when I tried to
mount my router's initrd. Yes, I know, I could have converted the image into
little endian. I just find that it is more consistent to support both kinds
Actually, in my eyes, it would be better to create a new version of cramfs
that standardizes the endianness and the block size. But that doesn't solve
s.a. (There's at least one...)Andi
-
Perhaps even more importantly, you can do a much better job.
The thing is, when I did cramfs originally, I had a total "senior moment",
and the reason I didn't compress the metadata was that it appeared hard to
do and fill it in later (ie compressing the metadata would mean that the
location of the data changes - and since the metadata obviously contains
pointers to the data, there's a chicken-and-egg problem there).But it should be *trivial* to compress the metadata too if the code just
were to put the metadata at the beginning of the image, and the real data
at the end, and then you can build up the image from both ends and you
*can* have a fixed starting point for the data (up at the top of the
image) even though you are changing the size of the metadata by
compression.But I literally designed and wrote the thing in a couple of days, and I
really didn't think it through right. As a result, the metadata may be
dense, but it's totally uncompressed. It would have been better to allow a
less dense basic format (allowing bigger uid/gid values, and offsets and
file sizes), but compress it.So a "v2" cramfs would be a great idea. Not just for fixing endianness
etc.Linus
-
I decided to compress the metadata when I designed Squashfs, a read-only
filesystem which was inspired by Cramfs. Squashfs stores the data at the
front of the filesystem and puts the metadata at the end, so the data is
always at a fixed point. Doing that and a couple of other things allows
the metadata to be built up and compressed in one-pass while the
filesystem is being created. The metadata is split into an inode table
and a directory table and compressed separately because it compressesSquashfs stores much more metadata information, but as it is compressed
it is much smaller than Cramfs. Typically the inode table compressesThat is what I always considered Squashfs to be. But I also made the
mistake of making Squashfs both little and big endian. That's going to
be fixed and then I'll make a second attempt at submitting it for
inclusion in the mainline kernel.Phillip
-
I didn't have a closer look on squashfs, but I am going to have it this weekend.
So far, it seems as if no "cramfs v2" is needed. My proposal is the following:I'll write a new patch for inclusion in the mainline kernel that makes cramfs
"little endian only". For people who really want to be able to mount filesystems
with both kinds of endianness there will be a seperate patch (not intended to be
merged into mainline) available somewhere on the net (my website or so). It will
definitely be marked as non-official in order to prevent people from creating
images in big endian. Officially, cramfs should only support little endian images.
If squashfs will be merged, cramfs should be marked as obsolete.Andi
-
Good. We do actually have precedence for exactly this kind of situation
before: it's what happened to ext2 as well (people were trying to push a
switch-endian version, and I said no) and the m68k people had their own
patches for a while but we're *so* much better off from being fixed-endianSounds like that, yes.
Linus
-
Actually there are as lots of initrd are cramfs. This means you'd need
to update mkcramfs all big endian machines out there.
-
So? Normally the initrd goes with the kernel anyway.
Linus
-
.. it's also statically checkable with tools like "sparse", so it avoids
bugs not only by being simpler, but by simply being fundamentally more
robust to start with.Linus
-
We can do proper typechecking with sparse even for dual-endian filesystems,
see ufs and sysvfs for example. And yes, for a new filesystems I'd always
chose one endianes and stick to it, but becase I certain someone forgot
that when creating cramfs we're stuck now :)
-
| Ingo Molnar | [patch 12/13] syslets: x86: optimized copy_uatom() |
| Greg Kroah-Hartman | [PATCH 017/196] aoechr: Convert from class_device to device |
| Yinghai Lu | Re: 2.6.26, PAT and AMD family 6 |
| Jan Engelhardt | intel iommu (Re: -mm merge plans for 2.6.23) |
git: | |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
| David Miller | [GIT]: Networking |
| David Miller | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Natalie Protasevich | [BUG] New Kernel Bugs |
