Skip to contentSkip to conversation

pramfs: headers

PATCH Superseded Marco Stornelli 3 participants 9 messages Nov 6, 2010 – Nov 10, 2010 VFS

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 8/16 pramfs: headers

From: Marco Stornelli <[email protected]>

Definitions for the PRAMFS filesystem.

---

fs/pramfs/pram.h +317 -0
diff -Nurp linux-2.6.36-orig/fs/pramfs/pram.h linux-2.6.36/fs/pramfs/pram.h
@@ -0,0 +1,317 @@
+/*
+ * FILE NAME pram.h
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Definitions for the PRAMFS filesystem.
+ *
+ * Copyright 2009-2010 Marco Stornelli <[email protected]>
+ * Copyright 2003 Sony Corporation
+ * Copyright 2003 Matsushita Electric Industrial Co., Ltd.
+ * 2003-2004 (c) MontaVista Software, Inc. , Steve Longerbeam
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef __PRAM_H
+#define __PRAM_H
+
+#include <linux/buffer_head.h>
+#include <linux/pram_fs.h>
+#include <linux/pram_fs_sb.h>
+#include <linux/crc16.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+/*
+ * Debug code
+ */
+#define pram_dbg(s, args...)	pr_debug("PRAMFS: "s, ## args)
+#define pram_err(s, args...)	pr_err("PRAMFS: "s, ## args)
+#define pram_warn(s, args...)	pr_warning("PRAMFS: "s, ## args)
+#define pram_info(s, args...)	pr_info("PRAMFS: "s, ## args)
+
+/* Function Prototypes */
+
+#ifdef CONFIG_PRAMFS_XIP
+
+#define pram_read	xip_file_read
+#define pram_write	xip_file_write
+#define pram_mmap	xip_file_mmap
+#define pram_aio_read	NULL
+#define pram_aio_write	NULL
+#define pram_readpage	NULL
+#define pram_direct_IO	NULL
+
+#else
+
+#define pram_read	do_sync_read
+#define pram_write	do_sync_write
+#define pram_mmap	__pram_mmap
+#define pram_aio_read	generic_file_aio_read
+#define pram_aio_write	generic_file_aio_write
+#define pram_direct_IO	__pram_direct_IO
+#define pram_readpage	__pram_readpage
+
+extern int pram_get_and_update_block(struct inode *inode, sector_t iblock,
+				     struct buffer_head *bh, int create);
+
+static inline int __pram_readpage(struct file *file, struct page *page)
+{
+	return block_read_full_page(page, pram_get_and_update_block);
+}
+
+/* file.c */
+extern ssize_t __pram_direct_IO(int rw, struct kiocb *iocb,
+			  const struct iovec *iov,
+			  loff_t offset, unsigned long nr_segs);
+
+
+#endif /* CONFIG_PRAMFS_XIP */
+
+#define pram_set_bit			ext2_set_bit
+#define pram_clear_bit			ext2_clear_bit
+#define pram_find_next_zero_bit		ext2_find_next_zero_bit
+
+/* balloc.c */
+extern void pram_init_bitmap(struct super_block *sb);
+extern void pram_free_block(struct super_block *sb, unsigned long blocknr);
+extern int pram_new_block(struct super_block *sb, unsigned long *blocknr, int zero);
+extern unsigned long pram_count_free_blocks(struct super_block *sb);
+
+/* dir.c */
+extern int pram_add_link(struct dentry *dentry, struct inode *inode);
+extern int pram_remove_link(struct inode *inode);
+
+/* namei.c */
+extern struct dentry *pram_get_parent(struct dentry *child);
+
+/* inode.c */
+extern int pram_alloc_blocks(struct inode *inode, int file_blocknr, int num);
+extern u64 pram_find_data_block(struct inode *inode,
+					 int file_blocknr);
+
+extern struct inode *pram_iget(struct super_block *sb, unsigned long ino);
+extern void pram_put_inode(struct inode *inode);
+extern void pram_evict_inode(struct inode *inode);
+extern struct inode *pram_new_inode(struct inode *dir, int mode);
+extern int pram_update_inode(struct inode *inode);
+extern int pram_write_inode(struct inode *inode, struct writeback_control *wbc);
+extern void pram_dirty_inode(struct inode *inode);
+extern int pram_notify_change(struct dentry *dentry, struct iattr *attr);
+
+
+/* super.c */
+#ifdef CONFIG_PRAMFS_TEST
+extern struct pram_super_block *get_pram_super(void);
+#endif
+extern struct super_block *pram_read_super(struct super_block *sb,
+					      void *data,
+					      int silent);
+extern int pram_statfs(struct dentry *d, struct kstatfs *buf);
+extern int pram_remount(struct super_block *sb, int *flags, char *data);
+
+/* symlink.c */
+extern int pram_block_symlink(struct inode *inode,
+			       const char *symname, int len);
+
+
+#ifdef CONFIG_PRAMFS_WRITE_PROTECT
+extern void pram_writeable(void *vaddr, unsigned long size, int rw);
+
+#define wrprotect(addr, size) pram_writeable(addr, size, 0)
+
+#else
+
+#define wrprotect(addr, size) do {} while (0)
+
+#endif /* CONFIG PRAMFS_WRITE_PROTECT */
+
+/* Inline functions start here */
+
+static inline int pram_calc_checksum(u8 *data, int n)
+{
+	u16 crc = 0;
+	crc = crc16(~0, (__u8 *)data + sizeof(__be16), n - sizeof(__be16));
+	if (*((__be16 *)data) == cpu_to_be16(crc))
+		return 0;
+	else
+		return 1;
+}
+
+/* If this is part of a read-modify-write of the super block,
+   pram_memunlock_super() before calling! */
+static inline struct pram_super_block *
+pram_get_super(struct super_block *sb)
+{
+	struct pram_sb_info *sbi = (struct pram_sb_info *)sb->s_fs_info;
+	return (struct pram_super_block *)sbi->virt_addr;
+}
+
+static inline struct pram_super_block *
+pram_get_redund_super(struct super_block *sb)
+{
+	struct pram_sb_info *sbi = (struct pram_sb_info *)sb->s_fs_info;
+	return (struct pram_super_block *)(sbi->virt_addr + PRAM_SB_SIZE);
+}
+
+/* pram_memunlock_super() before calling! */
+static inline void pram_sync_super(struct pram_super_block *ps)
+{
+	u16 crc = 0;
+	ps->s_wtime = cpu_to_be32(get_seconds());
+	ps->s_sum = 0;
+	crc = crc16(~0, (__u8 *)ps + sizeof(__be16), PRAM_SB_SIZE - sizeof(__be16));
+	ps->s_sum = cpu_to_be16(crc);
+	/* Keep sync redundant super block */
+	memcpy((void *)ps + PRAM_SB_SIZE, (void *)ps, PRAM_SB_SIZE);
+}
+
+/* pram_memunlock_inode() before calling! */
+static inline void pram_sync_inode(struct pram_inode *pi)
+{
+	u16 crc = 0;
+	pi->i_sum = 0;
+	crc = crc16(~0, (__u8 *)pi + sizeof(__be16), PRAM_INODE_SIZE - sizeof(__be16));
+	pi->i_sum = cpu_to_be16(crc);
+}
+
+#ifdef CONFIG_PRAMFS_WRITE_PROTECT
+static inline void pram_memunlock_range(void *p, unsigned long len)
+{
+#ifndef CONFIG_X86
+	local_irq_disable();
+#endif
+	preempt_disable();
+	pram_writeable(p, len, 1);
+}
+
+static inline void pram_memlock_range(void *p, unsigned long len)
+{
+	pram_writeable(p, len, 0);
+	preempt_enable();
+#ifndef CONFIG_X86
+	local_irq_enable();
+#endif
+}
+#else
+static inline void pram_memunlock_range(void *p, unsigned long len) {}
+static inline void pram_memlock_range(void *p, unsigned long len) {}
+#endif
+
+/* write protection for super block */
+#define pram_memunlock_super(ps) \
+	pram_memunlock_range((ps), PRAM_SB_SIZE)
+#define pram_memlock_super(ps) {\
+	pram_sync_super(ps);\
+	pram_memlock_range((ps), PRAM_SB_SIZE);\
+}
+
+/* write protection for inode metadata */
+#define pram_memunlock_inode(pi) \
+	pram_memunlock_range((pi), PRAM_INODE_SIZE)
+#define pram_memlock_inode(pi) {\
+	pram_sync_inode(pi);\
+	pram_memlock_range((pi), PRAM_INODE_SIZE);\
+}
+
+/* write protection for a data block */
+#define pram_memunlock_block(sb, bp) \
+	pram_memunlock_range((bp), (sb)->s_blocksize)
+#define pram_memlock_block(sb, bp) \
+	pram_memlock_range((bp), (sb)->s_blocksize)
+
+static inline void *
+pram_get_bitmap(struct super_block *sb)
+{
+	struct pram_super_block *ps = pram_get_super(sb);
+	return (void *)ps + be64_to_cpu(ps->s_bitmap_start);
+}
+
+/* If this is part of a read-modify-write of the inode metadata,
+   pram_memunlock_inode() before calling! */
+static inline struct pram_inode *
+pram_get_inode(struct super_block *sb, u64 ino)
+{
+	struct pram_super_block *ps = pram_get_super(sb);
+	return ino ? (struct pram_inode *)((void *)ps + ino) : NULL;
+}
+
+static inline ino_t
+pram_get_inodenr(struct super_block *sb, struct pram_inode *pi)
+{
+	struct pram_super_block *ps = pram_get_super(sb);
+	return (ino_t)((unsigned long)pi - (unsigned long)ps);
+}
+
+static inline u64
+pram_get_block_off(struct super_block *sb, unsigned long blocknr)
+{
+	struct pram_super_block *ps = pram_get_super(sb);
+	return (u64)(be64_to_cpu(ps->s_bitmap_start) +
+			     (blocknr << sb->s_blocksize_bits));
+}
+
+static inline unsigned long
+pram_get_blocknr(struct super_block *sb, u64 block)
+{
+	struct pram_super_block *ps = pram_get_super(sb);
+	return (block - be64_to_cpu(ps->s_bitmap_start)) >> sb->s_blocksize_bits;
+}
+
+/* If this is part of a read-modify-write of the block,
+   pram_memunlock_block() before calling! */
+static inline void *
+pram_get_block(struct super_block *sb, u64 block)
+{
+	struct pram_super_block *ps = pram_get_super(sb);
+	return block ? ((void *)ps + block) : NULL;
+}
+
+struct pram_inode_vfs {
+#ifdef CONFIG_PRAMFS_XATTR
+	/*
+	 * Extended attributes can be read independently of the main file
+	 * data. Taking i_mutex even when reading would cause contention
+	 * between readers of EAs and writers of regular file data, so
+	 * instead we synchronize on xattr_sem when reading or changing
+	 * EAs.
+	 */
+	struct rw_semaphore xattr_sem;
+#endif
+	/*
+	 * truncate_mutex is for serialising the truncate path against
+	 * get/update block.
+	 */
+	struct mutex truncate_mutex;
+	struct inode vfs_inode;
+};
+
+static inline struct pram_inode_vfs *PRAM_I(struct inode *inode)
+{
+	return container_of(inode, struct pram_inode_vfs, vfs_inode);
+}
+
+/*
+ * Inodes and files operations
+ */
+
+/* dir.c */
+extern struct file_operations pram_dir_operations;
+
+/* file.c */
+extern struct inode_operations pram_file_inode_operations;
+extern struct file_operations pram_file_operations;
+
+/* inode.c */
+extern struct address_space_operations pram_aops;
+
+/* namei.c */
+extern struct inode_operations pram_dir_inode_operations;
+
+/* symlink.c */
+extern struct inode_operations pram_symlink_inode_operations;
+
+extern struct backing_dev_info pram_backing_dev_info;
+
+#endif	/* __PRAM_H */
include/linux/magic.h +1 -0
diff -Nurp linux-2.6.36-orig/include/linux/magic.h linux-2.6.36/include/linux/magic.h
@@ -39,6 +39,7 @@
 #define OPENPROM_SUPER_MAGIC	0x9fa1
 #define PROC_SUPER_MAGIC	0x9fa0
 #define QNX4_SUPER_MAGIC	0x002f		/* qnx4 fs detection */
+#define PRAM_SUPER_MAGIC	0xEFFA
  #define REISERFS_SUPER_MAGIC	0x52654973	/* used by gcc */
 					/* used by file system utilities that
include/linux/pram_fs.h +118 -0

118 lines not on this page · raw message

include/linux/pram_fs_sb.h +44 -0

44 lines not on this page · raw message

#1 lore raw
Quoted 21 lines · Marco Stornelli

From: Marco Stornelli <[email protected]>

Definitions for the PRAMFS filesystem.

---
diff -Nurp linux-2.6.36-orig/fs/pramfs/pram.h linux-2.6.36/fs/pramfs/pram.h

fs/pramfs/pram.h +10 -0
@@ -0,0 +1,317 @@
 
+/*
+ * Structure of the super block in PRAMFS
+ */
+struct pram_super_block {
+	__be16	s_sum;          /* checksum of this sb, including padding */
+	__be64	s_size;         /* total size of fs in bytes */
+	__be32	s_blocksize;    /* blocksize in bytes */
+	__be32	s_inodes_count;	/* total inodes count (used or free) */
+	__be32	s_free_inodes_count;/* free inodes count */
+	__be32	s_free_inode_hint;  /* start hint for locating free inodes */

fs/pramfs/pram.h

Quoted 10 lines
fs/pramfs/pram.h +10 -0
+	__be32	s_blocks_count;	/* total data blocks count (used or free) */
+	__be32	s_free_blocks_count;/* free data blocks count */
+	__be32	s_free_blocknr_hint;/* free data blocks count */
+	__be64	s_bitmap_start; /* data block in-use bitmap location */
+	__be32	s_bitmap_blocks;/* size of bitmap in number of blocks */
+	__be32	s_mtime;	/* Mount time */
+	__be32	s_wtime;	/* Write time */
+	__be16	s_magic;	/* Magic signature */
+	char	s_volume_name[16]; /* volume name */
+};

Is there a particular reason to use big endian types for the data structures? On a little endian machine you will end up converting values everywhere. I assume that you don't expect the machine to change endianess between reboots :-). If this is for generating/reading filesystems from userspace, wouldn't it be better to have the userspace tools specify the target endianess and do the conversions there?

~Ryan

Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
[email protected]         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934
#2 lore raw

2010/11/7 Ryan Mallon <[email protected]>:

Quoted 40 lines · Marco Stornelli
Quoted 21 lines

From: Marco Stornelli <[email protected]>

Definitions for the PRAMFS filesystem.

---
diff -Nurp linux-2.6.36-orig/fs/pramfs/pram.h linux-2.6.36/fs/pramfs/pram.h

fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h        1970-01-01 01:00:00.000000000 +0100 +10 -0
@@ -0,0 +1,317 @@
 
+/*
+ * Structure of the super block in PRAMFS
+ */
+struct pram_super_block {
+     __be16  s_sum;          /* checksum of this sb, including padding */
+     __be64  s_size;         /* total size of fs in bytes */
+     __be32  s_blocksize;    /* blocksize in bytes */
+     __be32  s_inodes_count; /* total inodes count (used or free) */
+     __be32  s_free_inodes_count;/* free inodes count */
+     __be32  s_free_inode_hint;  /* start hint for locating free inodes */

fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200

Quoted 10 lines
fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h        1970-01-01 01:00:00.000000000 +0100 +10 -0
+     __be32  s_blocks_count; /* total data blocks count (used or free) */
+     __be32  s_free_blocks_count;/* free data blocks count */
+     __be32  s_free_blocknr_hint;/* free data blocks count */
+     __be64  s_bitmap_start; /* data block in-use bitmap location */
+     __be32  s_bitmap_blocks;/* size of bitmap in number of blocks */
+     __be32  s_mtime;        /* Mount time */
+     __be32  s_wtime;        /* Write time */
+     __be16  s_magic;        /* Magic signature */
+     char    s_volume_name[16]; /* volume name */
+};

Is there a particular reason to use big endian types for the data structures? On a little endian machine you will end up converting values everywhere. I assume that you don't expect the machine to change endianess between reboots :-). If this is for generating/reading filesystems from userspace, wouldn't it be better to have the userspace tools specify the target endianess and do the conversions there?

Quoted 1 line

~Ryan

Yes, there is a reason. In the first review a comment was: the fs must have a fix endianess layout. This fs is designed for the embedded world mainly. Since most of cpus used in this case are big-endian, it means that for typical use case, there is no cost for endianess conversion.

Marco

#3 lore raw
Quoted 41 lines · Marco Stornelli

2010/11/7 Ryan Mallon <[email protected]>:

Quoted 40 lines · Marco Stornelli
Quoted 21 lines

From: Marco Stornelli <[email protected]>

Definitions for the PRAMFS filesystem.

---
diff -Nurp linux-2.6.36-orig/fs/pramfs/pram.h linux-2.6.36/fs/pramfs/pram.h

fs/pramfs/pram.h 2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h 1970-01-01 01:00:00.000000000 +0100 +10 -0
@@ -0,0 +1,317 @@
 
+/*
+ * Structure of the super block in PRAMFS
+ */
+struct pram_super_block {
+     __be16  s_sum;          /* checksum of this sb, including padding */
+     __be64  s_size;         /* total size of fs in bytes */
+     __be32  s_blocksize;    /* blocksize in bytes */
+     __be32  s_inodes_count; /* total inodes count (used or free) */
+     __be32  s_free_inodes_count;/* free inodes count */
+     __be32  s_free_inode_hint;  /* start hint for locating free inodes */

fs/pramfs/pram.h 2010-10-30 12:02:45.000000000 +0200

Quoted 10 lines
fs/pramfs/pram.h 2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h 1970-01-01 01:00:00.000000000 +0100 +10 -0
+     __be32  s_blocks_count; /* total data blocks count (used or free) */
+     __be32  s_free_blocks_count;/* free data blocks count */
+     __be32  s_free_blocknr_hint;/* free data blocks count */
+     __be64  s_bitmap_start; /* data block in-use bitmap location */
+     __be32  s_bitmap_blocks;/* size of bitmap in number of blocks */
+     __be32  s_mtime;        /* Mount time */
+     __be32  s_wtime;        /* Write time */
+     __be16  s_magic;        /* Magic signature */
+     char    s_volume_name[16]; /* volume name */
+};

Is there a particular reason to use big endian types for the data structures? On a little endian machine you will end up converting values everywhere. I assume that you don't expect the machine to change endianess between reboots :-). If this is for generating/reading filesystems from userspace, wouldn't it be better to have the userspace tools specify the target endianess and do the conversions there?

Quoted 7 lines
Quoted 1 line

~Ryan

Yes, there is a reason. In the first review a comment was: the fs must have a fix endianess layout. This fs is designed for the embedded world mainly. Since most of cpus used in this case are big-endian, it means that for typical use case, there is no cost for endianess conversion.

ARM, which is a large portion of the embedded space, is typically little endian.

Why does a filesystem need to have a specific endianess layout? Especially for a highly specialised filesystem like this.

~Ryan

Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
[email protected]         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934
#4 lore raw

2010/11/8 Ryan Mallon <[email protected]>:

Quoted 44 lines · Marco Stornelli
Quoted 43 lines

2010/11/7 Ryan Mallon <[email protected]>:

Quoted 41 lines · Marco Stornelli
Quoted 21 lines

From: Marco Stornelli <[email protected]>

Definitions for the PRAMFS filesystem.

---
diff -Nurp linux-2.6.36-orig/fs/pramfs/pram.h linux-2.6.36/fs/pramfs/pram.h

fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h        1970-01-01 01:00:00.000000000 +0100 +10 -0
@@ -0,0 +1,317 @@
 
+/*
+ * Structure of the super block in PRAMFS
+ */
+struct pram_super_block {
+     __be16  s_sum;          /* checksum of this sb, including padding */
+     __be64  s_size;         /* total size of fs in bytes */
+     __be32  s_blocksize;    /* blocksize in bytes */
+     __be32  s_inodes_count; /* total inodes count (used or free) */
+     __be32  s_free_inodes_count;/* free inodes count */
+     __be32  s_free_inode_hint;  /* start hint for locating free inodes */

fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200

Quoted 10 lines
fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h        1970-01-01 01:00:00.000000000 +0100 +10 -0
+     __be32  s_blocks_count; /* total data blocks count (used or free) */
+     __be32  s_free_blocks_count;/* free data blocks count */
+     __be32  s_free_blocknr_hint;/* free data blocks count */
+     __be64  s_bitmap_start; /* data block in-use bitmap location */
+     __be32  s_bitmap_blocks;/* size of bitmap in number of blocks */
+     __be32  s_mtime;        /* Mount time */
+     __be32  s_wtime;        /* Write time */
+     __be16  s_magic;        /* Magic signature */
+     char    s_volume_name[16]; /* volume name */
+};

Is there a particular reason to use big endian types for the data structures? On a little endian machine you will end up converting values everywhere. I assume that you don't expect the machine to change endianess between reboots :-). If this is for generating/reading filesystems from userspace, wouldn't it be better to have the userspace tools specify the target endianess and do the conversions there?

~Ryan

Quoted 8 lines
Quoted 5 lines

Yes, there is a reason. In the first review a comment was: the fs must have a fix endianess layout. This fs is designed for the embedded world mainly. Since most of cpus used in this case are big-endian, it means that for typical use case, there is no cost for endianess conversion.

ARM, which is a large portion of the embedded space, is typically little endian.

Not always. Indeed, I didn't say *all* cpu used are big-endian.

Quoted 4 lines

Why does a filesystem need to have a specific endianess layout? Especially for a highly specialised filesystem like this.

I didn't agree with it, but in the first review there was more than one developer that said this thing. The main reason was to read the format (for example with JTAG) or to create an image with a fix format. I remember that someone said that there was a similar problem with jffs2 and the experience tell to us that a fix endianess is important. At that point I decided to use big-endian. You can see all the discussion in lkml. The review has been done at June 2009.

Regards,

Marco

#5 lore raw
Quoted 51 lines · Marco Stornelli

2010/11/8 Ryan Mallon <[email protected]>:

Quoted 50 lines · Marco Stornelli
Quoted 48 lines

2010/11/7 Ryan Mallon <[email protected]>:

Quoted 40 lines · Marco Stornelli
Quoted 21 lines

From: Marco Stornelli <[email protected]>

Definitions for the PRAMFS filesystem.

---
diff -Nurp linux-2.6.36-orig/fs/pramfs/pram.h linux-2.6.36/fs/pramfs/pram.h

fs/pramfs/pram.h 2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h 1970-01-01 01:00:00.000000000 +0100 +10 -0
@@ -0,0 +1,317 @@
 
+/*
+ * Structure of the super block in PRAMFS
+ */
+struct pram_super_block {
+     __be16  s_sum;          /* checksum of this sb, including padding */
+     __be64  s_size;         /* total size of fs in bytes */
+     __be32  s_blocksize;    /* blocksize in bytes */
+     __be32  s_inodes_count; /* total inodes count (used or free) */
+     __be32  s_free_inodes_count;/* free inodes count */
+     __be32  s_free_inode_hint;  /* start hint for locating free inodes */

fs/pramfs/pram.h 2010-10-30 12:02:45.000000000 +0200

Quoted 10 lines
fs/pramfs/pram.h 2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h 1970-01-01 01:00:00.000000000 +0100 +10 -0
+     __be32  s_blocks_count; /* total data blocks count (used or free) */
+     __be32  s_free_blocks_count;/* free data blocks count */
+     __be32  s_free_blocknr_hint;/* free data blocks count */
+     __be64  s_bitmap_start; /* data block in-use bitmap location */
+     __be32  s_bitmap_blocks;/* size of bitmap in number of blocks */
+     __be32  s_mtime;        /* Mount time */
+     __be32  s_wtime;        /* Write time */
+     __be16  s_magic;        /* Magic signature */
+     char    s_volume_name[16]; /* volume name */
+};

Is there a particular reason to use big endian types for the data structures? On a little endian machine you will end up converting values everywhere. I assume that you don't expect the machine to change endianess between reboots :-). If this is for generating/reading filesystems from userspace, wouldn't it be better to have the userspace tools specify the target endianess and do the conversions there?

Quoted 1 line

~Ryan

Yes, there is a reason. In the first review a comment was: the fs must have a fix endianess layout. This fs is designed for the embedded world mainly. Since most of cpus used in this case are big-endian, it means that for typical use case, there is no cost for endianess conversion.

Quoted 4 lines
Quoted 2 lines

ARM, which is a large portion of the embedded space, is typically little endian.

Not always. Indeed, I didn't say *all* cpu used are big-endian.

My point is that little endian embedded machines make up a large portion of the devices that this filesystem will be useful on. On those devices it will also have an (unnecessary) conversion overhead.

Quoted 5 lines
Quoted 4 lines

Why does a filesystem need to have a specific endianess layout? Especially for a highly specialised filesystem like this.

Quoted 7 lines

I didn't agree with it, but in the first review there was more than one developer that said this thing. The main reason was to read the format (for example with JTAG) or to create an image with a fix format. I remember that someone said that there was a similar problem with jffs2 and the experience tell to us that a fix endianess is important. At that point I decided to use big-endian. You can see all the discussion in lkml. The review has been done at June 2009.

You can still do all of those things without having a fixed endianess. You just have to have one extra step of telling the external tools what the endianess is. IMHO, it is better to have the overhead of the endian conversion in the tools since it is less costly there than an the embedded system.

I'm just trying to understand why the fixed endianess rule cannot be bent for such a specialised filesystem.

~Ryan

Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
[email protected]         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934
#6 lore raw
Quoted 72 lines · Ryan Mallon
Quoted 51 lines · Marco Stornelli

2010/11/8 Ryan Mallon <[email protected]>:

Quoted 50 lines · Marco Stornelli
Quoted 48 lines

2010/11/7 Ryan Mallon <[email protected]>:

Quoted 40 lines · Marco Stornelli
Quoted 21 lines

From: Marco Stornelli <[email protected]>

Definitions for the PRAMFS filesystem.

---
diff -Nurp linux-2.6.36-orig/fs/pramfs/pram.h linux-2.6.36/fs/pramfs/pram.h

fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h        1970-01-01 01:00:00.000000000 +0100 +10 -0
@@ -0,0 +1,317 @@
 
+/*
+ * Structure of the super block in PRAMFS
+ */
+struct pram_super_block {
+     __be16  s_sum;          /* checksum of this sb, including padding */
+     __be64  s_size;         /* total size of fs in bytes */
+     __be32  s_blocksize;    /* blocksize in bytes */
+     __be32  s_inodes_count; /* total inodes count (used or free) */
+     __be32  s_free_inodes_count;/* free inodes count */
+     __be32  s_free_inode_hint;  /* start hint for locating free inodes */

fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200

Quoted 10 lines
fs/pramfs/pram.h     2010-10-30 12:02:45.000000000 +0200 renamed from fs/pramfs/pram.h        1970-01-01 01:00:00.000000000 +0100 +10 -0
+     __be32  s_blocks_count; /* total data blocks count (used or free) */
+     __be32  s_free_blocks_count;/* free data blocks count */
+     __be32  s_free_blocknr_hint;/* free data blocks count */
+     __be64  s_bitmap_start; /* data block in-use bitmap location */
+     __be32  s_bitmap_blocks;/* size of bitmap in number of blocks */
+     __be32  s_mtime;        /* Mount time */
+     __be32  s_wtime;        /* Write time */
+     __be16  s_magic;        /* Magic signature */
+     char    s_volume_name[16]; /* volume name */
+};

Is there a particular reason to use big endian types for the data structures? On a little endian machine you will end up converting values everywhere. I assume that you don't expect the machine to change endianess between reboots :-). If this is for generating/reading filesystems from userspace, wouldn't it be better to have the userspace tools specify the target endianess and do the conversions there?

Quoted 1 line

~Ryan

Yes, there is a reason. In the first review a comment was: the fs must have a fix endianess layout. This fs is designed for the embedded world mainly. Since most of cpus used in this case are big-endian, it means that for typical use case, there is no cost for endianess conversion.

Quoted 4 lines
Quoted 2 lines

ARM, which is a large portion of the embedded space, is typically little endian.

Not always. Indeed, I didn't say *all* cpu used are big-endian.

My point is that little endian embedded machines make up a large portion of the devices that this filesystem will be useful on. On those devices it will also have an (unnecessary) conversion overhead.

Quoted 10 lines
Quoted 2 lines

Why does a filesystem need to have a specific endianess layout? Especially for a highly specialised filesystem like this.

I didn't agree with it, but in the first review there was more than one developer that said this thing. The main reason was to read the format (for example with JTAG) or to create an image with a fix format. I remember that someone said that there was a similar problem with jffs2 and the experience tell to us that a fix endianess is important. At that point I decided to use big-endian. You can see all the discussion in lkml. The review has been done at June 2009.

Quoted 8 lines

You can still do all of those things without having a fixed endianess. You just have to have one extra step of telling the external tools what the endianess is. IMHO, it is better to have the overhead of the endian conversion in the tools since it is less costly there than an the embedded system.

I'm just trying to understand why the fixed endianess rule cannot be bent for such a specialised filesystem.

When it was decided that filesystems should be fixed-endian and support for big-endian ext2 was dropped, the overhead of doing the fixed conversions was deetermined negligible due to compiler optimization.
That was ages ago, and current embedded systems run circles around the machines of those days.

Note that this is about metadata only. Actual file contents are always just byte streams.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
--
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

#7 lore raw

2010/11/9 Geert Uytterhoeven <[email protected]>:

Quoted 10 lines · Ryan Mallon
Quoted 8 lines

You can still do all of those things without having a fixed endianess. You just have to have one extra step of telling the external tools what the endianess is. IMHO, it is better to have the overhead of the endian conversion in the tools since it is less costly there than an the embedded system.

I'm just trying to understand why the fixed endianess rule cannot be bent for such a specialised filesystem.

Quoted 9 lines

When it was decided that filesystems should be fixed-endian and support for big-endian ext2 was dropped, the overhead of doing the fixed conversions was deetermined negligible due to compiler optimization.
That was ages ago, and current embedded systems run circles around the machines of those days.

Note that this is about metadata only. Actual file contents are always just byte streams.

I can add that the penalties in this case are negligible due to the compensation of the very fast access of the media. In addition, from performance point of view I'm pretty happy (you can see the some benchmark on the project web site).

Marco

#8 lore raw
Quoted 17 lines · Marco Stornelli

2010/11/9 Geert Uytterhoeven <[email protected]>:

Quoted 16 lines · Ryan Mallon
Quoted 8 lines

You can still do all of those things without having a fixed endianess. You just have to have one extra step of telling the external tools what the endianess is. IMHO, it is better to have the overhead of the endian conversion in the tools since it is less costly there than an the embedded system.

I'm just trying to understand why the fixed endianess rule cannot be bent for such a specialised filesystem.

When it was decided that filesystems should be fixed-endian and support for big-endian ext2 was dropped, the overhead of doing the fixed conversions was deetermined negligible due to compiler optimization.
That was ages ago, and current embedded systems run circles around the machines of those days.

Quoted 8 lines
Quoted 3 lines

Note that this is about metadata only. Actual file contents are always just byte streams.

I can add that the penalties in this case are negligible due to the compensation of the very fast access of the media. In addition, from performance point of view I'm pretty happy (you can see the some benchmark on the project web site).

Thanks for the explanation guys.

~Ryan

Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
[email protected]         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934