void filter_setup_file_ops(struct filter_fs *cache, struct inode *inode, struct inode_operations *filter_iops, struct file_operations *filter_fops) { struct inode_operations *pr_iops; struct inode_operations *cache_iops = inode->i_op; struct file_operations *cache_fops = inode->i_fop; FENTRY; if ( cache->o_flags & FILTER_DID_FILE_OPS ) { FEXIT; return; } cache->o_flags |= FILTER_DID_FILE_OPS; /* steal the old ops */ /* former ops become cache_ops */ cache->o_caops.cache_file_iops = cache_iops; cache->o_caops.cache_file_fops = cache_fops; /* abbreviate */ pr_iops = filter_c2ufiops(cache); /* setup our dir iops: copy and modify */ memcpy(pr_iops, cache_iops, sizeof(*cache_iops)); /* copy dir fops */ CERROR("*** cache file ops at %p\n", cache_fops); memcpy(filter_c2uffops(cache), cache_fops, sizeof(*cache_fops)); /* assign */ /* See comments above in filter_setup_dir_ops. SHP */ /*if (cache_iops->setattr)*/ pr_iops->setattr = filter_iops->setattr; if (cache_iops->getattr) pr_iops->getattr = filter_iops->getattr; /* XXX Should this be conditional rmr ? */ pr_iops->permission = filter_iops->permission; #ifdef CONFIG_FS_EXT_ATTR /* For now we assume that posix acls are handled through extended * attributes. If this is not the case, we must explicitly trap and * posix_set_acl */ if (cache_iops->set_ext_attr && filter_iops->set_ext_attr) pr_iops->set_ext_attr = filter_iops->set_ext_attr; #endif /* unconditional filtering operations */ filter_c2uffops(cache)->open = filter_fops->open; filter_c2uffops(cache)->release = filter_fops->release; filter_c2uffops(cache)->write = filter_fops->write; filter_c2uffops(cache)->ioctl = filter_fops->ioctl; FEXIT; }
void presto_set_ops(struct inode *inode, struct filter_fs *filter) { ENTRY; if (!inode || is_bad_inode(inode)) return; if (inode->i_gid == presto_excluded_gid ) { EXIT; CDEBUG(D_INODE, "excluded methods for %ld at %p, %p\n", inode->i_ino, inode->i_op, inode->i_fop); return; } if (S_ISREG(inode->i_mode)) { if ( !filter_c2cfiops(filter) ) { filter_setup_file_ops(filter, inode, &presto_file_iops, &presto_file_fops); } inode->i_op = filter_c2ufiops(filter); inode->i_fop = filter_c2uffops(filter); CDEBUG(D_INODE, "set file methods for %ld to %p\n", inode->i_ino, inode->i_op); } else if (S_ISDIR(inode->i_mode)) { inode->i_op = filter_c2udiops(filter); inode->i_fop = filter_c2udfops(filter); CDEBUG(D_INODE, "set dir methods for %ld to %p lookup %p\n", inode->i_ino, inode->i_op, inode->i_op->lookup); } else if (S_ISLNK(inode->i_mode)) { if ( !filter_c2csiops(filter)) { filter_setup_symlink_ops(filter, inode, &presto_sym_iops, &presto_sym_fops); } inode->i_op = filter_c2usiops(filter); inode->i_fop = filter_c2usfops(filter); CDEBUG(D_INODE, "set link methods for %ld to %p\n", inode->i_ino, inode->i_op); } EXIT; }