inode->i_op = &clonefs_file_inode_ops;
if (inode->i_mapping)
inode->i_mapping->a_ops = &clonefs_file_address_ops;
+ inode->i_fop = &clonefs_file_file_ops;
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &clonefs_dir_inode_ops;
inode->i_fop = &clonefs_dir_file_ops;
*/
struct dentry *clonefs_lookup(struct inode *dir, struct dentry *dentry)
{
- struct inode *cache_dir;
- struct dentry *cache_dentry;
+ struct inode *cache_dir = NULL;
+ struct dentry *cache_dentry = NULL, *tmp = NULL;
struct inode *cache_inode;
struct dentry *result;
struct inode *inode;
ENTRY;
cache_dir = clonefs_get_inode(dir);
+ if (!cache_dir)
+ RETURN(ERR_PTR(-ENOENT));
+
+ tmp = dget(list_entry(cache_dir->i_dentry.next, struct dentry, d_alias));
- cache_dentry = d_alloc(dentry->d_parent, &dentry->d_name);
+ cache_dentry = d_alloc(tmp->d_parent, &dentry->d_name);
+
if (!cache_dentry) {
iput(cache_dir);
+ dput(tmp);
RETURN(ERR_PTR(-ENOENT));
}
/* Lock cache directory inode. */
down(&cache_dir->i_sem);
+ dput(tmp);
/*
* Call underlying fs lookup function to set the 'd_inode' pointer
* to the corresponding directory inode.
struct inode *cache_inode;
struct file open_file;
struct dentry open_dentry;
- struct inode *inode=file->f_dentry->d_inode;
+ struct inode *inode = file->f_dentry->d_inode;
ENTRY;
i -> generation = snapops->get_generation(inode);
i -> flags = flag;
}
+
+void set_filter_ops(struct snap_cache *cache, struct inode *inode)
+{
+ /* XXX now set the correct snap_{file,dir,sym}_iops */
+ if (S_ISDIR(inode->i_mode)) {
+ inode->i_op = filter_c2udiops(cache->cache_filter);
+ inode->i_fop = filter_c2udfops(cache->cache_filter);
+ } else if (S_ISREG(inode->i_mode)) {
+ if ( !filter_c2cfiops(cache->cache_filter) ) {
+ filter_setup_file_ops(cache->cache_filter, inode,
+ ¤tfs_file_iops,
+ ¤tfs_file_fops,
+ ¤tfs_file_aops);
+ }
+ CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
+ inode->i_ino, inode->i_op);
+ inode->i_fop = filter_c2uffops(cache->cache_filter);
+ inode->i_op = filter_c2ufiops(cache->cache_filter);
+ if (inode->i_mapping)
+ inode->i_mapping->a_ops = filter_c2ufaops(cache->cache_filter);
+
+ }
+ else if (S_ISLNK(inode->i_mode)) {
+ if ( !filter_c2csiops(cache->cache_filter) ) {
+ filter_setup_symlink_ops(cache->cache_filter, inode,
+ ¤tfs_sym_iops, ¤tfs_sym_fops);
+ }
+ inode->i_op = filter_c2usiops(cache->cache_filter);
+ inode->i_fop = filter_c2usfops(cache->cache_filter);
+ CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
+ inode->i_ino, inode->i_op);
+ }
+}
+
/* Superblock operations. */
static void currentfs_read_inode(struct inode *inode)
{
struct snap_cache *cache;
- struct snapshot_operations *snapops;
ENTRY;
if( !inode )
currentfs_dotsnap_read_inode(cache, inode);
return;
}
- snapops = filter_c2csnapops(cache->cache_filter);
-
- if (!snapops || !snapops->get_indirect)
- return;
if(filter_c2csops(cache->cache_filter))
filter_c2csops(cache->cache_filter)->read_inode(inode);
- /* XXX now set the correct snap_{file,dir,sym}_iops */
- if (S_ISDIR(inode->i_mode))
- inode->i_op = filter_c2udiops(cache->cache_filter);
- else if (S_ISREG(inode->i_mode)) {
- if ( !filter_c2cfiops(cache->cache_filter) ) {
- filter_setup_file_ops(cache->cache_filter, inode,
- ¤tfs_file_iops,
- ¤tfs_file_fops,
- ¤tfs_file_aops);
- }
- CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
- inode->i_ino, inode->i_op);
- }
- else if (S_ISLNK(inode->i_mode)) {
- if ( !filter_c2csiops(cache->cache_filter) ) {
- filter_setup_symlink_ops(cache->cache_filter, inode,
- ¤tfs_sym_iops, ¤tfs_sym_fops);
- }
- inode->i_op = filter_c2usiops(cache->cache_filter);
- CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
- inode->i_ino, inode->i_op);
- }
+ set_filter_ops(cache, inode);
/*init filter_data struct
* FIXME flag should be set future*/
init_filter_data(inode, 0);
void cleanup_filter_info_cache(void);
int init_filter_info_cache(void);
extern void init_filter_data(struct inode *inode, int flag);
-
+extern void set_filter_ops(struct snap_cache *cache, struct inode *inode);
/* dir.c */
extern struct inode_operations currentfs_dir_iops;
extern struct file_operations currentfs_dir_fops;
#define FILTER_FS_EXT3 1
#define FILTER_FS_REISER 2
extern struct filter_fs filter_oppar[FILTER_FS_TYPES];
-
struct filter_fs *filter_get_filter_fs(const char *cache_type);
inline struct super_operations *filter_c2usops(struct filter_fs *cache);
inline struct inode_operations *filter_c2ufiops(struct filter_fs *cache);
inline struct inode_operations *filter_c2cfiops(struct filter_fs *cache);
inline struct inode_operations *filter_c2cdiops(struct filter_fs *cache);
inline struct inode_operations *filter_c2csiops(struct filter_fs *cache);
+inline struct file_operations *filter_c2udfops(struct filter_fs *cache);
inline struct file_operations *filter_c2cffops(struct filter_fs *cache);
inline struct file_operations *filter_c2cdfops(struct filter_fs *cache);
inline struct file_operations *filter_c2csfops(struct filter_fs *cache);
+inline struct file_operations *filter_c2uffops(struct filter_fs *cache);
+inline struct file_operations *filter_c2usfops(struct filter_fs *cache);
inline struct dentry_operations *filter_c2cdops(struct filter_fs *cache);
inline struct dentry_operations *filter_c2udops(struct filter_fs *cache);
inline struct address_space_operations *filter_c2cfaops(struct filter_fs *cache);
+inline struct address_space_operations *filter_c2ufaops(struct filter_fs *cache);
/* for snapfs */
inline struct snapshot_operations *filter_c2csnapops(struct filter_fs *cache);