[PATCH 00/14] Pramfs: Persistent and protected ram filesystem

2009-06-13 Thread Marco
This is a second attempt at mainlining Pramfs. The first attempt was
back in early 2004 by MontaVista. Since then the kernel code has almost
been completely rewritten. So my first item on the list was porting the
code on a recent kernel version. After that I added the XIP support.

Now some FAQs:

What is the goal of this filesystem?

Many embedded systems have a block of non-volatile RAM separate from
normal system memory, i.e. of which the kernel maintains no memory page
descriptors. For such systems it would be beneficial to mount a
fast read/write filesystem over this I/O memory, for storing
frequently accessed data that must survive system reboots and power
cycles. An example usage might be system logs under /var/log, or a user
address book in a cell phone or PDA.

Why this kind of filesystem should be mainlined?

Linux traditionally had no support for a persistent, non-volatile
RAM-based filesystem, persistent meaning the filesystem survives a
system reboot or power cycle intact. The RAM-based filesystems such as
tmpfs and ramfs have no actual backing store but exist entirely in the
page and buffer caches, hence the filesystem disappears after a system
reboot or power cycle.

Are there any pending patents on this code?

NO, there aren't patents pending on this code. MontaVista had a pending
patent application but now it has abandoned this way. Daniel Walker can
confirm that.


Marco



--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/14] Pramfs: File operations for directories

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

File operations for directories.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---

diff -uprN linux-2.6.30-orig/fs/pramfs/dir.c linux-2.6.30/fs/pramfs/dir.c
--- linux-2.6.30-orig/fs/pramfs/dir.c   1970-01-01 01:00:00.0 +0100
+++ linux-2.6.30/fs/pramfs/dir.c2009-06-13 12:51:46.0 +0200
@@ -0,0 +1,220 @@
+/*
+ * FILE NAME fs/pramfs/dir.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * File operations for directories.
+ *
+ * Copyright 2009 Marco Stornelli marco.storne...@gmail.com
+ * 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.
+ */
+
+#include linux/fs.h
+#include linux/pagemap.h
+#include pram_fs.h
+
+/*
+ * Parent is locked.
+ */
+int pram_add_link(struct dentry *dentry, struct inode *inode)
+{
+   struct inode *dir = dentry-d_parent-d_inode;
+   struct pram_inode *pidir, *pi, *pitail = NULL;
+   off_t tail_ino, prev_ino;
+   unsigned long flags;
+
+   const char *name = dentry-d_name.name;
+   int namelen = dentry-d_name.len  PRAM_NAME_LEN ?
+   PRAM_NAME_LEN : dentry-d_name.len;
+
+   flags = 0;
+
+   pidir = pram_get_inode(dir-i_sb, dir-i_ino);
+   pi = pram_get_inode(dir-i_sb, inode-i_ino);
+
+   dir-i_mtime = dir-i_ctime = CURRENT_TIME;
+
+   tail_ino = pidir-i_type.dir.tail;
+   if (tail_ino != 0) {
+   pitail = pram_get_inode(dir-i_sb, tail_ino);
+   pram_lock_inode(pitail, flags);
+   pitail-i_d.d_next = inode-i_ino;
+   pram_unlock_inode(pitail, flags);
+
+   prev_ino = tail_ino;
+
+   pram_lock_inode(pidir, flags);
+   pidir-i_type.dir.tail = inode-i_ino;
+   pidir-i_mtime = dir-i_mtime.tv_sec;
+   pidir-i_ctime = dir-i_ctime.tv_sec;
+   pram_unlock_inode(pidir, flags);
+   } else {
+   /* the directory is empty */
+   prev_ino = 0;
+
+   pram_lock_inode(pidir, flags);
+   pidir-i_type.dir.head = pidir-i_type.dir.tail = inode-i_ino;
+   pidir-i_mtime = dir-i_mtime.tv_sec;
+   pidir-i_ctime = dir-i_ctime.tv_sec;
+   pram_unlock_inode(pidir, flags);
+   }
+
+
+   pram_lock_inode(pi, flags);
+   pi-i_d.d_prev = prev_ino;
+   pi-i_d.d_parent = dir-i_ino;
+   memcpy(pi-i_d.d_name, name, namelen);
+   pi-i_d.d_name[namelen] = '\0';
+   pram_unlock_inode(pi, flags);
+   return 0;
+}
+
+int pram_remove_link(struct inode *inode)
+{
+   struct super_block *sb = inode-i_sb;
+   struct pram_inode *prev = NULL;
+   struct pram_inode *next = NULL;
+   struct pram_inode *pidir, *pi;
+   unsigned long flags;
+
+   flags = 0;
+
+   pi = pram_get_inode(sb, inode-i_ino);
+   pidir = pram_get_inode(sb, pi-i_d.d_parent);
+   if (!pidir)
+   return -EACCES;
+
+   if (inode-i_ino == pidir-i_type.dir.head) {
+   /* first inode in directory */
+   next = pram_get_inode(sb, pi-i_d.d_next);
+
+   if (next) {
+   pram_lock_inode(next, flags);
+   next-i_d.d_prev = 0;
+   pram_unlock_inode(next, flags);
+
+   pram_lock_inode(pidir, flags);
+   pidir-i_type.dir.head = pi-i_d.d_next;
+   } else {
+   pram_lock_inode(pidir, flags);
+   pidir-i_type.dir.head = pidir-i_type.dir.tail = 0;
+   }
+   pram_unlock_inode(pidir, flags);
+   } else if (inode-i_ino == pidir-i_type.dir.tail) {
+   /* last inode in directory */
+   prev = pram_get_inode(sb, pi-i_d.d_prev);
+
+   pram_lock_inode(prev, flags);
+   prev-i_d.d_next = 0;
+   pram_unlock_inode(prev, flags);
+
+   pram_lock_inode(pidir, flags);
+   pidir-i_type.dir.tail = pi-i_d.d_prev;
+   pram_unlock_inode(pidir, flags);
+   } else {
+   /* somewhere in the middle */
+   prev = pram_get_inode(sb, pi-i_d.d_prev);
+   next = pram_get_inode(sb, pi-i_d.d_next);
+
+   if (prev  next) {
+   pram_lock_inode(prev, flags);
+   prev-i_d.d_next = pi-i_d.d_next;
+   pram_unlock_inode(prev, flags);
+
+   pram_lock_inode(next, flags);
+   next-i_d.d_prev = pi-i_d.d_prev;
+   pram_unlock_inode(next, flags);
+   }
+   }
+
+   pram_lock_inode(pi, flags);
+   pi-i_d.d_next = 

[PATCH 04/14] Pramfs: Mounting as root filesystem

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

Pramfs can be used even as root filesystem.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---

diff -uprN linux-2.6.30-orig/init/do_mounts.c linux-2.6.30/init/do_mounts.c
--- linux-2.6.30-orig/init/do_mounts.c  2009-06-10 05:05:27.0 +0200
+++ linux-2.6.30/init/do_mounts.c   2009-06-13 12:50:36.0 +0200
@@ -299,6 +299,17 @@ static int __init mount_nfs_root(void)
 }
 #endif
 
+#ifdef CONFIG_ROOT_PRAMFS
+static int __init mount_pramfs_root(void)
+{
+   create_dev(/dev/root, ROOT_DEV);
+   if (do_mount_root(/dev/root, pramfs,
+   root_mountflags, root_mount_data) == 0)
+   return 1;
+return 0;
+}
+#endif
+
 #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
 void __init change_floppy(char *fmt, ...)
 {
@@ -331,6 +342,15 @@ void __init change_floppy(char *fmt, ...
 
 void __init mount_root(void)
 {
+#ifdef CONFIG_ROOT_PRAMFS
+   if (MAJOR(ROOT_DEV) == MEM_MAJOR) {
+   if (mount_pramfs_root())
+   return;
+
+   printk(KERN_ERR VFS: Unable to mount root fs via PRAMFS, 
trying floppy.\n);
+   ROOT_DEV = Root_FD0;
+   }
+#endif
 #ifdef CONFIG_ROOT_NFS
if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
if (mount_nfs_root())



--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/14] Pramfs: File operations for files

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

File operations for files.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---

diff -uprN linux-2.6.30-orig/fs/pramfs/file.c linux-2.6.30/fs/pramfs/file.c
--- linux-2.6.30-orig/fs/pramfs/file.c  1970-01-01 01:00:00.0 +0100
+++ linux-2.6.30/fs/pramfs/file.c   2009-06-13 12:52:56.0 +0200
@@ -0,0 +1,141 @@
+/*
+ * FILE NAME fs/pramfs/file.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * File operations for files.
+ *
+ * Copyright 2009 Marco Stornelli marco.storne...@gmail.com
+ * 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.
+ */
+#include linux/fs.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/uio.h
+#include linux/uaccess.h
+#include pram_fs.h
+#include xip.h
+
+static int pram_open_file(struct inode *inode, struct file *filp)
+{
+#ifndef CONFIG_PRAMFS_XIP
+   /* Without XIP we force to use Direct IO */
+   filp-f_flags |= O_DIRECT;
+#endif
+   return generic_file_open(inode, filp);
+}
+
+/*
+ * Called when an inode is released. Note that this is different
+ * from pram_open_file: open gets called at every open, but release
+ * gets called only when /all/ the files are closed.
+ */
+static int pram_release_file(struct inode *inode, struct file *filp)
+{
+   return 0;
+}
+
+ssize_t __pram_direct_IO(int rw, struct kiocb *iocb,
+  const struct iovec *iov,
+  loff_t offset, unsigned long nr_segs)
+{
+   struct file *file = iocb-ki_filp;
+   struct inode *inode = file-f_mapping-host;
+   struct super_block *sb = inode-i_sb;
+   int progress = 0;
+   ssize_t retval = 0;
+   struct pram_inode *pi;
+   void *tmp = NULL;
+   unsigned long flags;
+   unsigned long blocknr, blockoff;
+   int num_blocks, blocksize_mask, blocksize, blocksize_bits;
+   char __user *buf = iov-iov_base;
+   size_t length = iov-iov_len;
+
+   flags = 0;
+
+   if (length  0)
+   return -EINVAL;
+   if ((rw == READ)  (offset + length  inode-i_size))
+   length = inode-i_size - offset;
+   if (!length)
+   goto out;
+
+   blocksize_bits = inode-i_sb-s_blocksize_bits;
+   blocksize = 1  blocksize_bits;
+   blocksize_mask = blocksize - 1;
+
+   /* find starting block number to access */
+   blocknr = offset  blocksize_bits;
+   /* find starting offset within starting block */
+   blockoff = offset  blocksize_mask;
+   /* find number of blocks to access */
+   num_blocks = (blockoff + length + blocksize_mask)  blocksize_bits;
+
+   if (rw == WRITE) {
+   /* prepare a temporary buffer to hold a user data block
+  for writing. */
+   tmp = kmalloc(blocksize, GFP_KERNEL);
+   if (!tmp)
+   return -ENOMEM;
+   /* now allocate the data blocks we'll need */
+   retval = pram_alloc_blocks(inode, blocknr, num_blocks);
+   if (retval)
+   goto fail;
+   }
+
+   pi = pram_get_inode(inode-i_sb, inode-i_ino);
+
+   while (length) {
+   int count;
+   off_t block = pram_find_data_block(inode, blocknr++);
+   u8 *bp = (u8 *)pram_get_block(sb, block);
+   if (!bp)
+   goto fail;
+
+   count = blockoff + length  blocksize ?
+   blocksize - blockoff : length;
+
+   if (rw == READ) {
+   copy_to_user(buf, bp[blockoff], count);
+   } else {
+   copy_from_user(tmp, buf, count);
+
+   pram_lock_block(inode-i_sb, bp, flags);
+   memcpy(bp[blockoff], tmp, count);
+   pram_unlock_block(inode-i_sb, bp, flags);
+   }
+
+   progress += count;
+   buf += count;
+   length -= count;
+   blockoff = 0;
+   }
+
+   retval = progress;
+ fail:
+   kfree(tmp);
+ out:
+   return retval;
+}
+
+struct file_operations pram_file_operations = {
+   .llseek = generic_file_llseek,
+   .read   = pram_read,
+   .write  = pram_write,
+   .aio_read   = pram_aio_read,
+   .aio_write  = pram_aio_write,
+   .mmap   = pram_mmap,
+   .open   = pram_open_file,
+   .release= pram_release_file,
+   .fsync  = simple_sync_file,
+};
+
+struct inode_operations pram_file_inode_operations = {
+   .truncate   = pram_truncate,
+};

--
To unsubscribe from this list: send the line unsubscribe linux-embedded in

[PATCH 07/14] Pramfs: Inode operations

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

Inode operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---

diff -uprN linux-2.6.30-orig/fs/pramfs/inode.c linux-2.6.30/fs/pramfs/inode.c
--- linux-2.6.30-orig/fs/pramfs/inode.c 1970-01-01 01:00:00.0 +0100
+++ linux-2.6.30/fs/pramfs/inode.c  2009-06-13 12:58:27.0 +0200
@@ -0,0 +1,620 @@
+/*
+ * FILE NAME fs/pramfs/inode.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Inode methods (allocate/free/read/write).
+ *
+ * Copyright 2009 Marco Stornelli marco.storne...@gmail.com
+ * 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.
+ */
+#include linux/fs.h
+#include linux/smp_lock.h
+#include linux/sched.h
+#include linux/highuid.h
+#include linux/quotaops.h
+#include linux/module.h
+#include linux/mpage.h
+#include linux/backing-dev.h
+#include pram_fs.h
+#include xip.h
+
+static struct backing_dev_info pram_backing_dev_info = {
+   .ra_pages   = 0,/* No readahead */
+   .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK,
+};
+
+/*
+ * allocate a data block for inode and return it's absolute blocknr.
+ * Zeroes out the block if zero set. Increments inode-i_blocks.
+ */
+static int
+pram_new_data_block(struct inode *inode, int *blocknr, int zero)
+{
+   unsigned long flags;
+
+   int errval = pram_new_block(inode-i_sb, blocknr, zero);
+
+   flags = 0;
+
+   if (!errval) {
+   struct pram_inode *pi = pram_get_inode(inode-i_sb,
+   inode-i_ino);
+   inode-i_blocks++;
+   pram_lock_inode(pi, flags);
+   pi-i_blocks = inode-i_blocks;
+   pram_unlock_inode(pi, flags);
+   }
+
+   return errval;
+}
+
+/*
+ * find the offset to the block represented by the given inode's file
+ * relative block number.
+ */
+off_t pram_find_data_block(struct inode *inode, int file_blocknr)
+{
+   struct super_block *sb = inode-i_sb;
+   struct pram_inode *pi;
+   off_t *row; /* ptr to row block */
+   off_t *col; /* ptr to column blocks */
+   off_t bp = 0;
+   int i_row, i_col;
+   int N = sb-s_blocksize  2; /* num block ptrs per block */
+   int Nbits = sb-s_blocksize_bits - 2;
+
+   pi = pram_get_inode(sb, inode-i_ino);
+
+   i_row = file_blocknr  Nbits;
+   i_col  = file_blocknr  (N-1);
+
+   row = pram_get_block(sb, pi-i_type.reg.row_block);
+   if (row) {
+   col = pram_get_block(sb, row[i_row]);
+   if (col)
+   bp = col[i_col];
+   }
+
+   return bp;
+}
+
+
+/*
+ * Free data blocks from inode starting at first_trunc_block.
+ */
+static void
+pram_truncate_blocks(struct inode *inode, int first_trunc_block)
+{
+   struct super_block *sb = inode-i_sb;
+   struct pram_inode *pi = pram_get_inode(sb, inode-i_ino);
+   int N = sb-s_blocksize  2; /* num block ptrs per block */
+   int Nbits = sb-s_blocksize_bits - 2;
+   int first_row_index, last_row_index;
+   int i, j, first_blocknr, last_blocknr, blocknr;
+   unsigned long flags;
+   off_t *row; /* ptr to row block */
+   off_t *col; /* ptr to column blocks */
+
+   flags = 0;
+
+   if (first_trunc_block = inode-i_blocks ||
+   !inode-i_blocks || !pi-i_type.reg.row_block) {
+   return;
+   }
+
+   first_blocknr = first_trunc_block;
+   last_blocknr = inode-i_blocks - 1;
+   first_row_index = first_blocknr  Nbits;
+   last_row_index  = last_blocknr  Nbits;
+
+   row = pram_get_block(sb, pi-i_type.reg.row_block);
+
+   for (i = first_row_index; i = last_row_index; i++) {
+   int first_col_index = (i == first_row_index) ?
+   first_blocknr  (N-1) : 0;
+   int last_col_index = (i == last_row_index) ?
+   last_blocknr  (N-1) : N-1;
+
+   col = pram_get_block(sb, row[i]);
+   for (j = first_col_index; j = last_col_index; j++) {
+   blocknr = pram_get_blocknr(sb, col[j]);
+   pram_free_block(sb, blocknr);
+   pram_lock_block(sb, col, flags);
+   col[j] = 0;
+   pram_unlock_block(sb, col, flags);
+   }
+
+   if (first_col_index == 0) {
+   blocknr = pram_get_blocknr(sb, row[i]);
+   pram_free_block(sb, blocknr);
+   pram_lock_block(sb, row, flags);
+   row[i] = 0;
+   pram_unlock_block(sb, row, flags);
+   }
+   }
+
+   inode-i_blocks -= (last_blocknr - 

[PATCH 06/14] Pramfs: Include files

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

Include files.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---

diff -uprN linux-2.6.30-orig/fs/pramfs/pram_fs.h 
linux-2.6.30/fs/pramfs/pram_fs.h
--- linux-2.6.30-orig/fs/pramfs/pram_fs.h   1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.30/fs/pramfs/pram_fs.h2009-06-13 12:58:49.0 +0200
@@ -0,0 +1,388 @@
+/*
+ * FILE NAME include/linux/pram_fs.h
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Definitions for the PRAMFS filesystem.
+ *
+ * Copyright 2009 Marco Stornelli marco.storne...@gmail.com
+ * 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 _LINUX_PRAM_FS_H
+#define _LINUX_PRAM_FS_H
+
+#include linux/types.h
+
+#ifdef __KERNEL__
+#include linux/sched.h
+#include linux/buffer_head.h
+#include pram_fs_sb.h
+#endif
+
+/*
+ * The PRAM filesystem constants/structures
+ */
+
+/*
+ * Define PRAMFS_DEBUG to produce debug messages
+ */
+#define PRAMFS_DEBUG
+
+/*
+ * Debug code
+ */
+#ifdef __KERNEL__
+#define PFX pramfs
+#ifdef PRAMFS_DEBUG
+#define pram_dbg(format, arg...) \
+printk(KERN_DEBUG PFX :  format , ## arg)
+#else
+#define pram_dbg(format, arg...) do {} while (0)
+#endif
+#define pram_err(format, arg...) \
+printk(KERN_ERR PFX :  format , ## arg)
+#define pram_info(format, arg...) \
+printk(KERN_INFO PFX :  format , ## arg)
+#define pram_warn(format, arg...) \
+printk(KERN_WARNING PFX :  format , ## arg)
+#endif
+
+/*
+ * The PRAM file system magic number
+ */
+#define PRAM_SUPER_MAGIC   0xEFFA
+
+/*
+ * Maximal count of links to a file
+ */
+#define PRAM_LINK_MAX  32000
+
+#define PRAM_MIN_BLOCK_SIZE 512
+#define PRAM_MAX_BLOCK_SIZE 4096
+#define PRAM_DEF_BLOCK_SIZE 2048
+
+#define PRAM_INODE_SIZE 128 /* must be power of two */
+#define PRAM_INODE_BITS   7
+
+/*
+ * Structure of a directory entry in PRAMFS.
+ * Offsets are to the inode that holds the referenced dentry.
+ */
+struct pram_dentry {
+   off_t d_next; /* next dentry in this directory */
+   off_t d_prev; /* previous dentry in this directory */
+   off_t d_parent;   /* parent directory */
+   char   d_name[0];
+};
+
+
+/*
+ * Structure of an inode in PRAMFS
+ */
+struct pram_inode {
+   __u32   i_sum;  /* checksum of this inode */
+   __u32   i_uid;  /* Owner Uid */
+   __u32   i_gid;  /* Group Id */
+   __u16   i_mode; /* File mode */
+   __u16   i_links_count;  /* Links count */
+   __u32   i_blocks;   /* Blocks count */
+   __u32   i_size; /* Size of data in bytes */
+   __u32   i_atime;/* Access time */
+   __u32   i_ctime;/* Creation time */
+   __u32   i_mtime;/* Modification time */
+   __u32   i_dtime;/* Deletion Time */
+
+   union {
+   struct {
+   /*
+* ptr to row block of 2D block pointer array,
+* file block #'s 0 to (blocksize/4)^2 - 1.
+*/
+   off_t row_block;
+   } reg;   /* regular file or symlink inode */
+   struct {
+   off_t head; /* first entry in this directory */
+   off_t tail; /* last entry in this directory */
+   } dir;
+   struct {
+   __u32 rdev; /* major/minor # */
+   } dev;   /* device inode */
+   } i_type;
+
+   struct pram_dentry i_d;
+};
+
+#define PRAM_NAME_LEN \
+(PRAM_INODE_SIZE - offsetof(struct pram_inode, i_d.d_name) - 1)
+
+
+#define PRAM_SB_SIZE 128 /* must be power of two */
+#define PRAM_SB_BITS   7
+
+/*
+ * Structure of the super block in PRAMFS
+ */
+struct pram_super_block {
+   __u32   s_size; /* total size of fs in bytes */
+   __u32   s_blocksize;/* blocksize in bytes */
+   __u32   s_inodes_count; /* total inodes count (used or free) */
+   __u32   s_free_inodes_count;/* free inodes count */
+   __u32   s_free_inode_hint;  /* start hint for locating free inodes */
+   __u32   s_blocks_count; /* total data blocks count (used or free) */
+   __u32   s_free_blocks_count;/* free data blocks count */
+   __u32   s_free_blocknr_hint;/* free data blocks count */
+   off_t s_bitmap_start; /* data block in-use bitmap location */
+   __u32   s_bitmap_blocks;/* size of bitmap in number of blocks */
+   __u32   s_mtime;/* Mount time */
+   __u32   s_wtime;/* Write time */
+   __u16   s_magic;/* Magic signature */
+   chars_volume_name[16]; /* volume name */
+   __u32   s_sum;  /* checksum 

[PATCH 08/14] Pramfs: Makefile and Kconfig

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

Makefile and Kconfig.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---

diff -uprN linux-2.6.30-orig/fs/Kconfig linux-2.6.30/fs/Kconfig
--- linux-2.6.30-orig/fs/Kconfig2009-06-10 05:05:27.0 +0200
+++ linux-2.6.30/fs/Kconfig 2009-06-13 10:01:41.0 +0200
@@ -13,7 +13,7 @@ source fs/ext4/Kconfig
 config FS_XIP
 # execute in place
bool
-   depends on EXT2_FS_XIP
+   depends on EXT2_FS_XIP || PRAMFS_XIP
default y
 
 source fs/jbd/Kconfig
@@ -176,6 +176,7 @@ source fs/romfs/Kconfig
 source fs/sysv/Kconfig
 source fs/ufs/Kconfig
 source fs/exofs/Kconfig
+source fs/pramfs/Kconfig
 
 config NILFS2_FS
tristate NILFS2 file system support (EXPERIMENTAL)
diff -uprN linux-2.6.30-orig/fs/Makefile linux-2.6.30/fs/Makefile
--- linux-2.6.30-orig/fs/Makefile   2009-06-10 05:05:27.0 +0200
+++ linux-2.6.30/fs/Makefile2009-06-13 10:00:26.0 +0200
@@ -124,3 +124,5 @@ obj-$(CONFIG_OCFS2_FS)  += ocfs2/
 obj-$(CONFIG_BTRFS_FS) += btrfs/
 obj-$(CONFIG_GFS2_FS)   += gfs2/
 obj-$(CONFIG_EXOFS_FS)  += exofs/
+obj-$(CONFIG_PRAMFS)   += pramfs/
+
diff -uprN linux-2.6.30-orig/fs/pramfs/Kconfig linux-2.6.30/fs/pramfs/Kconfig
--- linux-2.6.30-orig/fs/pramfs/Kconfig 1970-01-01 01:00:00.0 +0100
+++ linux-2.6.30/fs/pramfs/Kconfig  2009-04-22 15:22:54.0 +0200
@@ -0,0 +1,51 @@
+config PRAMFS
+   tristate Persistent and Protected RAM file system support
+   select PRAMFS_NOWP if PRAMFS=m
+   help
+  If your system has a block of fast (comparable in access speed to
+  system memory) and non-volatile RAM and you wish to mount a
+  light-weight, full-featured, and space-efficient filesystem over it,
+  say Y here, and read file:Documentation/filesystems/pramfs.txt.
+
+  To compile this as a module,  choose M here: the module will be
+  called pramfs.
+
+config PRAMFS_XIP
+   bool Enable Execute-in-place in PRAMFS
+   depends on PRAMFS
+   select PRAMFS_NOWP
+   help
+  Say Y here to enable xip feature of PRAMFS.
+
+config PRAMFS_NOWP
+   bool Disable PRAMFS write protection
+   depends on PRAMFS
+   default n
+   help
+  Say Y here to disable the write protect feature of PRAMFS.
+
+config ROOT_PRAMFS
+   bool Root file system on PRAMFS
+   depends on PRAMFS  !ROOT_NFS
+   help
+ Say Y if you have enabled PRAMFS, and you want to be
+ able to use PRAMFS as the root filesystem.  To actually
+ have the kernel mount PRAMFS as a root file system, you
+ must also pass the command line parameter
+ root=/dev/null rootflags=physaddr=0x to the kernel
+ (replace 0x with the physical address location of the
+ previously initialized PRAMFS memory to boot with).
+
+config PRAMFS_TEST
+   boolean
+   depends on PRAMFS
+   default n
+
+config TEST_MODULE
+   tristate PRAMFS Test
+   depends on PRAMFS  m  !PRAMFS_NOWP
+   select PRAMFS_TEST
+   default n
+   help
+ Say Y here to build a simple module to test the protection of
+ PRAMFS. The module will be called pramfs_test.ko.
diff -uprN linux-2.6.30-orig/fs/pramfs/Makefile linux-2.6.30/fs/pramfs/Makefile
--- linux-2.6.30-orig/fs/pramfs/Makefile1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.30/fs/pramfs/Makefile 2009-04-19 11:58:51.0 +0200
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux pram-filesystem routines.
+#
+
+obj-$(CONFIG_PRAMFS) += pramfs.o
+obj-$(CONFIG_TEST_MODULE) += pramfs_test.o
+
+pramfs-objs := balloc.o dir.o file.o inode.o namei.o super.o symlink.o
+
+ifneq ($(CONFIG_PRAMFS_NOWP),y)
+pramfs-objs += wprotect.o
+endif
+pramfs-$(CONFIG_PRAMFS_XIP) += xip.o


--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/14] Pramfs: Symbolic link operations

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

Symbolic link operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---

diff -uprN linux-2.6.30-orig/fs/pramfs/symlink.c 
linux-2.6.30/fs/pramfs/symlink.c
--- linux-2.6.30-orig/fs/pramfs/symlink.c   1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.30/fs/pramfs/symlink.c2009-06-13 12:54:07.0 +0200
@@ -0,0 +1,73 @@
+/*
+ * FILE NAME fs/pramfs/symlink.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Symlink operations
+ *
+ * Copyright 2009 Marco Stornelli marco.storne...@gmail.com
+ * 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.
+ */
+
+#include linux/fs.h
+#include pram_fs.h
+
+int pram_block_symlink(struct inode *inode, const char *symname, int len)
+{
+   struct super_block *sb = inode-i_sb;
+   off_t block;
+   char *blockp;
+   int err;
+   unsigned long flags;
+
+   flags = 0;
+
+   err = pram_alloc_blocks(inode, 0, 1);
+   if (err)
+   return err;
+
+   block = pram_find_data_block(inode, 0);
+   blockp = pram_get_block(sb, block);
+
+   pram_lock_block(sb, blockp, flags);
+   memcpy(blockp, symname, len);
+   blockp[len] = '\0';
+   pram_unlock_block(sb, blockp, flags);
+   return 0;
+}
+
+static int pram_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+   struct inode *inode = dentry-d_inode;
+   struct super_block *sb = inode-i_sb;
+   off_t block;
+   char *blockp;
+
+   block = pram_find_data_block(inode, 0);
+   blockp = pram_get_block(sb, block);
+   return vfs_readlink(dentry, buffer, buflen, blockp);
+}
+
+static void *pram_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+   struct inode *inode = dentry-d_inode;
+   struct super_block *sb = inode-i_sb;
+   off_t block;
+   int status;
+   char *blockp;
+
+   block = pram_find_data_block(inode, 0);
+   blockp = pram_get_block(sb, block);
+   status = vfs_follow_link(nd, blockp);
+   return ERR_PTR(status);
+}
+
+struct inode_operations pram_symlink_inode_operations = {
+   .readlink   = pram_readlink,
+   .follow_link= pram_follow_link,
+};



--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/14] Pramfs: test module

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

Test module.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -uprN linux-2.6.30-orig/fs/pramfs/pramfs_test.c 
linux-2.6.30/fs/pramfs/pramfs_test.c
--- linux-2.6.30-orig/fs/pramfs/pramfs_test.c   1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.30/fs/pramfs/pramfs_test.c2009-06-13 13:07:38.0 
+0200
@@ -0,0 +1,50 @@
+/*
+ * FILE NAME fs/pramfs/namei.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Inode operations for directories.
+ *
+ * Copyright 2009 Marco Stornelli marco.storne...@gmail.com
+ * 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.
+ */
+#include linux/module.h
+#include linux/version.h
+#include linux/init.h
+#include linux/fs.h
+#include pram_fs.h
+
+int __init test_pramfs_write(void)
+{
+   struct pram_super_block *psb;
+   char *ptr;
+
+   psb = get_pram_super();
+   if (!psb) {
+   printk(KERN_ERR
+   %s: PRAMFS super block not found (not mounted?)\n,
+   __func__);
+   return 1;
+   }
+
+   /*
+* Attempt an unprotected clear of all information in the superblock,
+* this should cause a kernel page protection fault.
+*/
+   printk(%s: writing to kernel VA %p\n, __func__, psb);
+   memset(psb, 0 , PRAM_SB_SIZE);
+
+   return 0;
+}
+
+void test_pramfs_write_cleanup(void) {}
+
+/* Module information */
+MODULE_LICENSE(GPL);
+module_init(test_pramfs_write);
+module_exit(test_pramfs_write_cleanup);

--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/14] Pramfs: Inode operations for directories

2009-06-13 Thread Marco
From: Marco Stornelli marco.storne...@gmail.com

Inode operations for directories.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---

diff -uprN linux-2.6.30-orig/fs/pramfs/namei.c linux-2.6.30/fs/pramfs/namei.c
--- linux-2.6.30-orig/fs/pramfs/namei.c 1970-01-01 01:00:00.0 +0100
+++ linux-2.6.30/fs/pramfs/namei.c  2009-06-13 12:53:15.0 +0200
@@ -0,0 +1,328 @@
+/*
+ * FILE NAME fs/pramfs/namei.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Inode operations for directories.
+ *
+ * Copyright 2009 Marco Stornelli marco.storne...@gmail.com
+ * 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.
+ */
+#include linux/fs.h
+#include linux/pagemap.h
+#include pram_fs.h
+
+/*
+ * Couple of helper functions - make the code slightly cleaner.
+ */
+
+static inline void pram_inc_count(struct inode *inode)
+{
+   inode-i_nlink++;
+   pram_write_inode(inode, 0);
+}
+
+static inline void pram_dec_count(struct inode *inode)
+{
+   if (inode-i_nlink) {
+   inode-i_nlink--;
+   pram_write_inode(inode, 0);
+   }
+}
+
+static inline int pram_add_nondir(struct inode *dir,
+  struct dentry *dentry,
+  struct inode *inode)
+{
+   int err = pram_add_link(dentry, inode);
+   if (!err) {
+   d_instantiate(dentry, inode);
+   return 0;
+   }
+   pram_dec_count(inode);
+   iput(inode);
+   return err;
+}
+
+/*
+ * Methods themselves.
+ */
+
+static ino_t
+pram_inode_by_name(struct inode *dir,
+  struct dentry *dentry)
+{
+   struct pram_inode *pi;
+   ino_t ino;
+   int namelen;
+
+   pi = pram_get_inode(dir-i_sb, dir-i_ino);
+   ino = pi-i_type.dir.head;
+
+   while (ino) {
+   pi = pram_get_inode(dir-i_sb, ino);
+
+   if (pi-i_links_count) {
+   namelen = strlen(pi-i_d.d_name);
+
+   if (namelen == dentry-d_name.len 
+   !memcmp(dentry-d_name.name,
+   pi-i_d.d_name, namelen))
+   break;
+   }
+
+   ino = pi-i_d.d_next;
+   }
+
+   return ino;
+}
+
+static struct dentry *
+pram_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+{
+   struct inode *inode = NULL;
+   ino_t ino;
+
+   if (dentry-d_name.len  PRAM_NAME_LEN)
+   return ERR_PTR(-ENAMETOOLONG);
+
+   ino = pram_inode_by_name(dir, dentry);
+   if (ino) {
+   struct pram_inode *pi = pram_get_inode(dir-i_sb, ino);
+   inode = pram_fill_new_inode(dir-i_sb, pi);
+   if (!inode)
+   return ERR_PTR(-EACCES);
+   }
+
+   d_add(dentry, inode);
+   return NULL;
+}
+
+
+/*
+ * By the time this is called, we already have created
+ * the directory cache entry for the new file, but it
+ * is so far negative - it has no inode.
+ *
+ * If the create succeeds, we fill in the inode information
+ * with d_instantiate().
+ */
+static int pram_create(struct inode *dir, struct dentry *dentry,
+   int mode, struct nameidata *nd)
+{
+   struct inode *inode = pram_new_inode(dir, mode);
+   int err = PTR_ERR(inode);
+   if (!IS_ERR(inode)) {
+
+   inode-i_op = pram_file_inode_operations;
+   inode-i_fop = pram_file_operations;
+   inode-i_mapping-a_ops = pram_aops;
+   err = pram_add_nondir(dir, dentry, inode);
+   }
+   return err;
+}
+
+static int pram_mknod(struct inode *dir, struct dentry *dentry, int mode,
+  dev_t rdev)
+{
+   struct inode *inode = pram_new_inode(dir, mode);
+   int err = PTR_ERR(inode);
+   if (!IS_ERR(inode)) {
+   init_special_inode(inode, mode, rdev);
+   pram_write_inode(inode, 0); /* update rdev */
+   err = pram_add_nondir(dir, dentry, inode);
+   }
+   return err;
+}
+
+static int pram_symlink(struct inode *dir,
+ struct dentry *dentry,
+ const char *symname)
+{
+   struct super_block *sb = dir-i_sb;
+   int err = -ENAMETOOLONG;
+   unsigned len = strlen(symname);
+   struct inode *inode;
+
+   if (len+1  sb-s_blocksize)
+   goto out;
+
+   inode = pram_new_inode(dir, S_IFLNK | S_IRWXUGO);
+   err = PTR_ERR(inode);
+   if (IS_ERR(inode))
+   goto out;
+
+   inode-i_op = pram_symlink_inode_operations;
+   inode-i_mapping-a_ops = pram_aops;
+
+   err = pram_block_symlink(inode, symname, len);
+   if 

Re: [PATCH 00/14] Pramfs: Persistent and protected ram filesystem

2009-06-13 Thread Daniel Walker
On Sat, 2009-06-13 at 15:20 +0200, Marco wrote:

 Are there any pending patents on this code?
 
 NO, there aren't patents pending on this code. MontaVista had a pending
 patent application but now it has abandoned this way. Daniel Walker can
 confirm that.

Confirmed , there are no patents on this code.

Daniel

--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 06/14] Pramfs: Include files

2009-06-13 Thread Sam Ravnborg
On Sat, Jun 13, 2009 at 03:21:48PM +0200, Marco wrote:
 From: Marco Stornelli marco.storne...@gmail.com
 
 Include files.
 
 Signed-off-by: Marco Stornelli marco.storne...@gmail.com
 ---
 
 diff -uprN linux-2.6.30-orig/fs/pramfs/pram_fs.h 
 linux-2.6.30/fs/pramfs/pram_fs.h
 --- linux-2.6.30-orig/fs/pramfs/pram_fs.h 1970-01-01 01:00:00.0 
 +0100
 +++ linux-2.6.30/fs/pramfs/pram_fs.h  2009-06-13 12:58:49.0 +0200
 @@ -0,0 +1,388 @@
 +/*
 + * FILE NAME include/linux/pram_fs.h
 + *
 + * BRIEF DESCRIPTION
 + *
 + * Definitions for the PRAMFS filesystem.
 + *
 + * Copyright 2009 Marco Stornelli marco.storne...@gmail.com
 + * 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 _LINUX_PRAM_FS_H
 +#define _LINUX_PRAM_FS_H
 +
 +#include linux/types.h
 +
 +#ifdef __KERNEL__
 +#include linux/sched.h
 +#include linux/buffer_head.h
 +#include pram_fs_sb.h
 +#endif

The only reason to have this header file in include/linux/
is that it is used by userspace.
So please split it up so we have one header suitable for exporting
and another header with all the promfs local stuff.
The latter should be in fs/pramsfs/


 +
 +/*
 + * The PRAM filesystem constants/structures
 + */
 +
 +/*
 + * Define PRAMFS_DEBUG to produce debug messages
 + */
 +#define PRAMFS_DEBUG
 +
 +/*
 + * Debug code
 + */
 +#ifdef __KERNEL__
 +#define PFX pramfs
 +#ifdef PRAMFS_DEBUG
 +#define pram_dbg(format, arg...) \
 +printk(KERN_DEBUG PFX :  format , ## arg)
 +#else
 +#define pram_dbg(format, arg...) do {} while (0)
 +#endif
 +#define pram_err(format, arg...) \
 +printk(KERN_ERR PFX :  format , ## arg)
 +#define pram_info(format, arg...) \
 +printk(KERN_INFO PFX :  format , ## arg)
 +#define pram_warn(format, arg...) \
 +printk(KERN_WARNING PFX :  format , ## arg)
 +#endif

For a typical drivers we have some pr_* to avoid the above.
Can they be used for a filesystem too?

 +
 +/*
 + * The PRAM file system magic number
 + */
 +#define PRAM_SUPER_MAGIC 0xEFFA

Move to include/linux/magic.h

 +
 +/*
 + * Structure of an inode in PRAMFS
 + */
 +struct pram_inode {
 + __u32   i_sum;  /* checksum of this inode */
 + __u32   i_uid;  /* Owner Uid */
 + __u32   i_gid;  /* Group Id */
 + __u16   i_mode; /* File mode */
 + __u16   i_links_count;  /* Links count */
 + __u32   i_blocks;   /* Blocks count */
 + __u32   i_size; /* Size of data in bytes */
 + __u32   i_atime;/* Access time */
 + __u32   i_ctime;/* Creation time */
 + __u32   i_mtime;/* Modification time */
 + __u32   i_dtime;/* Deletion Time */
 +
 + union {
 + struct {
 + /*
 +  * ptr to row block of 2D block pointer array,
 +  * file block #'s 0 to (blocksize/4)^2 - 1.
 +  */
 + off_t row_block;

It is my understanding that we shall use: __kernel_off_t
in exported headers.

The headers are not added to Kbuild - so it is not exported.
I assume thats an oversight.

Sam
--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] MMC Agressive clocking framework v2

2009-06-13 Thread Pierre Ossman
On Sat, 13 Jun 2009 14:45:09 +0200
Linus Walleij linus.ml.wall...@gmail.com wrote:

 2009/6/2 Linus Walleij linus.ml.wall...@gmail.com:
 
  This patch modified the MMC core code to optionally call the
  set_ios() operation on the driver with the clock frequency set
  to 0 to gate the hardware block clock (and thus the MCI clock)
 
 have you had a chance to look at this for the current merge
 window Pierre?
 

Not yet, but I plan to. Sorry about the delay.

Rgds
-- 
 -- Pierre Ossman

  Linux kernel, MMC maintainerhttp://www.kernel.org
  rdesktop, core developer  http://www.rdesktop.org
  TigerVNC, core developer  http://www.tigervnc.org

  WARNING: This correspondence is being monitored by the
  Swedish government. Make sure your server uses encryption
  for SMTP traffic and consider using PGP for end-to-end
  encryption.


signature.asc
Description: PGP signature


Re: Kernel crashing and log buffers...

2009-06-13 Thread Wolfgang Denk
Dear Russell King,

In message 20090613102642.gb7...@flint.arm.linux.org.uk you wrote:

 The other way I've seen people read out crash messages is using a
 debugger to dump the kernel's log buffer directly.  That seems to work
 as well as any other method, and has the advantage that it doesn't
 require any kernel modifications.

This works well in the lab during hardware bringup or BSP development.

But we are also interested in a solution that allows to get  more  or
less  automatic access to the log buffer content after a crash - when
you have several ten thousand systems in the field,  such  a  feature
can save you a lot of money.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH, MD: Wolfgang Denk  Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: w...@denx.de
--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Representing Embedded Architectures at the Kernel Summit

2009-06-13 Thread Grant Likely
On Wed, Jun 10, 2009 at 5:13 PM, Kumar Galaga...@kernel.crashing.org wrote:

 On Jun 2, 2009, at 5:21 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:

 I'd like to propose AMP and kernel relocate
 as more and SoC will came with multiple core with or without the same arch

 I think AMP or at least the idea of the kernel communicating with other OSes
 on the same SoC in multi-core systems is interesting.

Indeed, and not just for SoCs.  I'm currently looking at Ira's
adaptation of virtio to use it for IPC between two separate CPUs
running separate Linux instances and connected via PCI.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
--
To unsubscribe from this list: send the line unsubscribe linux-embedded in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html