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

2010-10-10 Thread Marco Stornelli
Hi all,

after a lot of improvement, test, bug fix and new features, it's the
moment for third round with the kernel community to submit PRAMFS for
mainline.

Since the last review (June 2009) a lot of things are changed:

- removed any reference of BKL
- fixed the endianess for the fs layout
- added support for extended attributes, ACLs and security labels
- moved out any pte manipulations from fs and inserted them in mm
- implemented the new truncate convention
- fixed problems with 64bit archs

...and much more. Complete story in the ChangeLog inserted in the
documentation file.

In addition, in the web site tech page (http:\\pramfs.sourceforge.net),
you can find a lot of information about implementation, technical
details, benchmarking and so on.

All the work to mainline this feature is sponsored by the CE Linux Forum.

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


[PATCH 02/16] pramfs: super block operations

2010-10-10 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 06/16] pramfs: inode operations for dirs

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

Inode operations for directories.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/namei.c linux-2.6.36/fs/pramfs/namei.c
--- linux-2.6.36-orig/fs/pramfs/namei.c 1970-01-01 01:00:00.0 +0100
+++ linux-2.6.36/fs/pramfs/namei.c  2010-09-18 12:00:35.0 +0200
@@ -0,0 +1,363 @@
+/*
+ * FILE NAME fs/pramfs/namei.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Inode 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
+#include acl.h
+#include xattr.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);
+   unlock_new_inode(inode);
+   return 0;
+   }
+   pram_dec_count(inode);
+   unlock_new_inode(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 = be64_to_cpu(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 = be64_to_cpu(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) {
+   inode = pram_iget(dir-i_sb, ino);
+   if (!inode)
+   return ERR_PTR(-EACCES);
+   }
+
+   d_splice_alias(inode, dentry);
+   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;
+
+

[PATCH 05/16] pramfs: block allocation

2010-10-10 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] pramfs: symbolic links

2010-10-10 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


logfs segfaults at umount time

2010-10-10 Thread Michael Opdenacker
Hi Jörn,

I'm running some flash filesystem benchmarks for CELF, and I'm facing
kernel segfaults when I try to umount my logfs filesystem.

This happens with both 2.6.35 and 2.6.36-rc7. See the below trace.

Has anyone else faced the same kind of issue? Don't hesitate to get back
to me if you need more details or if there are commands you would like
me to run.

Thank you in advance for your help,

Cheers,

Michael.


r...@calao:~# cat /proc/cmdline
console=ttyS0,115200n8 root=/dev/nfs ip=192.168.2.100
nfsroot=192.168.2.1:/home/mike/work/celf/RFS mtdparts=atmel_nand:128m(Main)
r...@calao:~# flash_eraseall /dev/mtd0
Erasing 128 Kibyte @ 800 -- 100 % complete.
r...@calao:~# mkfs.logfs /dev/mtdblock0
Will create filesystem with the following details:
  hex:   decimal:
fssize=800  134217728
segsize= 4 262144
blocksize=1000   4096
writesize=   1  1

Do you wish to continue (yes/no)
yes

Finished generating LogFS
r...@calao:~# mount -t logfs /dev/mtdblock0 /mnt/flash/
r...@calao:~# cp -rf /fs/8m/* /mnt/flash/
eth0: TX underrun, resetting buffers
eth0: TX underrun, resetting buffers
r...@calao:~# umount /mnt/flash/
kernel BUG at fs/logfs/segment.c:858!
Unable to handle kernel NULL pointer dereference at virtual address 
pgd = c14a4000
[] *pgd=23a3c031, *pte=, *ppte=
Internal error: Oops: 817 [#1]
last sysfs file: /sys/devices/virtual/vc/vcs6/uevent
Modules linked in: logfs zlib_deflate zlib_inflate
CPU: 0Not tainted  (2.6.36-rc7 #1)
PC is at __bug+0x18/0x24
LR is at __bug+0x14/0x24
pc : [c0025764]lr : [c0025760]psr: 2013
sp : c2d91e18  ip :   fp : c2d91e84
r10: c03c3b80  r9 : 0009  r8 : 
r7 : c2d91e60  r6 : c3601d58  r5 : c3601d58  r4 : c03c3b80
r3 :   r2 : c033e368  r1 : 6013  r0 : 002c
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: 214a4000  DAC: 0015
Process umount (pid: 1292, stack limit = 0xc2d90270)
Stack: (0xc2d91e18 to 0xc2d92000)
1e00:   bf022620
bf022630
1e20: bf022620 c0078360  c0078a04  c3601d58 c2d91e60

1e40: 000e 0081  c3601d58 c2d91e60 c0078b2c 

1e60: 000e  c03e01a0 c03e01c0 c03e01e0 c03df100 c03df120
c03df140
1e80: c03df160 c03df180 c03df1a0 c03c3b80 c03986c0 c0398e40 c03c3ba0
c03c3bc0
1ea0:     c2c1f800 c2d9 c380dc60
c380dc78
1ec0:  c0078d70   c3601760 c3601cb8 c2c1f800
bf022104
1ee0: c3691830 c3601760 c035e708 c3601cb8 c035e708 c2c1f800 c035e848
c2d9
1f00: c380dc60 c380dc78  c00a90f4 c3601cb8 c00a99b8 c2c1f800
c2d9
1f20: bf0272e4 c035e848 c2d9 c0098d04 c2c1f800 c3a7b000 c380dc60
bf0248e4
1f40: c2c1f800 bf028228 c380dc60 c0097f70  c2d91f68 c380dc60
c00ad3ac
1f60: 4003a000 c380dc78 c2d91f68 c2d91f68 c2d91f70 c2d91f70 c380dc60
c35fbab8
1f80: c2d9 0001c530 0001aa1c 0001c518 0034 c0021fe8 c2d9

1fa0: 0001bab4 c0021e40 0001c530 0001aa1c 0001c530  0048

1fc0: 0001c530 0001aa1c 0001c518 0034   
0001bab4
1fe0: 0001c560 be983c08 402c1c5c 402c1c7c 6010 0001c530 e7d82003
e7c12007
[c0025764] (__bug+0x18/0x24) from [bf022630]
(map_invalidatepage+0x10/0x18 [logfs])
[bf022630] (map_invalidatepage+0x10/0x18 [logfs]) from [c0078360]
(do_invalidatepage+0x20/0x28)
[c0078360] (do_invalidatepage+0x20/0x28) from [c0078a04]
(truncate_inode_page+0xd4/0xe4)
[c0078a04] (truncate_inode_page+0xd4/0xe4) from [c0078b2c]
(truncate_inode_pages_range+0x118/0x344)
[c0078b2c] (truncate_inode_pages_range+0x118/0x344) from [c0078d70]
(truncate_inode_pages+0x18/0x20)
[c0078d70] (truncate_inode_pages+0x18/0x20) from [bf022104]
(logfs_evict_inode+0x40/0x188 [logfs])
[bf022104] (logfs_evict_inode+0x40/0x188 [logfs]) from [c00a90f4]
(evict+0x20/0xb0)
[c00a90f4] (evict+0x20/0xb0) from [c00a99b8] (iput+0x178/0x254)
[c00a99b8] (iput+0x178/0x254) from [c0098d04]
(generic_shutdown_super+0x78/0xe4)
[c0098d04] (generic_shutdown_super+0x78/0xe4) from [bf0248e4]
(logfs_kill_sb+0x40/0xf8 [logfs])
[bf0248e4] (logfs_kill_sb+0x40/0xf8 [logfs]) from [c0097f70]
(deactivate_locked_super+0x44/0x58)
[c0097f70] (deactivate_locked_super+0x44/0x58) from [c00ad3ac]
(sys_umount+0x6c/0x33c)
[c00ad3ac] (sys_umount+0x6c/0x33c) from [c0021e40]
(ret_fast_syscall+0x0/0x2c)
Code: e1a01000 e59f000c eb096367 e3a03000 (e5833000)
---[ end trace f09ed3af1a44d711 ]---
[ cut here ]
WARNING: at kernel/exit.c:899 do_exit+0x5d4/0x624()
Modules linked in: logfs zlib_deflate zlib_inflate
[c0027ae8] (unwind_backtrace+0x0/0xf4) from [c003a310]
(warn_slowpath_common+0x4c/0x64)
[c003a310] (warn_slowpath_common+0x4c/0x64) from [c003a344]
(warn_slowpath_null+0x1c/0x24)
[c003a344] (warn_slowpath_null+0x1c/0x24) from [c003e0a4]
(do_exit+0x5d4/0x624)
[c003e0a4] (do_exit+0x5d4/0x624) from [c0025c90] 

[PATCH 09/16] pramfs: dir operations

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

2010-10-10 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 14(16] pramfs: memory protection

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

Memory write protection.

Signed-off-by: Marco Stornelli marco.storne...@gmail.com
---
diff -Nurp linux-2.6.36-orig/fs/pramfs/wprotect.c 
linux-2.6.36/fs/pramfs/wprotect.c
--- linux-2.6.36-orig/fs/pramfs/wprotect.c  1970-01-01 01:00:00.0 
+0100
+++ linux-2.6.36/fs/pramfs/wprotect.c   2010-09-26 18:04:07.0 +0200
@@ -0,0 +1,31 @@
+/*
+ * FILE NAME fs/pramfs/wprotect.c
+ *
+ * BRIEF DESCRIPTION
+ *
+ * Write protection for the filesystem pages.
+ *
+ * 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/fs.h
+#include linux/mm.h
+#include linux/io.h
+#include pram.h
+
+void pram_writeable(void *vaddr, unsigned long size, int rw)
+{
+   int ret = 0;
+
+   ret = rw ? write_on_kernel_pte_range((unsigned long)vaddr, size) :
+   write_off_kernel_pte_range((unsigned long)vaddr, size);
+
+   BUG_ON(ret);
+}
diff -Nurp linux-2.6.36-orig/include/linux/mm.h linux-2.6.36/include/linux/mm.h
--- linux-2.6.36-orig/include/linux/mm.h2010-09-13 01:07:37.0 
+0200
+++ linux-2.6.36/include/linux/mm.h 2010-09-14 18:49:52.0 +0200
@@ -811,6 +811,11 @@ int follow_phys(struct vm_area_struct *v
unsigned int flags, unsigned long *prot, resource_size_t *phys);
 int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
void *buf, int len, int write);
+int writeable_kernel_pte_range(unsigned long address, unsigned long size,
+   unsigned int rw);
+
+#define write_on_kernel_pte_range(addr, size) writeable_kernel_pte_range(addr, 
size, 1)
+#define write_off_kernel_pte_range(addr, size) 
writeable_kernel_pte_range(addr, size, 0)
  static inline void unmap_shared_mapping_range(struct address_space *mapping,
loff_t const holebegin, loff_t const holelen)
diff -Nurp linux-2.6.36-orig/mm/memory.c linux-2.6.36/mm/memory.c
--- linux-2.6.36-orig/mm/memory.c   2010-09-13 01:07:37.0 +0200
+++ linux-2.6.36/mm/memory.c2010-09-14 18:49:52.0 +0200
@@ -3587,3 +3587,49 @@ void might_fault(void)
 }
 EXPORT_SYMBOL(might_fault);
 #endif
+
+int writeable_kernel_pte_range(unsigned long address, unsigned long size,
+ unsigned int rw)
+{
+
+   unsigned long addr = address  PAGE_MASK;
+   unsigned long end = address + size;
+   unsigned long start = addr;
+   int ret = -EINVAL;
+   pgd_t *pgd;
+   pud_t *pud;
+   pmd_t *pmd;
+   pte_t *ptep, pte;
+
+   spin_lock_irq(init_mm.page_table_lock);
+
+   do {
+   pgd = pgd_offset(init_mm, address);
+   if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+   goto out;
+
+   pud = pud_offset(pgd, address);
+   if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+   goto out;
+
+   pmd = pmd_offset(pud, address);
+   if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+   goto out;
+
+   ptep = pte_offset_kernel(pmd, addr);
+   pte = *ptep;
+   if (pte_present(pte)) {
+ pte = rw ? pte_mkwrite(pte) : pte_wrprotect(pte);
+ *ptep = pte;
+   }
+   addr += PAGE_SIZE;
+   } while (addr  (addr  end));
+
+   ret = 0;
+
+out:
+   flush_tlb_kernel_range(start, end);
+   spin_unlock_irq(init_mm.page_table_lock);
+   return ret;
+}
+EXPORT_SYMBOL(writeable_kernel_pte_range);
 
--
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] pramfs Makefile and Kconfig

2010-10-10 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-09-14 18:49:52.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.ko.
+
+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
+   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.ko.
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 pram-filesystem 

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

2010-10-10 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 11/16] pramfs: ACL management

2010-10-10 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.h
+ *
+ * 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 

Re: [PATCH 14(16] pramfs: memory protection

2010-10-10 Thread Andi Kleen
Marco Stornelli marco.storne...@gmail.com writes:
 +
 + do {
 + pgd = pgd_offset(init_mm, address);
 + if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
 + goto out;
 +
 + pud = pud_offset(pgd, address);
 + if (pud_none(*pud) || unlikely(pud_bad(*pud)))
 + goto out;
 +
 + pmd = pmd_offset(pud, address);
 + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
 + goto out;
 +
 + ptep = pte_offset_kernel(pmd, addr);
 + pte = *ptep;
 + if (pte_present(pte)) {

This won't work at all on x86 because you don't handle large 
pages.

And it doesn't work on x86-64 because the first 2GB are double
mapped (direct and kernel text mapping)

Thirdly I expect it won't either on architectures that map
the direct mapping with special registers (like IA64 or MIPS)

I'm not sure this is very useful anyways. It doesn't protect
against stray DMA and it doesn't protect against writes through
broken user PTEs.

-Andi

-- 
a...@linux.intel.com -- Speaking for myself only.
--
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 15/16] pramfs: test module

2010-10-10 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 04/16] pramfs: file operations

2010-10-10 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:
+

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

2010-10-10 Thread Randy Dunlap
On Sun, 10 Oct 2010 18:37:49 +0200 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.
 + *
 + * 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__);

Above 2 lines need to indented more.

 + 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);


---
~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


[PATCH 10/16] pramfs: xip operations

2010-10-10 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


Re: [PATCH 16/16] pramfs Makefile and Kconfig

2010-10-10 Thread Randy Dunlap
On Sun, 10 Oct 2010 18:39:11 +0200 Marco Stornelli wrote:

 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/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/Kconfig2010-09-14 18:49:52.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.ko.

  called pramfs.

(we don't add the .ko suffix; well, we try not to do that)

 +
 +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.

XIP

 +
 +config PRAMFS_WRITE_PROTECT
 + bool Enable PRAMFS write protection
 + depends on PRAMFS  MMU
 + 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

end sentence with period ('.').

 +
 +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.ko.

 called pramfs_test.



---
~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: logfs segfaults at umount time

2010-10-10 Thread Wolfgang Denk
Dear Michael,

In message 4cb1e5b3.1090...@free-electrons.com you wrote:
 
 I'm running some flash filesystem benchmarks for CELF, and I'm facing
 kernel segfaults when I try to umount my logfs filesystem.
...
 r...@calao:~# mount -t logfs /dev/mtdblock0 /mnt/flash/
 r...@calao:~# cp -rf /fs/8m/* /mnt/flash/
 eth0: TX underrun, resetting buffers
 eth0: TX underrun, resetting buffers

Seems you have some problems here already?

 r...@calao:~# umount /mnt/flash/
 kernel BUG at fs/logfs/segment.c:858!
 Unable to handle kernel NULL pointer dereference at virtual address 
 pgd = c14a4000
 [] *pgd=23a3c031, *pte=, *ppte=
 Internal error: Oops: 817 [#1]
...

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
We have phasers, I vote we blast 'em!
-- Bailey, The Corbomite Maneuver, stardate 1514.2
--
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: logfs segfaults at umount time

2010-10-10 Thread Michael Opdenacker
Hi Wolfgang,

On 10/10/2010 07:16 PM, Wolfgang Denk wrote:
 Dear Michael,

 In message 4cb1e5b3.1090...@free-electrons.com you wrote:
 r...@calao:~# mount -t logfs /dev/mtdblock0 /mnt/flash/
 r...@calao:~# cp -rf /fs/8m/* /mnt/flash/
 eth0: TX underrun, resetting buffers
 eth0: TX underrun, resetting buffers
 
 Seems you have some problems here already?
   
I don't think they are related. My rootfs in on NFS, and these happen
all the time on these at91 boards, causing no problem with the other
filesystems.

Cheers,

Michael.

-- 
Michael Opdenacker, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
+ 33 621 604 642

--
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