extern struct inode_operations smfs_file_iops;
extern struct file_operations smfs_file_fops;
-extern struct address_space_operations smfs_file_aops;
extern struct inode_operations smfs_sym_iops;
extern struct file_operations smfs_sym_fops;
extern struct super_operations smfs_super_ops;
return &smfs_ops->sm_file_fops;
}
-inline struct address_space_operations *cache_faops(struct sm_ops *smfs_ops)
-{
- return &smfs_ops->sm_file_aops;
-}
-
inline struct file_operations *cache_sfops(struct sm_ops *smfs_ops)
{
return &smfs_ops->sm_sym_fops;
fops->get_unmapped_area = cache_fops->get_unmapped_area;
}
}
-static void setup_aops(struct inode *cache_inode,
- struct address_space_operations *aops,
- struct address_space_operations *cache_aops)
-{
- if (cache_inode && cache_inode->i_mapping &&
- aops && cache_aops) {
- struct address_space_operations *caops = cache_inode->i_mapping->a_ops;
-
- if (caops->writepage)
- aops->writepage = cache_aops->writepage;
- if (caops->readpage)
- aops->readpage = cache_aops->readpage;
- if (caops->sync_page)
- aops->sync_page = cache_aops->sync_page;
- if (caops->prepare_write)
- aops->prepare_write = cache_aops->prepare_write;
- if (caops->commit_write)
- aops->commit_write = cache_aops->commit_write;
- if (caops->bmap)
- aops->bmap = cache_aops->bmap;
- if (caops->flushpage)
- aops->flushpage = cache_aops->flushpage;
- if (caops->releasepage)
- aops->releasepage = cache_aops->releasepage;
- if (caops->direct_IO)
- aops->direct_IO = cache_aops->direct_IO;
- if (caops->removepage)
- aops->removepage = cache_aops->removepage;
- }
-};
-
static void setup_sm_file_ops(struct inode *cache_inode,
struct inode *inode,
struct inode_operations *cache_iops,
- struct file_operations *cache_fops,
- struct address_space_operations *cache_aops)
+ struct file_operations *cache_fops)
{
struct smfs_super_info *smb;
struct inode_operations *iops;
struct file_operations *fops;
- struct address_space_operations *aops;
smb = S2SMI(inode->i_sb);
iops = cache_fiops(&smfs_operations);
fops = cache_ffops(&smfs_operations);
- aops = cache_faops(&smfs_operations);
memset(iops , 0 , sizeof (struct inode_operations));
memset(fops , 0 , sizeof (struct file_operations));
- memset(aops , 0 , sizeof (struct address_space_operations));
setup_iops(cache_inode, iops, cache_iops);
setup_fops(cache_inode, fops, cache_fops);
- setup_aops(cache_inode, aops, cache_aops);
return;
}
} else if (S_ISREG(inode->i_mode)) {
setup_sm_file_ops(cache_inode, inode,
&smfs_file_iops,
- &smfs_file_fops,
- &smfs_file_aops);
+ &smfs_file_fops);
CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
inode->i_ino, inode->i_op);
inode->i_fop = cache_ffops(&smfs_operations);
inode->i_op = cache_fiops(&smfs_operations);
- if (inode->i_mapping)
- inode->i_mapping->a_ops = cache_faops(&smfs_operations);
} else if (S_ISLNK(inode->i_mode)) {
setup_sm_symlink_ops(cache_inode, inode,
#include <linux/unistd.h>
#include <linux/pagemap.h>
#include "smfs_internal.h"
-
-static int smfs_readpage(struct file *file,
- struct page *page)
-{
- struct inode *inode = page->mapping->host;
- struct inode *cache_inode;
- struct page *cache_page = NULL;
- int rc = 0;
-
- ENTRY;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- cache_page = grab_cache_page(cache_inode->i_mapping, page->index);
-
- if (!cache_page)
- GOTO(exit_release, rc = -ENOMEM);
-
- if ((rc = cache_inode->i_mapping->a_ops->readpage(file, cache_page)))
- GOTO(exit_release, 0);
-
- wait_on_page(cache_page);
-
- if (!Page_Uptodate(cache_page))
- GOTO(exit_release, rc = -EIO);
-
- memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
-
- flush_dcache_page(page);
-
- kunmap(cache_page);
- page_cache_release(cache_page);
-
-exit:
- kunmap(page);
- SetPageUptodate(page);
- UnlockPage(page);
-
- RETURN(rc);
-
-exit_release:
- if (cache_page)
- page_cache_release(cache_page);
- UnlockPage(page);
- RETURN(rc);
-}
-
-static int smfs_writepage(struct page *page)
-{
-
- struct inode *inode = page->mapping->host;
- struct inode *cache_inode;
- int rc;
-
- ENTRY;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- if (cache_inode->i_mapping->a_ops->writepage)
- rc = cache_inode->i_mapping->a_ops->writepage(page);
-
- RETURN(rc);
-}
-
-static int smfs_sync_page(struct page *page)
-{
- struct inode *inode = page->mapping->host;
- struct inode *cache_inode;
- int rc = 0;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- if (cache_inode->i_mapping->a_ops->sync_page)
- rc = cache_inode->i_mapping->a_ops->sync_page(page);
-
- RETURN(rc);
-}
-
-static int smfs_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
-{
- struct inode *inode = page->mapping->host;
- struct inode *cache_inode;
- int rc = 0;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- if (cache_inode->i_mapping->a_ops->prepare_write)
- rc = cache_inode->i_mapping->a_ops->prepare_write(file, page, from, to);
-
- RETURN(rc);
-}
-
-static int smfs_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
-{
- struct inode *inode = page->mapping->host;
- struct inode *cache_inode;
- int rc = 0;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- if (cache_inode->i_mapping->a_ops->commit_write)
- rc = cache_inode->i_mapping->a_ops->commit_write(file, page, from, to);
-
- RETURN(rc);
-}
-
-static int smfs_bmap(struct address_space *mapping, long block)
-{
- struct inode *inode = mapping->host;
- struct inode *cache_inode;
- int rc = 0;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- if (cache_inode->i_mapping->a_ops->bmap)
- rc = cache_inode->i_mapping->a_ops->bmap(mapping, block);
-
- RETURN(rc);
-}
-
-static int smfs_flushpage(struct page *page, unsigned long offset)
-{
- struct inode *inode = page->mapping->host;
- struct inode *cache_inode;
- int rc = 0;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- if (cache_inode->i_mapping->a_ops->flushpage)
- rc = cache_inode->i_mapping->a_ops->flushpage(page, offset);
-
- RETURN(rc);
-}
-
-static int smfs_releasepage(struct page *page, int wait)
-{
- struct inode *inode = page->mapping->host;
- struct inode *cache_inode;
- int rc = 0;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- if (cache_inode->i_mapping->a_ops->releasepage)
- rc = cache_inode->i_mapping->a_ops->releasepage(page, wait);
-
- RETURN(rc);
-}
-
-static int smfs_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
- unsigned long blocknr, int blocksize)
-{
- struct inode *cache_inode;
- int rc = 0;
-
- cache_inode = I2CI(inode);
-
- if (!cache_inode)
- RETURN(-ENOENT);
-
- if (cache_inode->i_mapping->a_ops->direct_IO)
- rc = cache_inode->i_mapping->a_ops->direct_IO(rw, cache_inode, iobuf,
- blocknr, blocksize);
- RETURN(rc);
-}
-
-struct address_space_operations smfs_file_aops = {
- readpage: smfs_readpage,
- writepage: smfs_writepage,
- sync_page: smfs_sync_page,
- prepare_write: smfs_prepare_write,
- commit_write: smfs_commit_write,
- bmap: smfs_bmap,
- flushpage: smfs_flushpage,
- releasepage: smfs_releasepage,
- direct_IO: smfs_direct_IO,
-};
/* instantiate a file handle to the cache file */
void smfs_prepare_cachefile(struct inode *inode,
static int smfs_mmap(struct file * file, struct vm_area_struct * vma)
{
- struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
- struct inode *inode = mapping->host;
+ struct inode *inode = file->f_dentry->d_inode;
struct inode *cache_inode = NULL;
struct file open_file;
struct dentry open_dentry;
smfs_prepare_cachefile(inode, file, cache_inode,
&open_file, &open_dentry);
-
+
+ if (cache_inode->i_mapping == &cache_inode->i_data)
+ inode->i_mapping = cache_inode->i_mapping;
+
if (cache_inode->i_fop->mmap)
rc = cache_inode->i_fop->mmap(&open_file, vma);
-
+
duplicate_inode(cache_inode, inode);
smfs_update_file(file, &open_file);