pramfs: headers
PATCH v4 8/16 pramfs: headers
From: Marco Stornelli <[email protected]>
Definitions for the PRAMFS filesystem.
---
fs/pramfs/pram.h +317 -0
@@ -0,0 +1,317 @@ +/* +* FILE NAME pram.h +* +* BRIEF DESCRIPTION +* +* Definitions for the PRAMFS filesystem. +* +* Copyright 2009-2010 Marco Stornelli <[email protected]> +* Copyright 2003 Sony Corporation +* Copyright 2003 Matsushita Electric Industrial Co., Ltd. +* 2003-2004 (c) MontaVista Software, Inc. , Steve Longerbeam +* This file is licensed under the terms of the GNU General Public +* License version 2. This program is licensed "as is" without any +* warranty of any kind, whether express or implied. +*/ +#ifndef __PRAM_H +#define __PRAM_H + +#include <linux/buffer_head.h> +#include <linux/pram_fs.h> +#include <linux/pram_fs_sb.h> +#include <linux/crc16.h> +#include <linux/mutex.h> +#include <linux/types.h> + +/* +* Debug code +*/ +#define pram_dbg(s, args...) pr_debug("PRAMFS: "s, ## args) +#define pram_err(s, args...) pr_err("PRAMFS: "s, ## args) +#define pram_warn(s, args...) pr_warning("PRAMFS: "s, ## args) +#define pram_info(s, args...) pr_info("PRAMFS: "s, ## args) + +/* Function Prototypes */ + +#ifdef CONFIG_PRAMFS_XIP + +#define pram_read xip_file_read +#define pram_write xip_file_write +#define pram_mmap xip_file_mmap +#define pram_aio_read NULL +#define pram_aio_write NULL +#define pram_readpage NULL +#define pram_direct_IO NULL + +#else + +#define pram_read do_sync_read +#define pram_write do_sync_write +#define pram_mmap __pram_mmap +#define pram_aio_read generic_file_aio_read +#define pram_aio_write generic_file_aio_write +#define pram_direct_IO __pram_direct_IO +#define pram_readpage __pram_readpage + +extern int pram_get_and_update_block (struct inode *inode,sector_t iblock, +struct buffer_head *bh,int create); + +static inline int __pram_readpage (struct file *file,struct page *page) +{ +return block_read_full_page (page, pram_get_and_update_block); +} + +/* file.c */ +extern ssize_t __pram_direct_IO (int rw,struct kiocb *iocb, +const struct iovec *iov, +loff_t offset,unsigned long nr_segs); +extern int __pram_mmap (struct file *file,struct vm_area_struct *vma); + +#endif /* CONFIG_PRAMFS_XIP */ + +#define pram_set_bit ext2_set_bit +#define pram_clear_bit ext2_clear_bit +#define pram_find_next_zero_bit ext2_find_next_zero_bit + +/* balloc.c */ +extern void pram_init_bitmap (struct super_block *sb); +extern void pram_free_block (struct super_block *sb,unsigned long blocknr); +extern int pram_new_block (struct super_block *sb,unsigned long *blocknr,int zero); +extern unsigned long pram_count_free_blocks (struct super_block *sb); + +/* dir.c */ +extern int pram_add_link (struct dentry *dentry,struct inode *inode); +extern int pram_remove_link (struct inode *inode); + +/* namei.c */ +extern struct dentry *pram_get_parent (struct dentry *child); + +/* inode.c */ +extern int pram_alloc_blocks (struct inode *inode,int file_blocknr,int num); +extern u64 pram_find_data_block (struct inode *inode, +int file_blocknr); + +extern struct inode *pram_iget (struct super_block *sb,unsigned long ino); +extern void pram_put_inode (struct inode *inode); +extern void pram_evict_inode (struct inode *inode); +extern struct inode *pram_new_inode (struct inode *dir,int mode); +extern int pram_update_inode (struct inode *inode); +extern int pram_write_inode (struct inode *inode,struct writeback_control *wbc); +extern void pram_dirty_inode (struct inode *inode); +extern int pram_notify_change (struct dentry *dentry,struct iattr *attr); + + +/* super.c */ +#ifdef CONFIG_PRAMFS_TEST +extern struct pram_super_block *get_pram_super (void ); +#endif +extern struct super_block *pram_read_super (struct super_block *sb, +void *data, +int silent); +extern int pram_statfs (struct dentry *d,struct kstatfs *buf); +extern int pram_remount (struct super_block *sb,int *flags,char *data); + +/* symlink.c */ +extern int pram_block_symlink (struct inode *inode, +const char *symname,int len); + + +#ifdef CONFIG_PRAMFS_WRITE_PROTECT +extern void pram_writeable (void *vaddr,unsigned long size,int rw); + +#define wrprotect (addr, size) pram_writeable(addr, size, 0) + +#else + +#define wrprotect (addr, size) do {} while (0) + +#endif /* CONFIG PRAMFS_WRITE_PROTECT */ + +/* Inline functions start here */ + +static inline int pram_calc_checksum (u8 *data,int n) +{ +u16 crc =0 ; + crc =crc16 (~0 , (__u8 *)data +sizeof (__be16), n -sizeof (__be16)); +if (*((__be16 *)data) ==cpu_to_be16 (crc)) +return 0 ; +else +return 1 ; +} + +/* If this is part of a read-modify-write of the super block, +pram_memunlock_super() before calling! */ +static inline struct pram_super_block * +pram_get_super (struct super_block *sb) +{ +struct pram_sb_info *sbi = (struct pram_sb_info *)sb->s_fs_info; +return (struct pram_super_block *)sbi->virt_addr; +} + +static inline struct pram_super_block * +pram_get_redund_super (struct super_block *sb) +{ +struct pram_sb_info *sbi = (struct pram_sb_info *)sb->s_fs_info; +return (struct pram_super_block *)(sbi->virt_addr +PRAM_SB_SIZE ); +} + +/* pram_memunlock_super() before calling! */ +static inline void pram_sync_super (struct pram_super_block *ps) +{ +u16 crc =0 ; + ps->s_wtime =cpu_to_be32 (get_seconds ()); + ps->s_sum =0 ; + crc =crc16 (~0 , (__u8 *)ps +sizeof (__be16),PRAM_SB_SIZE -sizeof (__be16)); + ps->s_sum =cpu_to_be16 (crc); +/* Keep sync redundant super block */ +memcpy ((void *)ps +PRAM_SB_SIZE , (void *)ps,PRAM_SB_SIZE ); +} + +/* pram_memunlock_inode() before calling! */ +static inline void pram_sync_inode (struct pram_inode *pi) +{ +u16 crc =0 ; + pi->i_sum =0 ; + crc =crc16 (~0 , (__u8 *)pi +sizeof (__be16),PRAM_INODE_SIZE -sizeof (__be16)); + pi->i_sum =cpu_to_be16 (crc); +} + +#ifdef CONFIG_PRAMFS_WRITE_PROTECT +static inline void pram_memunlock_range (void *p,unsigned long len) +{ +#ifndef CONFIG_X86 +local_irq_disable (); +#endif +preempt_disable (); +pram_writeable (p, len,1 ); +} + +static inline void pram_memlock_range (void *p,unsigned long len) +{ +pram_writeable (p, len,0 ); +preempt_enable (); +#ifndef CONFIG_X86 +local_irq_enable (); +#endif +} +#else +static inline void pram_memunlock_range (void *p,unsigned long len) {} +static inline void pram_memlock_range (void *p,unsigned long len) {} +#endif + +/* write protection for super block */ +#define pram_memunlock_super (ps) \ + pram_memunlock_range((ps), PRAM_SB_SIZE) +#define pram_memlock_super (ps) {\ + pram_sync_super(ps);\ + pram_memlock_range((ps), PRAM_SB_SIZE);\ +} + +/* write protection for inode metadata */ +#define pram_memunlock_inode (pi) \ + pram_memunlock_range((pi), PRAM_INODE_SIZE) +#define pram_memlock_inode (pi) {\ + pram_sync_inode(pi);\ + pram_memlock_range((pi), PRAM_INODE_SIZE);\ +} + +/* write protection for a data block */ +#define pram_memunlock_block (sb, bp) \ + pram_memunlock_range((bp), (sb)->s_blocksize) +#define pram_memlock_block (sb, bp) \ + pram_memlock_range((bp), (sb)->s_blocksize) + +static inline void * +pram_get_bitmap (struct super_block *sb) +{ +struct pram_super_block *ps =pram_get_super (sb); +return (void *)ps +be64_to_cpu (ps->s_bitmap_start); +} + +/* If this is part of a read-modify-write of the inode metadata, +pram_memunlock_inode() before calling! */ +static inline struct pram_inode * +pram_get_inode (struct super_block *sb,u64 ino) +{ +struct pram_super_block *ps =pram_get_super (sb); +return ino ? (struct pram_inode *)((void *)ps + ino) :NULL ; +} + +static inline ino_t +pram_get_inodenr (struct super_block *sb,struct pram_inode *pi) +{ +struct pram_super_block *ps =pram_get_super (sb); +return (ino_t)((unsigned long )pi - (unsigned long )ps); +} + +static inline u64 +pram_get_block_off (struct super_block *sb,unsigned long blocknr) +{ +struct pram_super_block *ps =pram_get_super (sb); +return (u64)(be64_to_cpu (ps->s_bitmap_start) + + (blocknr << sb->s_blocksize_bits)); +} + +static inline unsigned long +pram_get_blocknr (struct super_block *sb,u64 block) +{ +struct pram_super_block *ps =pram_get_super (sb); +return (block -be64_to_cpu (ps->s_bitmap_start)) >> sb->s_blocksize_bits; +} + +/* If this is part of a read-modify-write of the block, +pram_memunlock_block() before calling! */ +static inline void * +pram_get_block (struct super_block *sb,u64 block) +{ +struct pram_super_block *ps =pram_get_super (sb); +return block ? ((void *)ps + block) :NULL ; +} + +struct pram_inode_vfs { +#ifdef CONFIG_PRAMFS_XATTR +/* +* Extended attributes can be read independently of the main file +* data. Taking i_mutex even when reading would cause contention +* between readers of EAs and writers of regular file data, so +* instead we synchronize on xattr_sem when reading or changing +* EAs. +*/ +struct rw_semaphore xattr_sem; +#endif +/* +* truncate_mutex is for serialising the truncate path against +* get/update block. +*/ +struct mutex truncate_mutex; +struct inode vfs_inode; +}; + +static inline struct pram_inode_vfs *PRAM_I (struct inode *inode) +{ + return container_of(inode, struct pram_inode_vfs, vfs_inode); +} + +/* +* Inodes and files operations +*/ + +/* dir.c */ +extern struct file_operations pram_dir_operations; + +/* file.c */ +extern struct inode_operations pram_file_inode_operations; +extern struct file_operations pram_file_operations; + +/* inode.c */ +extern struct address_space_operations pram_aops; + +/* namei.c */ +extern struct inode_operations pram_dir_inode_operations; + +/* symlink.c */ +extern struct inode_operations pram_symlink_inode_operations; + +extern struct backing_dev_info pram_backing_dev_info; + +#endif /* __PRAM_H */
include/linux/magic.h +1 -0
@@ -39,6 +39,7 @@#define OPENPROM_SUPER_MAGIC 0x9fa1#define PROC_SUPER_MAGIC 0x9fa0#define QNX4_SUPER_MAGIC 0x002f/* qnx4 fs detection */ +#define PRAM_SUPER_MAGIC 0xEFFA#define REISERFS_SUPER_MAGIC 0x52654973/* used by gcc */ /* used by file system utilities that
include/linux/pram_fs.h +118 -0
118 lines not on this page · raw message
include/linux/pram_fs_sb.h +44 -0
44 lines not on this page · raw message
fs/pramfs/pram.h line 33
Quoted 8 lines · Marco Stornelli
fs/pramfs/pram.h +8
-0+/* +* 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) +
Please kill off all of this and just use KBUILD_MODNAME centrally.
fs/pramfs/pram.h line 129
Quoted 11 lines
fs/pramfs/pram.h +11
-0+#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 */ +
Perhaps this should be pram_wrprotect()? Does this really benefit from being a config option instead of a mount option? Will this handle multiple mounts with some write protected and others not?
fs/pramfs/pram.h line 188
Quoted 10 lines
fs/pramfs/pram.h +10
-0+#ifdef CONFIG_PRAMFS_WRITE_PROTECT +static inline void pram_memunlock_range (void *p,unsigned long len) +{ +#ifndef CONFIG_X86 +local_irq_disable (); +#endif +preempt_disable (); +pram_writeable (p, len,1 ); +} +
This needs some explaining, or killing. While the latter is preferable, we can also work with the former.
2010/11/24 Paul Mundt <[email protected]>:
Quoted 10 lines · Marco Stornelli
fs/pramfs/pram.h line 33
Quoted 8 lines
fs/pramfs/pram.h +8
-0+/* +* 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) +Please kill off all of this and just use
KBUILD_MODNAMEcentrally.
I didn't know this way to do, I'll look at it.
Quoted 15 lines
fs/pramfs/pram.h line 129
Quoted 12 lines
fs/pramfs/pram.h +11
-0+#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 */ +Perhaps this should be
pram_wrprotect()? Does this really benefit from being a config option instead of a mount option? Will this handle multiple mounts with some write protected and others not?
See my previous response.
Quoted 14 lines
fs/pramfs/pram.h line 188
Quoted 11 lines
fs/pramfs/pram.h +10
-0+#ifdef CONFIG_PRAMFS_WRITE_PROTECT +static inline void pram_memunlock_range (void *p,unsigned long len) +{ +#ifndef CONFIG_X86 + local_irq_disable(); +#endif + preempt_disable(); + pram_writeable(p, len, 1); +} +This needs some explaining, or killing. While the latter is preferable, we can also work with the former.
Maybe I didn't understand, you mean preemt_disable() without disabling the interrupt?
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 16 lines · Marco Stornelli
2010/11/24 Paul Mundt <[email protected]>:
Quoted 6 lines
Quoted 6 lines
fs/pramfs/pram.h +6
-0+#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 Quoted 8 lines
fs/pramfs/pram.h line 129
Quoted 5 lines
fs/pramfs/pram.h +5
-0+ +#define wrprotect (addr, size) do {} while (0) + +#endif /* CONFIG PRAMFS_WRITE_PROTECT */ +Perhaps this should be
pram_wrprotect()? Does this really benefit from being a config option instead of a mount option? Will this handle multiple mounts with some write protected and others not?
Quoted 2 lines
See my previous response.
Your previous response only alludes to why you didn't feel like making it a mount option, and doesn't address any of the other questions.
Quoted 15 lines
Quoted 14 lines
fs/pramfs/pram.h line 188
Quoted 11 lines
fs/pramfs/pram.h +10
-0+#ifdef CONFIG_PRAMFS_WRITE_PROTECT +static inline void pram_memunlock_range (void *p,unsigned long len) +{ +#ifndef CONFIG_X86 + ? ? local_irq_disable(); +#endif + ? ? preempt_disable(); + ? ? pram_writeable(p, len, 1); +} +This needs some explaining, or killing. While the latter is preferable, we can also work with the former.
Quoted 2 lines
Maybe I didn't understand, you mean
preemt_disable()without disabling the interrupt?
I mean what exactly is this supposed to be doing? It looks pretty questionable for SMP for starters, it doesn't explain why x86 is special, etc. It looks like you wanted a spinlock with IRQs disabled but probably opted not to use it because you were throwing this around interfaces that could sleep, which looks like a really scary thing for latency. It's also making architecture assumptions without any explanation of why. This needs to be explained, and in some amount of detail, as it's not entirely obvious.
2010/11/24 Paul Mundt <[email protected]>:
Quoted 20 lines · Marco Stornelli
Quoted 16 lines
2010/11/24 Paul Mundt <[email protected]>:
Quoted 14 lines
fs/pramfs/pram.h line 188
Quoted 11 lines
fs/pramfs/pram.h +10
-0+#ifdef CONFIG_PRAMFS_WRITE_PROTECT +static inline void pram_memunlock_range (void *p,unsigned long len) +{ +#ifndef CONFIG_X86 + ? ? local_irq_disable(); +#endif + ? ? preempt_disable(); + ? ? pram_writeable(p, len, 1); +} +This needs some explaining, or killing. While the latter is preferable, we can also work with the former.
Quoted 2 lines
Maybe I didn't understand, you mean
preemt_disable()without disabling the interrupt?
Quoted 9 lines
I mean what exactly is this supposed to be doing? It looks pretty questionable for SMP for starters, it doesn't explain why x86 is special, etc. It looks like you wanted a spinlock with IRQs disabled but probably opted not to use it because you were throwing this around interfaces that could sleep, which looks like a really scary thing for latency. It's also making architecture assumptions without any explanation of why. This needs to be explained, and in some amount of detail, as it's not entirely obvious.
Ok, it's not clear, I'll try to explain. My idea here is avoid "open windows" with the memory not locked (lock here means not protected). The problem here is that if you call set_memory_rw/set_memory_ro with interrupt disabled (for x86) you'll fall in a bug_on() condition. I can add that the use of these functions has been discussed in the v1 patch series with Andi Kleen.
Marco