[PATCH 00/16 v2] pramfs: persistent and protected RAM Filesystem

2010-11-06 Thread Marco Stornelli
Hi all,

I send the patch series again. I fix documentation problems reported by
Randy Dunlap and Kieran Bingham. I reworked the memory protection
functions according to the suggestions of Andi Kleen.

I ask to Andrew to evaluate to insert this fs in mainline.

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 01/16 v2] pramfs: documentation

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Documentation for PRAMFS.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/Documentation/filesystems/pramfs.txt 
linux-2.6.36/Documentation/filesystems/pramfs.txt
--- linux-2.6.36-orig/Documentation/filesystems/pramfs.txt  1970-01-01 
01:00:00.0 +0100
+++ linux-2.6.36/Documentation/filesystems/pramfs.txt   2010-10-23 
09:04:32.0 +0200
@@ -0,0 +1,296 @@
+
+PRAMFS Overview
+===
+
+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.
+
+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.
+
+A relatively straightforward solution is to write a simple block driver
+for the non-volatile RAM, and mount over it any disk-based filesystem such
+as ext2, ext3, ext4, etc.
+
+But the disk-based fs over non-volatile RAM block driver approach has
+some drawbacks:
+
+1. Complexity of disk-based fs: disk-based filesystems such as ext2/ext3/ext4
+   were designed for optimum performance on spinning disk media, so they
+   implement features such as block groups, which attempts to group inode data
+   into a contiguous set of data blocks to minimize disk seeking when accessing
+   files. For RAM there is no such concern; a file's data blocks can be
+   scattered throughout the media with no access speed penalty at all. So block
+   groups in a filesystem mounted over RAM just adds unnecessary
+   complexity. A better approach is to use a filesystem specifically
+   tailored to RAM media which does away with these disk-based features.
+   This increases the efficient use of space on the media, i.e. more
+   space is dedicated to actual file data storage and less to meta-data
+   needed to maintain that file data.
+
+2. Different problems between disks and RAM: Because PRAMFS attempts to avoid
+   filesystem corruption caused by kernel bugs, dirty pages in the page cache
+   are not allowed to be written back to the backing-store RAM. This way, an
+   errant write into the page cache will not get written back to the 
filesystem.
+   However, if the backing-store RAM is comparable in access speed to system
+   memory, the penalty of not using caching is minimal. With this consideration
+   it's better to move file data directly between the user buffers and the 
backing
+   store RAM, i.e. use direct I/O. This prevents the unnecessary populating of
+   the page cache with dirty pages. However direct I/O has to be enabled at
+   every file open. To enable direct I/O at all times for all regular files
+   requires either that applications be modified to include the O_DIRECT flag 
on
+   all file opens, or that the filesystem used performs direct I/O by default.
+
+The Persistent/Protected RAM Special Filesystem (PRAMFS) is a read/write
+filesystem that has been designed to address these issues. PRAMFS is targeted
+to fast I/O memory, and if the memory is non-volatile, the filesystem will be
+persistent.
+
+In PRAMFS, direct I/O is enabled across all files in the filesystem, in other
+words the O_DIRECT flag is forced on every open of a PRAMFS file. Also, file
+I/O in the PRAMFS is always synchronous. There is no need to block the current
+process while the transfer to/from the PRAMFS is in progress, since one of
+the requirements of the PRAMFS is that the filesystem exists in fast RAM. So
+file I/O in PRAMFS is always direct, synchronous, and never blocks.
+
+The data organization in PRAMFS can be thought of as an extremely simplified
+version of ext2, such that the ratio of data to meta-data is very high.
+
+PRAMFS supports the execute-in-place. With XIP, instead of keeping data in the
+page cache, the need to have a page cache copy is eliminated completely.
+Readwrite type operations are performed directly from/to the memory. For file
+mappings, the RAM itself is mapped directly into userspace. XIP, in addition,
+speed up the applications start-up time because it removes the needs of any
+copies.
+
+PRAMFS is write protected. The page table entries that map the backing-store
+RAM are normally marked read-only. Write operations into the filesystem
+temporarily mark the affected pages as writeable, the write operation is
+carried out with locks held, and then the page table entries is +marked 
read-only 

[PATCH 02/16 v2] pramfs: super block operations

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Super block operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/super.c linux-2.6.36/fs/pramfs/super.c
--- linux-2.6.36-orig/fs/pramfs/super.c 1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/super.c  2010-09-25 14:09:47.0 +0200
@@ -0,0 +1,740 @@
+/*
+ * FILE NAME fs/pramfs/super.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Super block operations.
+ *
+ * Copyright 2009-2010 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/string.h
+#include linux/slab.h
+#include linux/init.h
+#include linux/blkdev.h
+#include linux/parser.h
+#include linux/vfs.h
+#include linux/uaccess.h
+#include linux/io.h
+#include linux/seq_file.h
+#include linux/mount.h
+#include linux/mm.h
+#include linux/ctype.h
+#include linux/bitops.h
+#include linux/magic.h
+#include linux/exportfs.h
+#include linux/random.h
+#include xattr.h
+#include pram.h
+
+static struct super_operations pram_sops;
+static const struct export_operations pram_export_ops;
+static struct kmem_cache *pram_inode_cachep;
+
+#ifdef CONFIG_PRAMFS_TEST
+static void *first_pram_super;
+
+struct pram_super_block *get_pram_super(void)
+{
+   return (struct pram_super_block *)first_pram_super;
+}
+EXPORT_SYMBOL(get_pram_super);
+#endif
+
+static void pram_set_blocksize(struct super_block *sb, unsigned long size)
+{
+   int bits;
+
+   /*
+   * We've already validated the user input and the value here must be
+   * between PRAM_MAX_BLOCK_SIZE and PRAM_MIN_BLOCK_SIZE
+   * and it must be a power of 2.
+   */
+   bits = fls(size) - 1;
+   sb-s_blocksize_bits = bits;
+   sb-s_blocksize = (1bits);
+}
+
+static inline void *pram_ioremap(phys_addr_t phys_addr, ssize_t size)
+{
+   void *retval;
+
+   /*
+* NOTE: Userland may not map this resource, we will mark the region so
+* /dev/mem and the sysfs MMIO access will not be allowed. This
+* restriction depends on STRICT_DEVMEM option. If this option is
+* disabled or not available we mark the region only as busy.
+*/
+   retval = request_mem_region_exclusive(phys_addr, size, pramfs);
+   if (!retval)
+   goto fail;
+
+   retval = ioremap_nocache(phys_addr, size);
+
+   if (retval)
+   wrprotect(retval, size);
+fail:
+   return retval;
+}
+
+static loff_t pram_max_size(int bits)
+{
+   loff_t res;
+   res = (1ULL  (3*bits - 6)) - 1;
+
+   if (res  MAX_LFS_FILESIZE)
+   res = MAX_LFS_FILESIZE;
+
+   pram_info(Max file size %llu bytes, res);
+   return res;
+}
+
+enum {
+   Opt_addr, Opt_bpi, Opt_size,
+   Opt_num_inodes, Opt_mode, Opt_uid,
+   Opt_gid, Opt_blocksize, Opt_err
+};
+
+static const match_table_t tokens = {
+   {Opt_bpi,   physaddr=%x},
+   {Opt_bpi,   bpi=%u},
+   {Opt_size,  init=%s},
+   {Opt_num_inodes, N=%u},
+   {Opt_mode,  mode=%o},
+   {Opt_uid,   uid=%u},
+   {Opt_gid,   gid=%u},
+   {Opt_blocksize, bs=%s},
+   {Opt_err,   NULL},
+};
+
+static phys_addr_t get_phys_addr(void **data)
+{
+   phys_addr_t phys_addr;
+   char *options = (char *) *data;
+
+   if (!options || strncmp(options, physaddr=, 9) != 0)
+   return (phys_addr_t)ULLONG_MAX;
+   options += 9;
+   phys_addr = (phys_addr_t)simple_strtoull(options, options, 0);
+   if (*options  *options != ',') {
+   pram_err(Invalid phys addr specification: %s\n,
+  (char *) *data);
+   return (phys_addr_t)ULLONG_MAX;
+   }
+   if (phys_addr  (PAGE_SIZE - 1)) {
+   pram_err(physical address 0x%16llx for pramfs isn't 
+ aligned to a page boundary\n,
+ (u64)phys_addr);
+   return (phys_addr_t)ULLONG_MAX;
+   }
+   if (*options == ',')
+   options++;
+   *data = (void *) options;
+   return phys_addr;
+}
+
+static int pram_parse_options(char *options, struct pram_sb_info *sbi)
+{
+   char *p, *rest;
+   substring_t args[MAX_OPT_ARGS];
+   int option;
+
+   if (!options)
+   return 0;
+
+   while ((p = strsep(options, ,)) != NULL) {
+   int token;
+   if (!*p)
+   continue;
+
+   token = match_token(p, tokens, args);
+   switch (token) {
+   case Opt_addr: {
+   /* physaddr managed in 

[PATCH 03/16 v2] pramfs: inode operations

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Inode methods (allocate/free/read/write).

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/inode.c linux-2.6.36/fs/pramfs/inode.c
--- linux-2.6.36-orig/fs/pramfs/inode.c 1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/inode.c  2010-09-26 18:04:38.0 +0200
@@ -0,0 +1,710 @@
+/*
+ * FILE NAME fs/pramfs/inode.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Inode methods (allocate/free/read/write).
+ *
+ * Copyright 2009-2010 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.h
+#include xattr.h
+#include xip.h
+#include acl.h
+
+struct backing_dev_info pram_backing_dev_info __read_mostly = {
+   .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, unsigned long *blocknr, 
int zero)
+{
+   int errval = pram_new_block(inode-i_sb, blocknr, zero);
+
+   if (!errval) {
+   struct pram_inode *pi = pram_get_inode(inode-i_sb,
+   inode-i_ino);
+   inode-i_blocks++;
+   pram_memunlock_inode(pi);
+   pi-i_blocks = cpu_to_be32(inode-i_blocks);
+   pram_memlock_inode(pi);
+   }
+
+   return errval;
+}
+
+/*
+ * find the offset to the block represented by the given inode's file
+ * relative block number.
+ */
+u64 pram_find_data_block(struct inode *inode, int file_blocknr)
+{
+   struct super_block *sb = inode-i_sb;
+   struct pram_inode *pi;
+   u64 *row; /* ptr to row block */
+   u64 *col; /* ptr to column blocks */
+   u64 bp = 0;
+   int i_row, i_col;
+   int N = sb-s_blocksize  3; /* num block ptrs per block */
+   int Nbits = sb-s_blocksize_bits - 3;
+
+   pi = pram_get_inode(sb, inode-i_ino);
+
+   i_row = file_blocknr  Nbits;
+   i_col  = file_blocknr  (N-1);
+
+   row = pram_get_block(sb, be64_to_cpu(pi-i_type.reg.row_block));
+   if (row) {
+   col = pram_get_block(sb, be64_to_cpu(row[i_row]));
+   if (col)
+   bp = be64_to_cpu(col[i_col]);
+   }
+
+   return bp;
+}
+
+/*
+ * Free data blocks from inode in the range start = end
+ */
+static void __pram_truncate_blocks(struct inode *inode, loff_t start, loff_t 
end)
+{
+   struct super_block *sb = inode-i_sb;
+   struct pram_inode *pi = pram_get_inode(sb, inode-i_ino);
+   int N = sb-s_blocksize  3; /* num block ptrs per block */
+   int Nbits = sb-s_blocksize_bits - 3;
+   int first_row_index, last_row_index, i, j;
+   unsigned long blocknr, first_blocknr, last_blocknr;
+   unsigned int freed = 0;
+   u64 *row; /* ptr to row block */
+   u64 *col; /* ptr to column blocks */
+
+   if (start  end || !inode-i_blocks || !pi-i_type.reg.row_block)
+   return;
+
+   mutex_lock(PRAM_I(inode)-truncate_mutex);
+
+   first_blocknr = (start + sb-s_blocksize - 1)  sb-s_blocksize_bits;
+   last_blocknr = (end + sb-s_blocksize - 1)  sb-s_blocksize_bits;
+   first_row_index = first_blocknr  Nbits;
+   last_row_index  = last_blocknr  Nbits;
+
+   row = pram_get_block(sb, be64_to_cpu(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;
+
+   if (unlikely(!row[i]))
+   continue;
+
+   col = pram_get_block(sb, be64_to_cpu(row[i]));
+
+   for (j = first_col_index; j = last_col_index; j++) {
+
+   if (unlikely(!col[j]))
+   continue;
+
+   blocknr = pram_get_blocknr(sb, be64_to_cpu(col[j]));
+   pram_free_block(sb, blocknr);
+   freed++;
+   pram_memunlock_block(sb, col);
+   col[j] = 0;
+   pram_memlock_block(sb, col);
+   }
+
+   if (first_col_index == 0) {
+ 

[PATCH 04/16 v2] pramfs: file operations

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

File operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/file.c linux-2.6.36/fs/pramfs/file.c
--- linux-2.6.36-orig/fs/pramfs/file.c  1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/file.c   2010-09-24 18:34:03.0 +0200
@@ -0,0 +1,166 @@
+/*
+ * FILE NAME fs/pramfs/file.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * File operations for files.
+ *
+ * Copyright 2009-2010 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/mm.h
+#include linux/uaccess.h
+#include pram.h
+#include acl.h
+#include xip.h
+#include xattr.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);
+}
+
+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, hole = 0;
+   ssize_t retval = 0;
+   void *tmp = NULL;
+   unsigned long blocknr, blockoff;
+   int num_blocks, blocksize_mask, blocksize, blocksize_bits;
+   char __user *buf = iov-iov_base;
+   size_t length = iov_length(iov, nr_segs);
+
+   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 fail1;
+   }
+
+   while (length) {
+   int count;
+   u8 *bp = NULL;
+   u64 block = pram_find_data_block(inode, blocknr++);
+   if (unlikely(!block  rw == READ)) {
+   /* We are falling in a hole */
+   hole = 1;
+   } else {
+   bp = (u8 *)pram_get_block(sb, block);
+   if (!bp)
+   goto fail2;
+   }
+
+   count = blockoff + length  blocksize ?
+   blocksize - blockoff : length;
+
+   if (rw == READ) {
+   if (unlikely(hole)) {
+   retval = clear_user(buf, count);
+   if (retval) {
+   retval = -EFAULT;
+   goto fail1;
+   }
+   } else {
+   retval = copy_to_user(buf, bp[blockoff], 
count);
+   if (retval) {
+   retval = -EFAULT;
+   goto fail1;
+   }
+   }
+   } else {
+   retval = copy_from_user(tmp, buf, count);
+   if (retval) {
+   retval = -EFAULT;
+   goto fail1;
+   }
+
+   pram_memunlock_block(inode-i_sb, bp);
+   memcpy(bp[blockoff], tmp, count);
+   pram_memlock_block(inode-i_sb, bp);
+   }
+
+   progress += count;
+   buf += count;
+   length -= count;
+   blockoff = 0;
+   hole = 0;
+   }
+
+fail2:
+   retval = progress;
+fail1:
+   kfree(tmp);
+out:
+

[PATCH 05/16 v2] pramfs: block allocation

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Block allocation operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/balloc.c linux-2.6.36/fs/pramfs/balloc.c
--- linux-2.6.36-orig/fs/pramfs/balloc.c1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.36/fs/pramfs/balloc.c 2010-09-26 18:05:06.0 +0200
@@ -0,0 +1,155 @@
+/*
+ * FILE NAME fs/pramfs/balloc.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * The blocks allocation and deallocation routines.
+ *
+ * Copyright 2009-2010 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/bitops.h
+#include pram.h
+
+/*
+ * This just marks in-use the blocks that make up the bitmap.
+ * The bitmap must be writeable before calling.
+ */
+void pram_init_bitmap(struct super_block *sb)
+{
+   struct pram_super_block *ps = pram_get_super(sb);
+   u64 *bitmap = pram_get_bitmap(sb);
+   int blocks = be32_to_cpu(ps-s_bitmap_blocks);
+
+   memset(bitmap, 0, blocks  sb-s_blocksize_bits);
+
+   while (blocks = 64) {
+   *bitmap++ = (u64)ULLONG_MAX;
+   blocks -= 64;
+   }
+
+   if (blocks)
+   *bitmap = cpu_to_le64((1ULL  blocks) - 1);
+}
+
+
+/* Free absolute blocknr */
+void pram_free_block(struct super_block *sb, unsigned long blocknr)
+{
+   struct pram_super_block *ps;
+   u64 bitmap_block;
+   unsigned long bitmap_bnr;
+   void *bitmap;
+   void *bp;
+
+   lock_super(sb);
+
+   bitmap = pram_get_bitmap(sb);
+   /*
+* find the block within the bitmap that contains the inuse bit
+* for the block we need to free. We need to unlock this bitmap
+* block to clear the inuse bit.
+*/
+   bitmap_bnr = blocknr  (3 + sb-s_blocksize_bits);
+   bitmap_block = pram_get_block_off(sb, bitmap_bnr);
+   bp = pram_get_block(sb, bitmap_block);
+
+   pram_memunlock_block(sb, bp);
+   pram_clear_bit(blocknr, bitmap); /* mark the block free */
+   pram_memlock_block(sb, bp);
+
+   ps = pram_get_super(sb);
+   pram_memunlock_super(ps);
+   if (blocknr  be32_to_cpu(ps-s_free_blocknr_hint))
+   ps-s_free_blocknr_hint = cpu_to_be32(blocknr);
+   be32_add_cpu(ps-s_free_blocks_count, 1);
+   pram_memlock_super(ps);
+
+   unlock_super(sb);
+}
+
+
+/*
+ * allocate a block and return it's absolute blocknr. Zeroes out the
+ * block if zero set.
+ */
+int pram_new_block(struct super_block *sb, unsigned long *blocknr, int zero)
+{
+   struct pram_super_block *ps;
+   off_t bitmap_block;
+   unsigned long bnr, bitmap_bnr;
+   int errval;
+   void *bitmap;
+   void *bp;
+
+   lock_super(sb);
+   ps = pram_get_super(sb);
+   bitmap = pram_get_bitmap(sb);
+
+   if (ps-s_free_blocks_count) {
+   /* find the oldest unused block */
+   bnr = pram_find_next_zero_bit(bitmap,
+be32_to_cpu(ps-s_blocks_count),
+be32_to_cpu(ps-s_free_blocknr_hint));
+
+   if (bnr  be32_to_cpu(ps-s_bitmap_blocks) ||
+   bnr = be32_to_cpu(ps-s_blocks_count)) {
+   pram_err(no free blocks found!\n);
+   errval = -ENOSPC;
+   goto fail;
+   }
+
+   pram_dbg(allocating blocknr %lu\n, bnr);
+   pram_memunlock_super(ps);
+   be32_add_cpu(ps-s_free_blocks_count, -1);
+   if (bnr  (be32_to_cpu(ps-s_blocks_count)-1))
+   ps-s_free_blocknr_hint = cpu_to_be32(bnr+1);
+   else
+   ps-s_free_blocknr_hint = 0;
+   pram_memlock_super(ps);
+   } else {
+   pram_err(all blocks allocated\n);
+   errval = -ENOSPC;
+   goto fail;
+   }
+
+   /*
+* find the block within the bitmap that contains the inuse bit
+* for the unused block we just found. We need to unlock it to
+* set the inuse bit.
+*/
+   bitmap_bnr = bnr  (3 + sb-s_blocksize_bits);
+   bitmap_block = pram_get_block_off(sb, bitmap_bnr);
+   bp = pram_get_block(sb, bitmap_block);
+
+   pram_memunlock_block(sb, bp);
+   pram_set_bit(bnr, bitmap); /* mark the new block in use */
+   pram_memlock_block(sb, bp);
+
+   if (zero) {
+   bp = pram_get_block(sb, pram_get_block_off(sb, bnr));
+   pram_memunlock_block(sb, bp);
+   memset(bp, 0, sb-s_blocksize);
+   

[PATCH 07/16 v2] pramfs: symbolic links

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Symlink operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/symlink.c 
linux-2.6.36/fs/pramfs/symlink.c
--- linux-2.6.36-orig/fs/pramfs/symlink.c   1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.36/fs/pramfs/symlink.c2010-09-14 18:49:52.0 +0200
@@ -0,0 +1,78 @@
+/*
+ * FILE NAME fs/pramfs/symlink.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Symlink operations
+ *
+ * Copyright 2009-2010 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.h
+#include xattr.h
+
+int pram_block_symlink(struct inode *inode, const char *symname, int len)
+{
+   struct super_block *sb = inode-i_sb;
+   u64 block;
+   char *blockp;
+   int err;
+
+   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_memunlock_block(sb, blockp);
+   memcpy(blockp, symname, len);
+   blockp[len] = '\0';
+   pram_memlock_block(sb, blockp);
+   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;
+   u64 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,
+   .setattr= pram_notify_change,
+#ifdef CONFIG_PRAMFS_XATTR
+   .setxattr   = generic_setxattr,
+   .getxattr   = generic_getxattr,
+   .listxattr  = pram_listxattr,
+   .removexattr= generic_removexattr,
+#endif
+};
 
--
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 08/16 v2] pramfs: headers

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Definitions for the PRAMFS filesystem.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/pram.h linux-2.6.36/fs/pramfs/pram.h
--- linux-2.6.36-orig/fs/pramfs/pram.h  1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/pram.h   2010-10-30 12:02:45.0 +0200
@@ -0,0 +1,317 @@
+/*
+ * FILE NAME pram.h
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Definitions for the PRAMFS filesystem.
+ *
+ * Copyright 2009-2010 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 __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_bitext2_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) == 

[PATCH 09/16 v2] pramfs: dir operations

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

File operations for directories.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/dir.c linux-2.6.36/fs/pramfs/dir.c
--- linux-2.6.36-orig/fs/pramfs/dir.c   1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/dir.c2010-09-17 19:08:54.0 +0200
@@ -0,0 +1,215 @@
+/*
+ * FILE NAME fs/pramfs/dir.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * File operations for directories.
+ *
+ * Copyright 2009-2010 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.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;
+   u64 tail_ino, prev_ino;
+
+   const char *name = dentry-d_name.name;
+
+   int namelen = dentry-d_name.len  PRAM_NAME_LEN ?
+   PRAM_NAME_LEN : dentry-d_name.len;
+
+   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 = be64_to_cpu(pidir-i_type.dir.tail);
+   if (tail_ino != 0) {
+   pitail = pram_get_inode(dir-i_sb, tail_ino);
+   pram_memunlock_inode(pitail);
+   pitail-i_d.d_next = cpu_to_be64(inode-i_ino);
+   pram_memlock_inode(pitail);
+
+   prev_ino = tail_ino;
+
+   pram_memunlock_inode(pidir);
+   pidir-i_type.dir.tail = cpu_to_be64(inode-i_ino);
+   pidir-i_mtime = cpu_to_be32(dir-i_mtime.tv_sec);
+   pidir-i_ctime = cpu_to_be32(dir-i_ctime.tv_sec);
+   pram_memlock_inode(pidir);
+   } else {
+   /* the directory is empty */
+   prev_ino = 0;
+
+   pram_memunlock_inode(pidir);
+   pidir-i_type.dir.tail = cpu_to_be64(inode-i_ino);
+   pidir-i_type.dir.head = cpu_to_be64(inode-i_ino);
+   pidir-i_mtime = cpu_to_be32(dir-i_mtime.tv_sec);
+   pidir-i_ctime = cpu_to_be32(dir-i_ctime.tv_sec);
+   pram_memlock_inode(pidir);
+   }
+
+
+   pram_memunlock_inode(pi);
+   pi-i_d.d_prev = cpu_to_be64(prev_ino);
+   pi-i_d.d_parent = cpu_to_be64(dir-i_ino);
+   memcpy(pi-i_d.d_name, name, namelen);
+   pi-i_d.d_name[namelen] = '\0';
+   pram_memlock_inode(pi);
+   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;
+
+   pi = pram_get_inode(sb, inode-i_ino);
+   pidir = pram_get_inode(sb, be64_to_cpu(pi-i_d.d_parent));
+   if (!pidir)
+   return -EACCES;
+
+   if (inode-i_ino == be64_to_cpu(pidir-i_type.dir.head)) {
+   /* first inode in directory */
+   next = pram_get_inode(sb, be64_to_cpu(pi-i_d.d_next));
+
+   if (next) {
+   pram_memunlock_inode(next);
+   next-i_d.d_prev = 0;
+   pram_memlock_inode(next);
+
+   pram_memunlock_inode(pidir);
+   pidir-i_type.dir.head = pi-i_d.d_next;
+   } else {
+   pram_memunlock_inode(pidir);
+   pidir-i_type.dir.head = 0;
+   pidir-i_type.dir.tail = 0;
+   }
+   pram_memlock_inode(pidir);
+   } else if (inode-i_ino == be64_to_cpu(pidir-i_type.dir.tail)) {
+   /* last inode in directory */
+   prev = pram_get_inode(sb, be64_to_cpu(pi-i_d.d_prev));
+
+   pram_memunlock_inode(prev);
+   prev-i_d.d_next = 0;
+   pram_memlock_inode(prev);
+
+   pram_memunlock_inode(pidir);
+   pidir-i_type.dir.tail = pi-i_d.d_prev;
+   pram_memlock_inode(pidir);
+   } else {
+   /* somewhere in the middle */
+   prev = pram_get_inode(sb, be64_to_cpu(pi-i_d.d_prev));
+   next = pram_get_inode(sb, be64_to_cpu(pi-i_d.d_next));
+
+   if (prev  next) {
+   pram_memunlock_inode(prev);
+   prev-i_d.d_next = pi-i_d.d_next;
+   pram_memlock_inode(prev);
+
+   pram_memunlock_inode(next);
+   next-i_d.d_prev = pi-i_d.d_prev;
+   

[PATCH 10/16 v2] pramfs: XIP operations

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

XIP operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/xip.c linux-2.6.36/fs/pramfs/xip.c
--- linux-2.6.36-orig/fs/pramfs/xip.c   1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/xip.c2010-09-14 18:49:52.0 +0200
@@ -0,0 +1,90 @@
+/*
+ * FILE NAME fs/pramfs/xip.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * XIP operations.
+ *
+ * Copyright 2009-2010 Marco Stornelli marco.storne...@gmail.com
+ * 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/mm.h
+#include linux/fs.h
+#include linux/genhd.h
+#include linux/buffer_head.h
+#include pram.h
+#include xip.h
+
+static int pram_find_and_alloc_blocks(struct inode *inode, sector_t iblock,
+sector_t *data_block, int create)
+{
+   int err = -EIO;
+   u64 block;
+
+   mutex_lock(PRAM_I(inode)-truncate_lock);
+
+   block = pram_find_data_block(inode, iblock);
+
+   if (!block) {
+   if (!create) {
+   err = -ENODATA;
+   goto err;
+   }
+
+   err = pram_alloc_blocks(inode, iblock, 1);
+   if (err)
+   goto err;
+
+   block = pram_find_data_block(inode, iblock);
+   if (!block) {
+   err = -ENODATA;
+   goto err;
+   }
+   }
+
+   *data_block = block;
+   err = 0;
+
+ err:
+   mutex_unlock(PRAM_I(inode)-truncate_lock);
+   return err;
+}
+
+
+static int __pram_get_block(struct inode *inode, pgoff_t pgoff, int create,
+  sector_t *result)
+{
+   int rc = 0;
+   sector_t iblock;
+
+   /* find starting block number to access */
+   iblock = (sector_t)pgoff  (PAGE_CACHE_SHIFT - inode-i_blkbits);
+
+   rc = pram_find_and_alloc_blocks(inode, iblock, result, create);
+
+   if (rc == -ENODATA)
+   BUG_ON(create);
+
+   return rc;
+}
+
+int pram_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create,
+   void **kmem, unsigned long *pfn)
+{
+   int rc;
+   sector_t block;
+
+   /* first, retrieve the block */
+   rc = __pram_get_block(mapping-host, pgoff, create, block);
+   if (rc)
+   goto exit;
+
+   *kmem = pram_get_block(mapping-host-i_sb, block);
+   *pfn = page_to_pfn(virt_to_page((unsigned long)*kmem));
+
+exit:
+   return rc;
+}
diff -Nurp linux-2.6.36-orig/fs/pramfs/xip.h linux-2.6.36/fs/pramfs/xip.h
--- linux-2.6.36-orig/fs/pramfs/xip.h   1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/xip.h2010-09-14 18:49:52.0 +0200
@@ -0,0 +1,24 @@
+/*
+ * FILE NAME fs/pramfs/xip.h
+ *
+ * BRIEF DESCRIPTION
+ *
+ * XIP operations.
+ *
+ * Copyright 2009-2010 Marco Stornelli marco.storne...@gmail.com
+ * 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.
+ */
+
+#ifdef CONFIG_PRAMFS_XIP
+
+int pram_get_xip_mem(struct address_space *, pgoff_t, int, void **,
+ unsigned long *);
+
+#else
+
+#define pram_get_xip_mem NULL
+
+#endif
+
 
--
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/16 v2] pramfs: ACL management

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

ACL operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/acl.c linux-2.6.36/fs/pramfs/acl.c
--- linux-2.6.36-orig/fs/pramfs/acl.c   1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/acl.c2010-09-14 18:49:52.0 +0200
@@ -0,0 +1,418 @@
+/*
+ * FILE NAME fs/pramfs/acl.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * POSIX ACL operations
+ *
+ * Copyright 2010 Marco Stornelli marco.storne...@gmail.com
+ *
+ * based on fs/ext2/acl.c with the following copyright:
+ *
+ * Copyright (C) 2001-2003 Andreas Gruenbacher, agr...@suse.de
+ *
+ * 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/capability.h
+#include linux/init.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/fs.h
+#include pram.h
+#include xattr.h
+#include acl.h
+
+/*
+ * Load ACL information from filesystem.
+ */
+static struct posix_acl *pram_acl_load(const void *value, size_t size)
+{
+   const char *end = (char *)value + size;
+   int n, count;
+   struct posix_acl *acl;
+
+   if (!value)
+   return NULL;
+   if (size  sizeof(struct pram_acl_header))
+return ERR_PTR(-EINVAL);
+   if (((struct pram_acl_header *)value)-a_version !=
+   cpu_to_be32(PRAM_ACL_VERSION))
+   return ERR_PTR(-EINVAL);
+   value = (char *)value + sizeof(struct pram_acl_header);
+   count = pram_acl_count(size);
+   if (count  0)
+   return ERR_PTR(-EINVAL);
+   if (count == 0)
+   return NULL;
+   acl = posix_acl_alloc(count, GFP_KERNEL);
+   if (!acl)
+   return ERR_PTR(-ENOMEM);
+   for (n = 0; n  count; n++) {
+   struct pram_acl_entry *entry = (struct pram_acl_entry *)value;
+   if ((char *)value + sizeof(struct pram_acl_entry_short)  end)
+   goto fail;
+   acl-a_entries[n].e_tag  = be16_to_cpu(entry-e_tag);
+   acl-a_entries[n].e_perm = be16_to_cpu(entry-e_perm);
+   switch (acl-a_entries[n].e_tag) {
+   case ACL_USER_OBJ:
+   case ACL_GROUP_OBJ:
+   case ACL_MASK:
+   case ACL_OTHER:
+   value = (char *)value +
+   sizeof(struct pram_acl_entry_short);
+   acl-a_entries[n].e_id = ACL_UNDEFINED_ID;
+   break;
+   case ACL_USER:
+   case ACL_GROUP:
+   value = (char *)value + sizeof(struct pram_acl_entry);
+   if ((char *)value  end)
+   goto fail;
+   acl-a_entries[n].e_id =
+   be32_to_cpu(entry-e_id);
+   break;
+   default:
+   goto fail;
+   }
+   }
+   if (value != end)
+   goto fail;
+   return acl;
+
+fail:
+   posix_acl_release(acl);
+   return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Save ACL information into the filesystem.
+ */
+static void *pram_acl_save(const struct posix_acl *acl, size_t *size)
+{
+   struct pram_acl_header *ext_acl;
+   char *e;
+   size_t n;
+
+   *size = pram_acl_size(acl-a_count);
+   ext_acl = kmalloc(sizeof(struct pram_acl_header) + acl-a_count *
+   sizeof(struct pram_acl_entry), GFP_KERNEL);
+   if (!ext_acl)
+   return ERR_PTR(-ENOMEM);
+   ext_acl-a_version = cpu_to_be32(PRAM_ACL_VERSION);
+   e = (char *)ext_acl + sizeof(struct pram_acl_header);
+   for (n = 0; n  acl-a_count; n++) {
+   struct pram_acl_entry *entry = (struct pram_acl_entry *)e;
+   entry-e_tag  = cpu_to_be16(acl-a_entries[n].e_tag);
+   entry-e_perm = cpu_to_be16(acl-a_entries[n].e_perm);
+   switch (acl-a_entries[n].e_tag) {
+   case ACL_USER:
+   case ACL_GROUP:
+   entry-e_id =
+   cpu_to_be32(acl-a_entries[n].e_id);
+   e += sizeof(struct pram_acl_entry);
+   break;
+   case ACL_USER_OBJ:
+   case ACL_GROUP_OBJ:
+   case ACL_MASK:
+   case ACL_OTHER:
+   e += sizeof(struct pram_acl_entry_short);
+   break;
+   default:
+   goto fail;
+   }
+   }
+   return (char *)ext_acl;
+
+fail:
+   kfree(ext_acl);
+   return ERR_PTR(-EINVAL);
+}
+
+/*
+ * inode-i_mutex: don't care
+ */
+static struct posix_acl *pram_get_acl(struct inode *inode, int type)
+{
+   int name_index;
+   char *value = NULL;
+   struct posix_acl 

[PATCH 12/16 v2] pramfs: extended attributes

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Extended attributes operations.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/xattr.c linux-2.6.36/fs/pramfs/xattr.c
--- linux-2.6.36-orig/fs/pramfs/xattr.c 1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/xattr.c  2010-09-14 19:45:40.0 +0200
@@ -0,0 +1,1108 @@
+/*
+ * FILE NAME fs/pramfs/xattr.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Extended attributes operations.
+ *
+ * Copyright 2010 Marco Stornelli marco.storne...@gmail.com
+ *
+ * based on fs/ext2/xattr.c with the following copyright:
+ *
+ * Fix by Harrison Xing harri...@mountainviewdata.com.
+ * Extended attributes for symlinks and special files added per
+ *  suggestion of Luka Renko luka.re...@hermes.si.
+ * xattr consolidation Copyright (c) 2004 James Morris jmor...@redhat.com,
+ *  Red Hat Inc.
+ *
+ * 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.
+ */
+
+/*
+ * Extended attributes are stored in blocks allocated outside of
+ * any inode. The i_xattr field is then made to point to this allocated
+ * block. If all extended attributes of an inode are identical, these
+ * inodes may share the same extended attribute block. Such situations
+ * are automatically detected by keeping a cache of recent attribute block
+ * numbers and hashes over the block's contents in memory.
+ *
+ *
+ * Extended attribute block layout:
+ *
+ *   +--+
+ *   | header   |
+ *   | entry 1  | |
+ *   | entry 2  | | growing downwards
+ *   | entry 3  | v
+ *   | four null bytes  |
+ *   | . . .|
+ *   | value 1  | ^
+ *   | value 3  | | growing upwards
+ *   | value 2  | |
+ *   +--+
+ *
+ * The block header is followed by multiple entry descriptors. These entry
+ * descriptors are variable in size, and alligned to PRAM_XATTR_PAD
+ * byte boundaries. The entry descriptors are sorted by attribute name,
+ * so that two extended attribute blocks can be compared efficiently.
+ *
+ * Attribute values are aligned to the end of the block, stored in
+ * no specific order. They are also padded to PRAM_XATTR_PAD byte
+ * boundaries. No additional gaps are left between them.
+ *
+ * Locking strategy
+ * 
+ * pi-i_xattr is protected by PRAM_I(inode)-xattr_sem.
+ * EA blocks are only changed if they are exclusive to an inode, so
+ * holding xattr_sem also means that nothing but the EA block's reference
+ * count will change. Multiple writers to an EA block are synchronized
+ * by the mutex in each block descriptor. Block descriptors are kept in a
+ * red black tree and the key is the absolute block number.
+ */
+
+#include linux/module.h
+#include linux/init.h
+#include linux/mbcache.h
+#include linux/rwsem.h
+#include linux/security.h
+#include pram.h
+#include xattr.h
+#include acl.h
+#include desctree.h
+
+#define HDR(bp) ((struct pram_xattr_header *)(bp))
+#define ENTRY(ptr) ((struct pram_xattr_entry *)(ptr))
+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
+#define GET_DESC(sbi, blocknr) lookup_xblock_desc(sbi, blocknr, 
pram_xblock_desc_cache, 1)
+#define LOOKUP_DESC(sbi, blocknr) lookup_xblock_desc(sbi, blocknr, NULL, 0)
+
+#ifdef PRAM_XATTR_DEBUG
+# define ea_idebug(inode, f...) do { \
+   printk(KERN_DEBUG inode %ld: , inode-i_ino); \
+   printk(f); \
+   printk(\n); \
+   } while (0)
+# define ea_bdebug(blocknr, f...) do { \
+   printk(KERN_DEBUG block %lu: , blocknr); \
+   printk(f); \
+   printk(\n); \
+   } while (0)
+#else
+# define ea_idebug(f...)
+# define ea_bdebug(f...)
+#endif
+
+static int pram_xattr_set2(struct inode *, char *, struct pram_xblock_desc *, 
struct pram_xattr_header *);
+
+static int pram_xattr_cache_insert(struct super_block *sb, unsigned long 
blocknr, u32 xhash);
+static struct pram_xblock_desc *pram_xattr_cache_find(struct inode *,
+struct pram_xattr_header *);
+static void pram_xattr_rehash(struct pram_xattr_header *,
+ struct pram_xattr_entry *);
+
+static struct mb_cache *pram_xattr_cache;
+static struct kmem_cache *pram_xblock_desc_cache;
+
+static const struct xattr_handler *pram_xattr_handler_map[] = {
+   [PRAM_XATTR_INDEX_USER]  = pram_xattr_user_handler,
+#ifdef CONFIG_PRAMFS_POSIX_ACL
+   [PRAM_XATTR_INDEX_POSIX_ACL_ACCESS]  = pram_xattr_acl_access_handler,
+   [PRAM_XATTR_INDEX_POSIX_ACL_DEFAULT] = pram_xattr_acl_default_handler,
+#endif
+   [PRAM_XATTR_INDEX_TRUSTED]   = pram_xattr_trusted_handler,
+#ifdef CONFIG_PRAMFS_SECURITY
+   [PRAM_XATTR_INDEX_SECURITY]  = pram_xattr_security_handler,
+#endif
+};
+
+const 

[PATCH 13/16 v2] pramfs: xattr block descriptors tree

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Extended attributes block descriptors tree.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/desctree.c 
linux-2.6.36/fs/pramfs/desctree.c
--- linux-2.6.36-orig/fs/pramfs/desctree.c  1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.36/fs/pramfs/desctree.c   2010-09-14 18:49:52.0 +0200
@@ -0,0 +1,184 @@
+/*
+ * FILE NAME fs/pramfs/desctree.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Extended attributes block descriptors tree.
+ *
+ * Copyright 2010 Marco Stornelli marco.storne...@gmail.com
+ *
+ * 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/spinlock.h
+#include desctree.h
+#include pram.h
+
+/* xblock_desc_init_always()
+ *
+ * These are initializations that need to be done on every
+ * descriptor allocation as the fields are not initialised
+ * by slab allocation.
+ */
+void xblock_desc_init_always(struct pram_xblock_desc *desc)
+{
+   atomic_set(desc-refcount, 0);
+   desc-blocknr = 0;
+   desc-flags = 0;
+}
+
+/* xblock_desc_init_once()
+ *
+ * These are initializations that only need to be done
+ * once, because the fields are idempotent across use
+ * of the descriptor, so let the slab aware of that.
+ */
+void xblock_desc_init_once(struct pram_xblock_desc *desc)
+{
+   mutex_init(desc-lock);
+}
+
+/* __insert_xblock_desc()
+ *
+ * Insert a new descriptor in the tree.
+ *
+ */
+static void __insert_xblock_desc(struct pram_sb_info *sbi,
+unsigned long blocknr, struct rb_node *node)
+{
+   struct rb_node **p = (sbi-desc_tree.rb_node);
+   struct rb_node *parent = NULL;
+   struct pram_xblock_desc *desc;
+
+   while (*p) {
+   parent = *p;
+   desc = rb_entry(parent, struct pram_xblock_desc, node);
+
+   if (blocknr  desc-blocknr)
+   p = (*p)-rb_left;
+   else if (blocknr  desc-blocknr)
+   p = (*p)-rb_right;
+   else
+   /* Oops...an other descriptor for the same block ? */
+   BUG();
+   }
+
+   rb_link_node(node, parent, p);
+   rb_insert_color(node, sbi-desc_tree);
+}
+
+void insert_xblock_desc(struct pram_sb_info *sbi, struct pram_xblock_desc 
*desc)
+{
+   spin_lock(sbi-desc_tree_lock);
+   __insert_xblock_desc(sbi, desc-blocknr, desc-node);
+   spin_unlock(sbi-desc_tree_lock);
+};
+
+/* __lookup_xblock_desc()
+ *
+ * Search an extended attribute descriptor in the tree via the
+ * block number. It returns the descriptor if it's found or
+ * NULL. If not found it creates a new descriptor if create is not 0.
+ */
+static struct pram_xblock_desc *__lookup_xblock_desc(struct pram_sb_info *sbi,
+   unsigned long blocknr,
+   struct kmem_cache *cache,
+   int create)
+{
+   struct rb_node *n = sbi-desc_tree.rb_node;
+   struct pram_xblock_desc *desc = NULL;
+
+   while (n) {
+   desc = rb_entry(n, struct pram_xblock_desc, node);
+
+   if (blocknr  desc-blocknr)
+   n = n-rb_left;
+   else if (blocknr  desc-blocknr)
+   n = n-rb_right;
+   else {
+   atomic_inc(desc-refcount);
+   goto out;
+   }
+   }
+
+   /* not found */
+   if (create) {
+   desc = kmem_cache_alloc(cache, GFP_NOFS);
+   if (!desc)
+   return ERR_PTR(-ENOMEM);
+   xblock_desc_init_always(desc);
+   atomic_set(desc-refcount, 1);
+   desc-blocknr = blocknr;
+   __insert_xblock_desc(sbi, desc-blocknr, desc-node);
+   }
+out:
+   return desc;
+}
+
+struct pram_xblock_desc *lookup_xblock_desc(struct pram_sb_info *sbi,
+   unsigned long blocknr,
+   struct kmem_cache *cache,
+   int create)
+{
+   struct pram_xblock_desc *desc = NULL;
+
+   spin_lock(sbi-desc_tree_lock);
+   desc = __lookup_xblock_desc(sbi, blocknr, cache, create);
+   spin_unlock(sbi-desc_tree_lock);
+   return desc;
+}
+
+/* put_xblock_desc()
+ *
+ * Decrement the reference count and if it reaches zero and the
+ * desciptor has been marked to be free, then we free it.
+ * It returns 0 if the descriptor has been deleted and 1 otherwise.
+ */
+int put_xblock_desc(struct pram_sb_info *sbi, struct pram_xblock_desc *desc)
+{
+   int ret = 1;
+   if (!desc)
+   return ret;
+
+   if (atomic_dec_and_lock(desc-refcount, sbi-desc_tree_lock)) {
+

[PATCH 15/16 v2] pramfs: test module

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Test module.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/pramfs_test.c 
linux-2.6.36/fs/pramfs/pramfs_test.c
--- linux-2.6.36-orig/fs/pramfs/pramfs_test.c   1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.36/fs/pramfs/pramfs_test.c2010-09-14 18:49:52.0 
+0200
@@ -0,0 +1,49 @@
+/*
+ * FILE NAME fs/pramfs/namei.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Pramfs test module.
+ *
+ * Copyright 2009-2010 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.h
+
+int __init test_pramfs_write(void)
+{
+   struct pram_super_block *psb;
+
+   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 checksum information in the
+* superblock, this should cause a kernel page protection fault.
+*/
+   printk(%s: writing to kernel VA %p\n, __func__, psb);
+   psb-s_sum = 0;
+
+   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 16/16 v2] pramfs: Makefile and Kconfig

2010-11-06 Thread Marco Stornelli
From: Marco Stornelli marco.storne...@gmail.com

Makefile and Kconfig.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/Makefile linux-2.6.36/fs/Makefile
--- linux-2.6.36-orig/fs/Makefile   2010-09-13 01:07:37.0 +0200
+++ linux-2.6.36/fs/Makefile2010-09-14 18:49:52.0 +0200
@@ -126,3 +126,4 @@ obj-$(CONFIG_BTRFS_FS)  += btrfs/
 obj-$(CONFIG_GFS2_FS)   += gfs2/
 obj-$(CONFIG_EXOFS_FS)  += exofs/
 obj-$(CONFIG_CEPH_FS)  += ceph/
+obj-$(CONFIG_PRAMFS)   += pramfs/
diff -Nurp linux-2.6.36-orig/fs/Kconfig linux-2.6.36/fs/Kconfig
--- linux-2.6.36-orig/fs/Kconfig2010-09-13 01:07:37.0 +0200
+++ linux-2.6.36/fs/Kconfig 2010-09-14 18:49:52.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
@@ -25,13 +25,14 @@ config FS_MBCACHE
default y if EXT2_FS=y  EXT2_FS_XATTR
default y if EXT3_FS=y  EXT3_FS_XATTR
default y if EXT4_FS=y  EXT4_FS_XATTR
-   default m if EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4_FS_XATTR
+   default y if PRAMFS=y  PRAMFS_XATTR
+   default m if EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4_FS_XATTR || 
PRAMFS_XATTR
  source fs/reiserfs/Kconfig
 source fs/jfs/Kconfig
  config FS_POSIX_ACL
-# Posix ACL utility routines (for now, only ext2/ext3/jfs/reiserfs/nfs4)
+# Posix ACL utility routines (for now, only ext2/ext3/jfs/reiserfs/nfs4/pramfs)
 #
 # NOTE: you can implement Posix ACLs without these helpers (XFS does).
 #  Never use this symbol for ifdefs.
@@ -189,6 +190,7 @@ source fs/romfs/Kconfig
 source fs/sysv/Kconfig
 source fs/ufs/Kconfig
 source fs/exofs/Kconfig
+source fs/pramfs/Kconfig
  endif # MISC_FILESYSTEMS
 diff -Nurp linux-2.6.36-orig/fs/pramfs/Kconfig linux-2.6.36/fs/pramfs/Kconfig
--- linux-2.6.36-orig/fs/pramfs/Kconfig 1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/Kconfig  2010-10-30 10:30:19.0 +0200
@@ -0,0 +1,72 @@
+config PRAMFS
+   tristate Persistent and Protected RAM file system support
+   depends on HAS_IOMEM  EXPERIMENTAL
+   select CRC16
+   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  !PRAMFS_WRITE_PROTECT
+   help
+  Say Y here to enable XIP feature of PRAMFS.
+
+config PRAMFS_WRITE_PROTECT
+   bool Enable PRAMFS write protection
+   depends on PRAMFS  MMU  HAVE_SET_MEMORY_RO
+   default y
+   help
+  Say Y here to enable the write protect feature of PRAMFS.
+
+config PRAMFS_XATTR
+   bool PRAMFS extended attributes
+   depends on PRAMFS
+   help
+ Extended attributes are name:value pairs associated with inodes by
+ the kernel or by users (see the attr(5) manual page, or visit
+ http://acl.bestbits.at/ for details).
+
+ If unsure, say N.
+
+config PRAMFS_POSIX_ACL
+   bool PRAMFS POSIX Access Control Lists
+   depends on PRAMFS_XATTR
+   select FS_POSIX_ACL
+   help
+ Posix Access Control Lists (ACLs) support permissions for users and
+ groups beyond the owner/group/world scheme.
+
+ To learn more about Access Control Lists, visit the Posix ACLs for
+ Linux website http://acl.bestbits.at/.
+
+ If you don't know what Access Control Lists are, say N.
+
+config PRAMFS_SECURITY
+   bool PRAMFS Security Labels
+   depends on PRAMFS_XATTR
+   help
+ Security labels support alternative access control models
+ implemented by security modules like SELinux.  This option
+ enables an extended attribute handler for file security
+ labels in the pram filesystem.
+
+ If you are not using a security module that requires using
+ extended attributes for file security labels, say N.
+
+config PRAMFS_TEST
+   boolean
+   depends on PRAMFS
+
+config TEST_MODULE
+   tristate PRAMFS Test
+   depends on PRAMFS  m
+   select PRAMFS_TEST
+   help
+ Say Y here to build a simple module to test the protection of
+ PRAMFS. The module will be called pramfs_test.
diff -Nurp linux-2.6.36-orig/fs/pramfs/Makefile linux-2.6.36/fs/pramfs/Makefile
--- linux-2.6.36-orig/fs/pramfs/Makefile1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.36/fs/pramfs/Makefile 2010-09-14 18:49:52.0 +0200
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux 

Re: [PATCH 01/16 v2] pramfs: documentation

2010-11-06 Thread James Hogan
Hi,

On Sat, Nov 06, 2010 at 09:56:18AM +0100, Marco Stornelli wrote:
 From: Marco Stornelli marco.storne...@gmail.com
 +PRAMFS is write protected. The page table entries that map the backing-store
 +RAM are normally marked read-only. Write operations into the filesystem
 +temporarily mark the affected pages as writeable, the write operation is
 +carried out with locks held, and then the page table entries is +marked 
 read-only again.
 +This feature provides protection against filesystem corruption caused by 
 errant

Looks like an accidental lost newline in the patch here, should that be
are marked or is there some text missing?

Cheers
James
--
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 12/16] pramfs: extended attributes

2010-11-06 Thread James Hogan
Hi Marco,

On Sun, Oct 10, 2010 at 06:34:29PM +0200, Marco Stornelli wrote:
 From: Marco Stornelli marco.storne...@gmail.com
 diff -Nurp linux-2.6.36-orig/fs/pramfs/xattr.h linux-2.6.36/fs/pramfs/xattr.h
 --- linux-2.6.36-orig/fs/pramfs/xattr.h   1970-01-01 01:00:00.0 
 +0100
 +++ linux-2.6.36/fs/pramfs/xattr.h2010-09-18 08:40:35.0 +0200
 @@ -0,0 +1,134 @@
 +/*
 + * FILE NAME fs/pramfs/xattr.h
 + *
 + * BRIEF DESCRIPTION
 + *
 + * Extended attributes for the pram filesystem.
 + *
 + * Copyright 2010 Marco Stornelli marco.storne...@gmail.com
 + *
 + * based on fs/ext2/xattr.h with the following copyright:
 + *
 + *(C) 2001 Andreas Gruenbacher, a.gruenbac...@computer.org
 + *
 + * 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/init.h
 +#include linux/xattr.h
 +
 +/* Magic value in attribute blocks */
 +#define PRAM_XATTR_MAGIC 0x6d617270
 +
 +/* Maximum number of references to one attribute block */
 +#define PRAM_XATTR_REFCOUNT_MAX  1024
 +
 +/* Name indexes */
 +#define PRAM_XATTR_INDEX_USER1
 +#define PRAM_XATTR_INDEX_POSIX_ACL_ACCESS2
 +#define PRAM_XATTR_INDEX_POSIX_ACL_DEFAULT   3
 +#define PRAM_XATTR_INDEX_TRUSTED 4
 +#define  PRAM_XATTR_INDEX_LUSTRE 5
 +#define PRAM_XATTR_INDEX_SECURITY6

Maybe nobody minds, but there's some inconsistent whitespace here.

Cheers
James
--
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 10/16 v2] pramfs: XIP operations

2010-11-06 Thread James Hogan
Hi,

On Sat, Nov 06, 2010 at 09:59:27AM +0100, Marco Stornelli wrote:
 diff -Nurp linux-2.6.36-orig/fs/pramfs/xip.c linux-2.6.36/fs/pramfs/xip.c
 --- linux-2.6.36-orig/fs/pramfs/xip.c 1970-01-01 01:00:00.0 +0100
 +++ linux-2.6.36/fs/pramfs/xip.c  2010-09-14 18:49:52.0 +0200
snip
 +static int pram_find_and_alloc_blocks(struct inode *inode, sector_t iblock,
 +  sector_t *data_block, int create)
 +{
 + int err = -EIO;
 + u64 block;
 +
 + mutex_lock(PRAM_I(inode)-truncate_lock);

fs/pramfs/xip.c: In function ‘pram_find_and_alloc_blocks’:
fs/pramfs/xip.c:27: error: ‘struct pram_inode_vfs’ has no member named
‘truncate_lock’
fs/pramfs/xip.c:52: error: ‘struct pram_inode_vfs’ has no member named
‘truncate_lock’

i guess that should be truncate_mutex.

 +
 + block = pram_find_data_block(inode, iblock);
 +
 + if (!block) {
 + if (!create) {
 + err = -ENODATA;
 + goto err;
 + }
 +
 + err = pram_alloc_blocks(inode, iblock, 1);
 + if (err)
 + goto err;
 +
 + block = pram_find_data_block(inode, iblock);
 + if (!block) {
 + err = -ENODATA;
 + goto err;
 + }
 + }
 +
 + *data_block = block;
 + err = 0;
 +
 + err:
 + mutex_unlock(PRAM_I(inode)-truncate_lock);

same here

 + return err;
 +}

Cheers
James
--
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 01/16 v2] pramfs: documentation

2010-11-06 Thread Marco Stornelli
Il 06/11/2010 11:39, James Hogan ha scritto:
 Hi,
 
 On Sat, Nov 06, 2010 at 09:56:18AM +0100, Marco Stornelli wrote:
 From: Marco Stornelli marco.storne...@gmail.com
 +PRAMFS is write protected. The page table entries that map the backing-store
 +RAM are normally marked read-only. Write operations into the filesystem
 +temporarily mark the affected pages as writeable, the write operation is
 +carried out with locks held, and then the page table entries is +marked 
 read-only again.
 +This feature provides protection against filesystem corruption caused by 
 errant
 
 Looks like an accidental lost newline in the patch here, should that be
 are marked or is there some text missing?
 

My fault, a problem during email formatting. I'll resend this patch.

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


Re: [PATCH 02/16 v2] pramfs: super block operations

2010-11-06 Thread Marco Stornelli
Il 06/11/2010 12:16, James Hogan ha scritto:
 Hi Marco,
 
 On Sat, Nov 06, 2010 at 09:56:39AM +0100, Marco Stornelli wrote:
 From: Marco Stornelli marco.storne...@gmail.com
 +static void pram_set_blocksize(struct super_block *sb, unsigned long size)
 +{
 +int bits;
 +
 +/*
 +* We've already validated the user input and the value here must be
 +* between PRAM_MAX_BLOCK_SIZE and PRAM_MIN_BLOCK_SIZE
 +* and it must be a power of 2.
 +*/
 
 Should this comment have spaces after the tabs to be consistent with the
 other multiline comments (pram_ioremap) and the coding style?
 

Ok, no problem.

Thanks for the review.

Regards,

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


Re: [PATCH 10/16 v2] pramfs: XIP operations

2010-11-06 Thread Marco Stornelli
Il 06/11/2010 14:33, James Hogan ha scritto:
 Hi,
 
 On Sat, Nov 06, 2010 at 09:59:27AM +0100, Marco Stornelli wrote:
 diff -Nurp linux-2.6.36-orig/fs/pramfs/xip.c linux-2.6.36/fs/pramfs/xip.c
 --- linux-2.6.36-orig/fs/pramfs/xip.c1970-01-01 01:00:00.0 
 +0100
 +++ linux-2.6.36/fs/pramfs/xip.c 2010-09-14 18:49:52.0 +0200
 snip
 +static int pram_find_and_alloc_blocks(struct inode *inode, sector_t iblock,
 + sector_t *data_block, int create)
 +{
 +int err = -EIO;
 +u64 block;
 +
 +mutex_lock(PRAM_I(inode)-truncate_lock);
 
 fs/pramfs/xip.c: In function ‘pram_find_and_alloc_blocks’:
 fs/pramfs/xip.c:27: error: ‘struct pram_inode_vfs’ has no member named
 ‘truncate_lock’
 fs/pramfs/xip.c:52: error: ‘struct pram_inode_vfs’ has no member named
 ‘truncate_lock’
 
 i guess that should be truncate_mutex.
 

Oops, my fault, yes it's truncate_mutex. I'll fix it asap.

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


Re: [PATCH 15/16 v2] pramfs: test module

2010-11-06 Thread Randy Dunlap
On Sat, 06 Nov 2010 10:01:12 +0100 Marco Stornelli wrote:

 From: Marco Stornelli marco.storne...@gmail.com
 
 Test module.
 
 Signed-off-by: Marco Stornelli marco.storne...@gmail.com
 ---
 diff -Nurp linux-2.6.36-orig/fs/pramfs/pramfs_test.c 
 linux-2.6.36/fs/pramfs/pramfs_test.c
 --- linux-2.6.36-orig/fs/pramfs/pramfs_test.c 1970-01-01 01:00:00.0 
 +0100
 +++ linux-2.6.36/fs/pramfs/pramfs_test.c  2010-09-14 18:49:52.0 
 +0200
 @@ -0,0 +1,49 @@
 +/*
 + * FILE NAME fs/pramfs/namei.c
 + *
 + * BRIEF DESCRIPTION
 + *
 + * Pramfs test module.


Wrong FILE NAME.  Better to just omit it completely.

---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
--
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 16/16 v2] pramfs: Makefile and Kconfig

2010-11-06 Thread Randy Dunlap
On Sat, 06 Nov 2010 10:01:29 +0100 Marco Stornelli wrote:

 From: Marco Stornelli marco.storne...@gmail.com
 
 Makefile and Kconfig.
 
 Signed-off-by: Marco Stornelli marco.storne...@gmail.com
 ---
 +config TEST_MODULE
 + tristate PRAMFS Test
 + depends on PRAMFS  m
 + select PRAMFS_TEST
 + help
 +   Say Y here to build a simple module to test the protection of
 +   PRAMFS. The module will be called pramfs_test.

Since kconfig symbols are global, this one needs something like
PRAMFS_ as a prefix, please.


 diff -Nurp linux-2.6.36-orig/fs/pramfs/Makefile 
 linux-2.6.36/fs/pramfs/Makefile
 --- linux-2.6.36-orig/fs/pramfs/Makefile  1970-01-01 01:00:00.0 
 +0100
 +++ linux-2.6.36/fs/pramfs/Makefile   2010-09-14 18:49:52.0 +0200
 @@ -0,0 +1,14 @@
 +#
 +# Makefile for the linux pram-filesystem routines.
 +#
 +
 +obj-$(CONFIG_PRAMFS) += pramfs.o
 +obj-$(CONFIG_TEST_MODULE) += pramfs_test.o
 +
 +pramfs-y := balloc.o dir.o file.o inode.o namei.o super.o symlink.o
 +
 +pramfs-$(CONFIG_PRAMFS_WRITE_PROTECT) += wprotect.o
 +pramfs-$(CONFIG_PRAMFS_XIP) += xip.o
 +pramfs-$(CONFIG_PRAMFS_XATTR) += xattr.o xattr_user.o xattr_trusted.o 
 desctree.o
 +pramfs-$(CONFIG_PRAMFS_POSIX_ACL) += acl.o
 +pramfs-$(CONFIG_PRAMFS_SECURITY) += xattr_security.o


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
--
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