LKML Archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7] omfs: define filesystem structures
@ 2008-03-27  0:45 Bob Copeland
  2008-03-28 20:19 ` Pavel Machek
  0 siblings, 1 reply; 8+ messages in thread
From: Bob Copeland @ 2008-03-27  0:45 UTC (permalink / raw
  To: linux-kernel; +Cc: linux-fsdevel, Bob Copeland

OMFS is a proprietary filesystem created for the ReplayTV and
also used by the Rio Karma.  It uses hash tables with unordered,
unbounded lists in each bucket for directories, extents for
data blocks, 64-bit addressing for blocks, with up to 8K blocks
(only 2K of a given block is ever used for metadata, so the FS
still works with 4K pages).

This and the following set of changes add support for OMFS; this
change adds the header file.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
---
Hi all,

I've been maintaining this reverse-engineered filesystem
out-of-tree since around 2.6.12.  It has stabilized to the point
that, while not quite feature-complete, it is close enough that
I'm pretty much just applying VFS API updates to it these days.
So, in the spirit of stable_api_nonsense, I request that it be
considered for inclusion for .26 or later.

There is a small user community (<20?) using the driver today.
According to google, it has been packaged by others for Debian,
Ubuntu, and Mandriva.

I have also written an implementation in FUSE.  However, in
its current unoptimized state, it's about half the speed of the
kernel driver.  Either way, the kernel version could use a review 
given some distros have apparently picked it up.

 fs/omfs/omfs.h |  150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 150 insertions(+), 0 deletions(-)
 create mode 100644 fs/omfs/omfs.h

diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h
new file mode 100644
index 0000000..4a602e9
--- /dev/null
+++ b/fs/omfs/omfs.h
@@ -0,0 +1,150 @@
+#ifndef _OMFS_H
+#define _OMFS_H
+
+#include <linux/module.h>
+#include <linux/fs.h>
+
+#define OMFS_MAGIC 0xC2993D87
+#define OMFS_IMAGIC 0xD2
+
+#define OMFS_DIR 'D'
+#define OMFS_FILE 'F'
+#define OMFS_INODE_NORMAL 'e'
+#define OMFS_INODE_CONTINUATION 'c'
+#define OMFS_INODE_SYSTEM 's'
+#define OMFS_NAMELEN 256
+#define OMFS_DIR_START 0x1b8
+#define OMFS_EXTENT_START 0x1d0
+#define OMFS_EXTENT_CONT 0x40
+#define OMFS_XOR_COUNT 19
+
+#define OMFS_STATE_NEW 1
+
+/* In-memory structures */
+struct omfs_sb_info {
+	u64 s_num_blocks;
+	u64 s_bitmap_ino;
+	u64 s_root_ino;
+	u32 s_blocksize;
+	u32 s_mirrors;
+	u32 s_sys_blocksize;
+	u32 s_clustersize;
+	int s_block_shift;
+	unsigned long **s_imap;
+	int s_imap_size;
+	struct mutex s_bitmap_lock;
+};
+
+struct omfs_inode_info {
+	u8 i_state;
+	struct inode vfs_inode;
+};
+
+/* On-disk structures */
+struct omfs_super_block {
+	char s_fill1[256];
+	__be64 s_root_block;
+	__be64 s_num_blocks;
+	__be32 s_magic;
+	__be32 s_blocksize;
+	__be32 s_mirrors;
+	__be32 s_sys_blocksize;
+};
+
+struct omfs_header {
+	__be64 h_self;
+	__be32 h_body_size;
+	__be16 h_crc;
+	char h_fill1[2];
+	u8 h_version;
+	char h_type;
+	u8 h_magic;
+	u8 h_check_xor;
+	__be32 h_fill2;
+};
+
+struct omfs_root_block {
+	struct omfs_header r_head;
+	__be64 r_fill1;
+	__be64 r_num_blocks;
+	__be64 r_root_dir;
+	__be64 r_bitmap;
+	__be32 r_blocksize;
+	__be32 r_clustersize;
+	__be64 r_mirrors;
+	char r_name[OMFS_NAMELEN];
+};
+
+struct omfs_inode {
+	struct omfs_header i_head;
+	__be64 i_parent;
+	__be64 i_sibling;
+	__be64 i_ctime;
+	char i_fill1[35];
+	char i_type;
+	__be32 i_fill2;
+	char i_fill3[64];
+	char i_name[OMFS_NAMELEN];
+	__be64 i_size;
+};
+
+struct omfs_extent_entry {
+	__be64 e_cluster;
+	__be64 e_blocks;
+};
+
+struct omfs_extent {
+	__be64 e_next;
+	__be32 e_extent_count;
+	__be32 e_fill;
+	struct omfs_extent_entry e_entry;
+};
+
+
+/* convert a cluster number to a 512-byte block number */
+static inline sector_t clus_to_blk(struct omfs_sb_info *sbi, sector_t block)
+{
+	return block << sbi->s_block_shift;
+}
+
+static inline struct omfs_sb_info *OMFS_SB(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+
+static inline struct omfs_inode_info *OMFS_I(struct inode *inode)
+{
+	return list_entry(inode, struct omfs_inode_info, vfs_inode);
+}
+
+/* bitmap.c */
+extern unsigned long omfs_count_free(struct super_block *sb);
+extern int omfs_allocate_block(struct super_block *sb, u64 block);
+extern int omfs_allocate_range(struct super_block *sb, int min_request,
+			int max_request, u64 *return_block, int *return_size);
+extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
+
+/* checksum.c */
+int omfs_update_checksums(struct omfs_inode *oi, struct super_block *sb,
+		ino_t ino);
+
+/* dir.c */
+extern struct file_operations omfs_dir_operations;
+extern struct inode_operations omfs_dir_inops;
+extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
+
+/* file.c */
+extern struct file_operations omfs_file_operations;
+extern struct inode_operations omfs_file_inops;
+extern struct address_space_operations omfs_aops;
+extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
+extern int omfs_shrink_inode(struct inode *inode);
+
+/* inode.c */
+extern struct inode *omfs_iget(struct super_block *sb, ino_t inode);
+extern struct inode *omfs_new_inode(struct inode *dir, int mode);
+extern int omfs_reserve_block(struct super_block *sb, sector_t block);
+extern int omfs_find_empty_block(struct super_block *sb, int mode, ino_t *ino);
+extern int omfs_sync_inode(struct inode *inode);
+
+#endif
-- 
1.5.4.2.182.gb3092



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/7] omfs: define filesystem structures
  2008-03-27  0:45 Bob Copeland
@ 2008-03-28 20:19 ` Pavel Machek
  2008-03-28 23:18   ` Bob Copeland
  0 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2008-03-28 20:19 UTC (permalink / raw
  To: Bob Copeland; +Cc: linux-kernel, linux-fsdevel

On Wed 2008-03-26 20:45:54, Bob Copeland wrote:
> OMFS is a proprietary filesystem created for the ReplayTV and
> also used by the Rio Karma.  It uses hash tables with unordered,
> unbounded lists in each bucket for directories, extents for

Why did they create such beast?

> +struct omfs_header {
> +	__be64 h_self;
> +	__be32 h_body_size;
> +	__be16 h_crc;
> +	char h_fill1[2];
> +	u8 h_version;
> +	char h_type;
> +	u8 h_magic;
> +	u8 h_check_xor;
> +	__be32 h_fill2;
> +};

attribute packed or something? Some strange machine (alpha?) may
decide to align u8s at 32bit boundaries...

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/7] omfs: define filesystem structures
  2008-03-28 20:19 ` Pavel Machek
@ 2008-03-28 23:18   ` Bob Copeland
  2008-03-29  3:15     ` Arnd Bergmann
  0 siblings, 1 reply; 8+ messages in thread
From: Bob Copeland @ 2008-03-28 23:18 UTC (permalink / raw
  To: Pavel Machek; +Cc: linux-kernel, linux-fsdevel

On Fri, Mar 28, 2008 at 09:19:40PM +0100, Pavel Machek wrote:
> On Wed 2008-03-26 20:45:54, Bob Copeland wrote:
> > OMFS is a proprietary filesystem created for the ReplayTV and
> > also used by the Rio Karma.  It uses hash tables with unordered,
> > unbounded lists in each bucket for directories, extents for
> 
> Why did they create such beast?

Heh, I wish I knew.  Good old NIH.  There were so many "interesting"
decisions here, like requiring seeks all over the place for dir
traversal, picking a hash function that has collisions in almost every
bucket even when the table is half empty, wasting large amounts of space
by not even using 3/4s of certain blocks -- it's hard to pick a favorite.

Oh, on ReplayTV 4/5xxx they also byte-swapped the block layer such that
every 4 bytes were written backwards (even data).  So a be64 would
be written out as 'le32_high le32_low'.  This patch doesn't support that 
brain damage, but I did cook up a bswap dm target to test with one of 
those disk images.

> > +struct omfs_header {
> > +	__be64 h_self;
> > +	__be32 h_body_size;
> > +	__be16 h_crc;
> > +	char h_fill1[2];
> > +	u8 h_version;
> > +	char h_type;
> > +	u8 h_magic;
> > +	u8 h_check_xor;
> > +	__be32 h_fill2;
> > +};
> 
> attribute packed or something? Some strange machine (alpha?) may
> decide to align u8s at 32bit boundaries...

Thanks, I guess this applies for all the on disk structs.

-- 
Bob Copeland %% www.bobcopeland.com 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/7] omfs: define filesystem structures
  2008-03-28 23:18   ` Bob Copeland
@ 2008-03-29  3:15     ` Arnd Bergmann
  2008-03-29 15:29       ` Jamie Lokier
  0 siblings, 1 reply; 8+ messages in thread
From: Arnd Bergmann @ 2008-03-29  3:15 UTC (permalink / raw
  To: Bob Copeland; +Cc: Pavel Machek, linux-kernel, linux-fsdevel

On Saturday 29 March 2008, Bob Copeland wrote:
> On Fri, Mar 28, 2008 at 09:19:40PM +0100, Pavel Machek wrote:
> > On Wed 2008-03-26 20:45:54, Bob Copeland wrote:
> > > +struct omfs_header {
> > > +   __be64 h_self;
> > > +   __be32 h_body_size;
> > > +   __be16 h_crc;
> > > +   char h_fill1[2];
> > > +   u8 h_version;
> > > +   char h_type;
> > > +   u8 h_magic;
> > > +   u8 h_check_xor;
> > > +   __be32 h_fill2;
> > > +};
> > 
> > attribute packed or something? Some strange machine (alpha?) may
> > decide to align u8s at 32bit boundaries...
> 
> Thanks, I guess this applies for all the on disk structs.

Actually, we don't normally add the attribute((packed)) in cases like
this one, where you already have manual padding in it. Marking this
structure packed would only cause a small performance loss on accesses
of its members on certain architectures, but not have an impact on
correctness.

No architecture supported by Linux requires higher than natural alignment
for any integer types, and a lot of other code would break otherwise.

	Arnd <><

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/7] omfs: define filesystem structures
  2008-03-29  3:15     ` Arnd Bergmann
@ 2008-03-29 15:29       ` Jamie Lokier
  2008-03-30  3:16         ` Bob Copeland
  0 siblings, 1 reply; 8+ messages in thread
From: Jamie Lokier @ 2008-03-29 15:29 UTC (permalink / raw
  To: Arnd Bergmann; +Cc: Bob Copeland, Pavel Machek, linux-kernel, linux-fsdevel

Arnd Bergmann wrote:
> Actually, we don't normally add the attribute((packed)) in cases like
> this one, where you already have manual padding in it. Marking this
> structure packed would only cause a small performance loss on accesses
> of its members on certain architectures, but not have an impact on
> correctness.
> 
> No architecture supported by Linux requires higher than natural alignment
> for any integer types, and a lot of other code would break otherwise.

That's not quite true.  Some architectures supported by Linux add
"external" padding to the size and alignment of a structure.

	struct my_subtype {
		unsigned char st1, st2;
	};

On Linux/ARM, sizeof(my_subtype) == 4 and __alignof__(my_subtype) == 4.
On Linux/x86, sizeof(my_subtype) == 2 and __alignof__(my_subtype) == 1.

This will break code which expects them to pack into an array, or
which is accessing this structure from a 2-byte aligned address.

This also effects structures containing other structures:

	struct my_type {
		unsigned char a, b, c, d;
		struct my_subtype st[2];
		unsigned char e, f, g, h;
	};

On Linux/ARM, sizeof(my_type) == 16 and __alignof__(my_subtype) == 4.
On Linux/ARM, sizeof(my_type) == 12 and __alignof__(my_subtype) == 1.

This did break one of my programs on Linux.  I had to decide between
using __attribute__((packed)) and losing portability, or stop using a
struct to access the data which was ugly but portable (the structures
had a lot more fields than this example).

-- Jamie

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/7] omfs: define filesystem structures
  2008-03-29 15:29       ` Jamie Lokier
@ 2008-03-30  3:16         ` Bob Copeland
  0 siblings, 0 replies; 8+ messages in thread
From: Bob Copeland @ 2008-03-30  3:16 UTC (permalink / raw
  To: Arnd Bergmann, Pavel Machek, linux-kernel, linux-fsdevel

Version 2 of this patch, with these changes:
 - remove unnecessary omfs_inode_info
 - update prototype for omfs_update_checksums to kill unused params

>From b2f65cb52dea81ff51489be3af791936fc4b336c Mon Sep 17 00:00:00 2001
From: Bob Copeland <me@bobcopeland.com>
Date: Thu, 27 Mar 2008 17:22:47 -0400
Subject: [PATCH] omfs: define filesystem structures

OMFS is a proprietary filesystem created for the ReplayTV and
also used by the Rio Karma.  It uses hash tables with unordered,
unbounded lists in each bucket for directories, extents for
data blocks, 64-bit addressing for blocks, with up to 8K blocks
(only 2K of a given block is ever used for metadata, so the FS
still works with 4K pages).

This and the following set of changes add support for OMFS; this
change adds the header file.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
---
 fs/omfs/omfs.h |  137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 137 insertions(+), 0 deletions(-)
 create mode 100644 fs/omfs/omfs.h

diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h
new file mode 100644
index 0000000..349764b
--- /dev/null
+++ b/fs/omfs/omfs.h
@@ -0,0 +1,137 @@
+#ifndef _OMFS_H
+#define _OMFS_H
+
+#include <linux/module.h>
+#include <linux/fs.h>
+
+#define OMFS_MAGIC 0xC2993D87
+#define OMFS_IMAGIC 0xD2
+
+#define OMFS_DIR 'D'
+#define OMFS_FILE 'F'
+#define OMFS_INODE_NORMAL 'e'
+#define OMFS_INODE_CONTINUATION 'c'
+#define OMFS_INODE_SYSTEM 's'
+#define OMFS_NAMELEN 256
+#define OMFS_DIR_START 0x1b8
+#define OMFS_EXTENT_START 0x1d0
+#define OMFS_EXTENT_CONT 0x40
+#define OMFS_XOR_COUNT 19
+
+/* In-memory structures */
+struct omfs_sb_info {
+	u64 s_num_blocks;
+	u64 s_bitmap_ino;
+	u64 s_root_ino;
+	u32 s_blocksize;
+	u32 s_mirrors;
+	u32 s_sys_blocksize;
+	u32 s_clustersize;
+	int s_block_shift;
+	unsigned long **s_imap;
+	int s_imap_size;
+	struct mutex s_bitmap_lock;
+};
+
+/* On-disk structures */
+struct omfs_super_block {
+	char s_fill1[256];
+	__be64 s_root_block;
+	__be64 s_num_blocks;
+	__be32 s_magic;
+	__be32 s_blocksize;
+	__be32 s_mirrors;
+	__be32 s_sys_blocksize;
+};
+
+struct omfs_header {
+	__be64 h_self;
+	__be32 h_body_size;
+	__be16 h_crc;
+	char h_fill1[2];
+	u8 h_version;
+	char h_type;
+	u8 h_magic;
+	u8 h_check_xor;
+	__be32 h_fill2;
+};
+
+struct omfs_root_block {
+	struct omfs_header r_head;
+	__be64 r_fill1;
+	__be64 r_num_blocks;
+	__be64 r_root_dir;
+	__be64 r_bitmap;
+	__be32 r_blocksize;
+	__be32 r_clustersize;
+	__be64 r_mirrors;
+	char r_name[OMFS_NAMELEN];
+};
+
+struct omfs_inode {
+	struct omfs_header i_head;
+	__be64 i_parent;
+	__be64 i_sibling;
+	__be64 i_ctime;
+	char i_fill1[35];
+	char i_type;
+	__be32 i_fill2;
+	char i_fill3[64];
+	char i_name[OMFS_NAMELEN];
+	__be64 i_size;
+};
+
+struct omfs_extent_entry {
+	__be64 e_cluster;
+	__be64 e_blocks;
+};
+
+struct omfs_extent {
+	__be64 e_next;
+	__be32 e_extent_count;
+	__be32 e_fill;
+	struct omfs_extent_entry e_entry;
+};
+
+
+/* convert a cluster number to a 512-byte block number */
+static inline sector_t clus_to_blk(struct omfs_sb_info *sbi, sector_t block)
+{
+	return block << sbi->s_block_shift;
+}
+
+static inline struct omfs_sb_info *OMFS_SB(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+
+/* bitmap.c */
+extern unsigned long omfs_count_free(struct super_block *sb);
+extern int omfs_allocate_block(struct super_block *sb, u64 block);
+extern int omfs_allocate_range(struct super_block *sb, int min_request,
+			int max_request, u64 *return_block, int *return_size);
+extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
+
+/* checksum.c */
+int omfs_update_checksums(struct omfs_inode *oi);
+
+/* dir.c */
+extern struct file_operations omfs_dir_operations;
+extern struct inode_operations omfs_dir_inops;
+extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
+
+/* file.c */
+extern struct file_operations omfs_file_operations;
+extern struct inode_operations omfs_file_inops;
+extern struct address_space_operations omfs_aops;
+extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
+extern int omfs_shrink_inode(struct inode *inode);
+
+/* inode.c */
+extern struct inode *omfs_iget(struct super_block *sb, ino_t inode);
+extern struct inode *omfs_new_inode(struct inode *dir, int mode);
+extern int omfs_reserve_block(struct super_block *sb, sector_t block);
+extern int omfs_find_empty_block(struct super_block *sb, int mode, ino_t *ino);
+extern int omfs_sync_inode(struct inode *inode);
+
+#endif
-- 
1.5.4.2.182.gb3092



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 1/7] omfs: define filesystem structures
@ 2008-04-12 22:58 Bob Copeland
  2008-04-13  8:03 ` Christoph Hellwig
  0 siblings, 1 reply; 8+ messages in thread
From: Bob Copeland @ 2008-04-12 22:58 UTC (permalink / raw
  To: linux-kernel; +Cc: linux-fsdevel, akpm, Bob Copeland

    OMFS is a proprietary filesystem created for the ReplayTV and
    also used by the Rio Karma.  It uses hash tables with unordered,
    unbounded lists in each bucket for directories, extents for
    data blocks, 64-bit addressing for blocks, with up to 8K blocks
    (only 2K of a given block is ever used for metadata, so the FS
    still works with 4K pages).

    This and the following set of changes add support for OMFS; this
    change adds the header file.

    Signed-off-by: Bob Copeland <me@bobcopeland.com>
---
 fs/omfs/omfs.h |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 139 insertions(+), 0 deletions(-)
 create mode 100644 fs/omfs/omfs.h

diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h
new file mode 100644
index 0000000..5faeb91
--- /dev/null
+++ b/fs/omfs/omfs.h
@@ -0,0 +1,139 @@
+#ifndef _OMFS_H
+#define _OMFS_H
+
+#include <linux/module.h>
+#include <linux/fs.h>
+
+#define OMFS_MAGIC 0xC2993D87
+#define OMFS_IMAGIC 0xD2
+
+#define OMFS_DIR 'D'
+#define OMFS_FILE 'F'
+#define OMFS_INODE_NORMAL 'e'
+#define OMFS_INODE_CONTINUATION 'c'
+#define OMFS_INODE_SYSTEM 's'
+#define OMFS_NAMELEN 256
+#define OMFS_DIR_START 0x1b8
+#define OMFS_EXTENT_START 0x1d0
+#define OMFS_EXTENT_CONT 0x40
+#define OMFS_XOR_COUNT 19
+
+/* In-memory structures */
+struct omfs_sb_info {
+	u64 s_num_blocks;
+	u64 s_bitmap_ino;
+	u64 s_root_ino;
+	u32 s_blocksize;
+	u32 s_mirrors;
+	u32 s_sys_blocksize;
+	u32 s_clustersize;
+	int s_block_shift;
+	unsigned long **s_imap;
+	int s_imap_size;
+	struct mutex s_bitmap_lock;
+};
+
+/* On-disk structures */
+struct omfs_super_block {
+	char s_fill1[256];
+	__be64 s_root_block;
+	__be64 s_num_blocks;
+	__be32 s_magic;
+	__be32 s_blocksize;
+	__be32 s_mirrors;
+	__be32 s_sys_blocksize;
+};
+
+struct omfs_header {
+	__be64 h_self;
+	__be32 h_body_size;
+	__be16 h_crc;
+	char h_fill1[2];
+	u8 h_version;
+	char h_type;
+	u8 h_magic;
+	u8 h_check_xor;
+	__be32 h_fill2;
+};
+
+struct omfs_root_block {
+	struct omfs_header r_head;
+	__be64 r_fill1;
+	__be64 r_num_blocks;
+	__be64 r_root_dir;
+	__be64 r_bitmap;
+	__be32 r_blocksize;
+	__be32 r_clustersize;
+	__be64 r_mirrors;
+	char r_name[OMFS_NAMELEN];
+};
+
+struct omfs_inode {
+	struct omfs_header i_head;
+	__be64 i_parent;
+	__be64 i_sibling;
+	__be64 i_ctime;
+	char i_fill1[35];
+	char i_type;
+	__be32 i_fill2;
+	char i_fill3[64];
+	char i_name[OMFS_NAMELEN];
+	__be64 i_size;
+};
+
+struct omfs_extent_entry {
+	__be64 e_cluster;
+	__be64 e_blocks;
+};
+
+struct omfs_extent {
+	__be64 e_next;
+	__be32 e_extent_count;
+	__be32 e_fill;
+	struct omfs_extent_entry e_entry;
+};
+
+
+/* convert a cluster number to a 512-byte block number */
+static inline sector_t clus_to_blk(struct omfs_sb_info *sbi, sector_t block)
+{
+	return block << sbi->s_block_shift;
+}
+
+static inline struct omfs_sb_info *OMFS_SB(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+
+/* bitmap.c */
+extern unsigned long omfs_count_free(struct super_block *sb);
+extern int omfs_allocate_block(struct super_block *sb, u64 block);
+extern int omfs_allocate_range(struct super_block *sb, int min_request,
+			int max_request, u64 *return_block, int *return_size);
+extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
+
+/* checksum.c */
+int omfs_update_checksums(struct omfs_inode *oi);
+
+/* dir.c */
+extern struct file_operations omfs_dir_operations;
+extern struct inode_operations omfs_dir_inops;
+extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
+extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, 
+			u64 fsblock);
+
+/* file.c */
+extern struct file_operations omfs_file_operations;
+extern struct inode_operations omfs_file_inops;
+extern struct address_space_operations omfs_aops;
+extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
+extern int omfs_shrink_inode(struct inode *inode);
+
+/* inode.c */
+extern struct inode *omfs_iget(struct super_block *sb, ino_t inode);
+extern struct inode *omfs_new_inode(struct inode *dir, int mode);
+extern int omfs_reserve_block(struct super_block *sb, sector_t block);
+extern int omfs_find_empty_block(struct super_block *sb, int mode, ino_t *ino);
+extern int omfs_sync_inode(struct inode *inode);
+
+#endif
-- 
1.5.4.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/7] omfs: define filesystem structures
  2008-04-12 22:58 [PATCH 1/7] omfs: define filesystem structures Bob Copeland
@ 2008-04-13  8:03 ` Christoph Hellwig
  0 siblings, 0 replies; 8+ messages in thread
From: Christoph Hellwig @ 2008-04-13  8:03 UTC (permalink / raw
  To: Bob Copeland; +Cc: linux-kernel, linux-fsdevel, akpm

On Sat, Apr 12, 2008 at 06:58:35PM -0400, Bob Copeland wrote:
>     OMFS is a proprietary filesystem created for the ReplayTV and
>     also used by the Rio Karma.  It uses hash tables with unordered,
>     unbounded lists in each bucket for directories, extents for
>     data blocks, 64-bit addressing for blocks, with up to 8K blocks
>     (only 2K of a given block is ever used for metadata, so the FS
>     still works with 4K pages).
> 
>     This and the following set of changes add support for OMFS; this
>     change adds the header file.

Looks good.  Although I would separate the on-disk structure into a
separate header of it's own.  That makes it easy to spot what we're
dealing with, and you can easily re-use just that header in userspace
should you write any maintainance tools like mkfs or fsck for this
filesystem in the future.

> 
>     Signed-off-by: Bob Copeland <me@bobcopeland.com>
> ---
>  fs/omfs/omfs.h |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 139 insertions(+), 0 deletions(-)
>  create mode 100644 fs/omfs/omfs.h
> 
> diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h
> new file mode 100644
> index 0000000..5faeb91
> --- /dev/null
> +++ b/fs/omfs/omfs.h
> @@ -0,0 +1,139 @@
> +#ifndef _OMFS_H
> +#define _OMFS_H
> +
> +#include <linux/module.h>
> +#include <linux/fs.h>
> +
> +#define OMFS_MAGIC 0xC2993D87
> +#define OMFS_IMAGIC 0xD2
> +
> +#define OMFS_DIR 'D'
> +#define OMFS_FILE 'F'
> +#define OMFS_INODE_NORMAL 'e'
> +#define OMFS_INODE_CONTINUATION 'c'
> +#define OMFS_INODE_SYSTEM 's'
> +#define OMFS_NAMELEN 256
> +#define OMFS_DIR_START 0x1b8
> +#define OMFS_EXTENT_START 0x1d0
> +#define OMFS_EXTENT_CONT 0x40
> +#define OMFS_XOR_COUNT 19
> +
> +/* In-memory structures */
> +struct omfs_sb_info {
> +	u64 s_num_blocks;
> +	u64 s_bitmap_ino;
> +	u64 s_root_ino;
> +	u32 s_blocksize;
> +	u32 s_mirrors;
> +	u32 s_sys_blocksize;
> +	u32 s_clustersize;
> +	int s_block_shift;
> +	unsigned long **s_imap;
> +	int s_imap_size;
> +	struct mutex s_bitmap_lock;
> +};
> +
> +/* On-disk structures */
> +struct omfs_super_block {
> +	char s_fill1[256];
> +	__be64 s_root_block;
> +	__be64 s_num_blocks;
> +	__be32 s_magic;
> +	__be32 s_blocksize;
> +	__be32 s_mirrors;
> +	__be32 s_sys_blocksize;
> +};
> +
> +struct omfs_header {
> +	__be64 h_self;
> +	__be32 h_body_size;
> +	__be16 h_crc;
> +	char h_fill1[2];
> +	u8 h_version;
> +	char h_type;
> +	u8 h_magic;
> +	u8 h_check_xor;
> +	__be32 h_fill2;
> +};
> +
> +struct omfs_root_block {
> +	struct omfs_header r_head;
> +	__be64 r_fill1;
> +	__be64 r_num_blocks;
> +	__be64 r_root_dir;
> +	__be64 r_bitmap;
> +	__be32 r_blocksize;
> +	__be32 r_clustersize;
> +	__be64 r_mirrors;
> +	char r_name[OMFS_NAMELEN];
> +};
> +
> +struct omfs_inode {
> +	struct omfs_header i_head;
> +	__be64 i_parent;
> +	__be64 i_sibling;
> +	__be64 i_ctime;
> +	char i_fill1[35];
> +	char i_type;
> +	__be32 i_fill2;
> +	char i_fill3[64];
> +	char i_name[OMFS_NAMELEN];
> +	__be64 i_size;
> +};
> +
> +struct omfs_extent_entry {
> +	__be64 e_cluster;
> +	__be64 e_blocks;
> +};
> +
> +struct omfs_extent {
> +	__be64 e_next;
> +	__be32 e_extent_count;
> +	__be32 e_fill;
> +	struct omfs_extent_entry e_entry;
> +};
> +
> +
> +/* convert a cluster number to a 512-byte block number */
> +static inline sector_t clus_to_blk(struct omfs_sb_info *sbi, sector_t block)
> +{
> +	return block << sbi->s_block_shift;
> +}
> +
> +static inline struct omfs_sb_info *OMFS_SB(struct super_block *sb)
> +{
> +	return sb->s_fs_info;
> +}
> +
> +/* bitmap.c */
> +extern unsigned long omfs_count_free(struct super_block *sb);
> +extern int omfs_allocate_block(struct super_block *sb, u64 block);
> +extern int omfs_allocate_range(struct super_block *sb, int min_request,
> +			int max_request, u64 *return_block, int *return_size);
> +extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
> +
> +/* checksum.c */
> +int omfs_update_checksums(struct omfs_inode *oi);
> +
> +/* dir.c */
> +extern struct file_operations omfs_dir_operations;
> +extern struct inode_operations omfs_dir_inops;
> +extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
> +extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, 
> +			u64 fsblock);
> +
> +/* file.c */
> +extern struct file_operations omfs_file_operations;
> +extern struct inode_operations omfs_file_inops;
> +extern struct address_space_operations omfs_aops;
> +extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
> +extern int omfs_shrink_inode(struct inode *inode);
> +
> +/* inode.c */
> +extern struct inode *omfs_iget(struct super_block *sb, ino_t inode);
> +extern struct inode *omfs_new_inode(struct inode *dir, int mode);
> +extern int omfs_reserve_block(struct super_block *sb, sector_t block);
> +extern int omfs_find_empty_block(struct super_block *sb, int mode, ino_t *ino);
> +extern int omfs_sync_inode(struct inode *inode);
> +
> +#endif
> -- 
> 1.5.4.2
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
---end quoted text---

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-04-13  8:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-12 22:58 [PATCH 1/7] omfs: define filesystem structures Bob Copeland
2008-04-13  8:03 ` Christoph Hellwig
  -- strict thread matches above, loose matches on Subject: below --
2008-03-27  0:45 Bob Copeland
2008-03-28 20:19 ` Pavel Machek
2008-03-28 23:18   ` Bob Copeland
2008-03-29  3:15     ` Arnd Bergmann
2008-03-29 15:29       ` Jamie Lokier
2008-03-30  3:16         ` Bob Copeland

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 read-only IMAP folder(s) and NNTP newsgroup(s).