On Thu, 15 November 2007 21:35:16 +0100, Andi Drebes wrote:
> +     /* 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.
"host_endian" or "swap_endian" with reversed logic or something.

> +     /* check for wrong endianess */
> +     else if (super.magic == CRAMFS_MAGIC_WEND)
> +     {
> +other_endian:
> +             if (sbi->endian) {
> +                     if (!silent) {
> +                             printk(KERN_ERR "cramfs: it seems as if you 
> were trying to mount a filesystem "
> +                                     "whose endianness does not match the 
> host's one. You might want to try "
> +                                     "the option \"swapendian\" when 
> mounting the filesystem.\n");
> +                             printk(KERN_ERR "cramfs: the filesystem will 
> not be mounted.\n");
> +                     }
> +                     goto out;
> +             }
> +             else {
> +                     if (!sbi->endian) {
> +                             if (!silent)
> +                                     printk(KERN_INFO "cramfs: mounting 
> cramfs with another endianness\n");
> +                             CRAMFS_CONVERT_SUPER(super);
> +                     }
> +             }
> +     }
> +     else if (super.magic == CRAMFS_MAGIC && !sbi->endian)
> +     {
> +             printk(KERN_ERR "cramfs: you are trying to mount a filesystem 
> whose endianness matches the "
> +                     "host's one. Do not use the option \"swapendian\".\n");
> +             goto out;
> +     }

You could remove most of this by removing the mount option and simply
deciding endianness based on super.magic.  So why the extra work?

> @@ -483,9 +532,18 @@ static int cramfs_readpage(struct file *file, struct 
> page * page)
>  
>               start_offset = OFFSET(inode) + maxblock*4;
>               mutex_lock(&read_mutex);
> -             if (page->index)
> +             if (page->index) {
>                       start_offset = *(u32 *) cramfs_read(sb, 
> blkptr_offset-4, 4);
> -             compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - 
> start_offset);
> +
> +                     if(unlikely(!endian))
> +                             start_offset = CPU_ENDIAN_32(start_offset);
> +             }
> +
> +             if(unlikely(!endian))
> +                     compr_len = CPU_ENDIAN_32(*(u32 *) cramfs_read(sb, 
> blkptr_offset, 4)) - start_offset;
> +             else
> +                     compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) 
> - start_offset);

The two conditional can be combined into one.

> diff --git a/include/linux/cramfs_endian.h b/include/linux/cramfs_endian.h
> new file mode 100644
> index 0000000..9b90b26
> --- /dev/null
> +++ b/include/linux/cramfs_endian.h
> @@ -0,0 +1,58 @@
> +/*
> + * cramfs_endian.h provides definitions used when mounting
> + * a cram filesystem whose endianness doesn't match the host's
> + * one.
> + *
> + * Copyright 2007 (C) Andi Drebes <[EMAIL PROTECTED]>
> + *
> + * This file is released under the GPLv2.
> + */
> +
> +#ifndef __CRAMFS_ENDIAN_H
> +#define __CRAMFS_ENDIAN_H
> +
> +#ifdef __LITTLE_ENDIAN
> +     #define CPU_ENDIAN_32(x) (be32_to_cpu(x))
> +     #define CPU_ENDIAN_16(x) (be16_to_cpu(x))
> +#elif defined __BIG_ENDIAN
> +     #define CPU_ENDIAN_32(x) (le32_to_cpu(x))
> +     #define CPU_ENDIAN_16(x) (le16_to_cpu(x))
> +#else
> +     #error "Neither __LITTLE_ENDIAN nor __BIG_ENDIAN is defined!"
> +#endif

You're using Xe32_to_cpu on host-endian numbers?  Sparse won't be happy.
Better just use swab32 directly.

> +
> +/* Converts a cramfs_info from the wrong endianess
> +   to host endianess. */
> +#define CRAMFS_CONVERT_INFO(info) \
> +     do { \
> +             (info).crc = CPU_ENDIAN_32((info).crc); \
> +             (info).edition = CPU_ENDIAN_32((info).edition); \
> +             (info).blocks = CPU_ENDIAN_32((info).blocks); \
> +             (info).files = CPU_ENDIAN_32((info).files); \
> +     } while(0)

Better make it a static inline function for type safety.  Possibly even
an out-of-line function.

> +/* Converts a cramfs_info from the wrong endianess
> +   to host endianess. */
> +#define CRAMFS_CONVERT_INODE(inode) \
> +     do { \
> +             __u8* ptr = (__u8*)(inode);\
> +             (inode)->mode = CPU_ENDIAN_16((inode)->mode); \
> +             (inode)->uid = CPU_ENDIAN_16((inode)->uid); \
> +             (inode)->size = (ptr[4] << 16) | (ptr[5] << 8) | (ptr[6]) ; \
> +             (inode)->offset = ((ptr[8] & 0x03) << 24) | (ptr[9] << 16) | 
> (ptr[10] << 8) | ptr[11]; \
> +             (inode)->namelen = (ptr[8] & 0x3f) >> 2; \
> +     } while(0)
> +
> +/* Converts a cramfs superblock from the wrong endianess
> +   to host endianess. */
> +#define CRAMFS_CONVERT_SUPER(super) \
> +     do { \
> +             (super).magic = CPU_ENDIAN_32((super).magic); \
> +             (super).size = CPU_ENDIAN_32((super).size); \
> +             (super).flags = CPU_ENDIAN_32((super).flags); \
> +             (super).future = CPU_ENDIAN_32((super).future); \
> +             CRAMFS_CONVERT_INFO((super).fsid); \
> +             CRAMFS_CONVERT_INODE(&(super).root); \
> +     } while(0)

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
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to