Pramfs: File operations for files
PATCH 5/14 Pramfs: File operations for files
From: Marco Stornelli <[email protected]>
File operations for files.
Signed-off-by Marco Stornelli <[email protected]>
---
fs/pramfs/file.c +141 -0
@@ -0,0 +1,141 @@ +/* +* FILE NAME fs/pramfs/file.c +* +* BRIEF DESCRIPTION +* +* File operations for files. +* +* Copyright 2009 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. +*/ +#include <linux/fs.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/uio.h> +#include <linux/uaccess.h> +#include "pram_fs.h" +#include "xip.h" + +static int pram_open_file (struct inode *inode,struct file *filp) +{ +#ifndef CONFIG_PRAMFS_XIP +/* Without XIP we force to use Direct IO */ + filp->f_flags |=O_DIRECT ; +#endif +return generic_file_open (inode, filp); +} + +/* +* Called when an inode is released. Note that this is different +* from pram_open_file: open gets called at every open, but release +* gets called only when /all/ the files are closed. +*/ +static int pram_release_file (struct inode *inode,struct file *filp) +{ +return 0 ; +} + +ssize_t __pram_direct_IO (int rw,struct kiocb *iocb, +const struct iovec *iov, +loff_t offset,unsigned long nr_segs) +{ +struct file *file = iocb->ki_filp; +struct inode *inode = file->f_mapping->host; +struct super_block *sb = inode->i_sb; +int progress =0 ; +ssize_t retval =0 ; +struct pram_inode *pi; +void *tmp =NULL ; +unsigned long flags; +unsigned long blocknr, blockoff; +int num_blocks, blocksize_mask, blocksize, blocksize_bits; +char __user *buf = iov->iov_base; +size_t length = iov->iov_len; + + flags =0 ; + +if (length <0 ) +return -EINVAL ; +if ((rw ==READ ) && (offset + length > inode->i_size)) + length = inode->i_size - offset; +if (!length) + goto out; + + blocksize_bits = inode->i_sb->s_blocksize_bits; + blocksize =1 << blocksize_bits; + blocksize_mask = blocksize -1 ; + +/* find starting block number to access */ + blocknr = offset >> blocksize_bits; +/* find starting offset within starting block */ + blockoff = offset & blocksize_mask; +/* find number of blocks to access */ + num_blocks = (blockoff + length + blocksize_mask) >> blocksize_bits; + +if (rw ==WRITE ) { +/* prepare a temporary buffer to hold a user data block +for writing. */ + tmp =kmalloc (blocksize,GFP_KERNEL ); +if (!tmp) +return -ENOMEM ; +/* now allocate the data blocks we'll need */ + retval =pram_alloc_blocks (inode, blocknr, num_blocks); +if (retval) + goto fail; + } + + pi =pram_get_inode (inode->i_sb, inode->i_ino); + +while (length) { +int count; +off_t block =pram_find_data_block (inode, blocknr++); +u8 *bp = (u8 *)pram_get_block (sb, block); +if (!bp) + goto fail; + + count = blockoff + length > blocksize ? + blocksize - blockoff : length; + +if (rw ==READ ) { +copy_to_user (buf, &bp[blockoff], count); + }else { +copy_from_user (tmp, buf, count); + +pram_lock_block (inode->i_sb, bp, flags); +memcpy (&bp[blockoff], tmp, count); +pram_unlock_block (inode->i_sb, bp, flags); + } + + progress += count; + buf += count; + length -= count; + blockoff =0 ; + } + + retval = progress; + fail: +kfree (tmp); + out: +return retval; +} + +struct file_operations pram_file_operations = { + .llseek = generic_file_llseek, + .read = pram_read, + .write = pram_write, + .aio_read = pram_aio_read, + .aio_write = pram_aio_write, + .mmap = pram_mmap, + .open = pram_open_file, + .release = pram_release_file, + .fsync = simple_sync_file, +}; + +struct inode_operations pram_file_inode_operations = { + .truncate = pram_truncate, +};
Quoted 23 lines · Marco
From: Marco Stornelli <[email protected]>
File operations for files.
Signed-off-by Marco Stornelli <[email protected]>---
diff -uprN
linux-2.6.30-orig/fs/pramfs/file.clinux-2.6.30/fs/pramfs/file.cfs/pramfs/file.c +12
-0@@ -0,0 +1,141 @@ +/* +* FILE NAME fs/pramfs/file.c +* +* BRIEF DESCRIPTION +* +* File operations for files. +* +* Copyright 2009 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
fs/pramfs/file.c line 22
Quoted 10 lines
fs/pramfs/file.c +10
-0+* License version 2. This program is licensed "as is" without any +* warranty of any kind, whether express or implied. +*/ +#include <linux/fs.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/uio.h> +#include <linux/uaccess.h> +#include "pram_fs.h" +#include "xip.h"
It would be cleaner if the xip.h include was added in patch 14 of 14, since that's the XIP support patch.
fs/pramfs/file.c line 29
Quoted 6 lines
fs/pramfs/file.c +6
-0+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
Same as above .. It's better to have all the support for a given feature all in the same patch. The rest of your patches are dotted with these bits of code that should really be refactored into other patches.
Daniel