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; }
/* XXX in 2.3 there are "fast" and "slow" symlink ops for ext2 XXX */ void filter_setup_symlink_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_SYMLINK_OPS ) { FEXIT; return; } cache->o_flags |= FILTER_DID_SYMLINK_OPS; /* steal the old ops */ cache->o_caops.cache_sym_iops = cache_iops; cache->o_caops.cache_sym_fops = cache_fops; /* abbreviate */ pr_iops = filter_c2usiops(cache); /* setup our dir iops: copy and modify */ memcpy(pr_iops, cache_iops, sizeof(*cache_iops)); /* 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; /* assign */ /* copy fops - careful for symlinks they might be NULL */ if ( cache_fops ) { memcpy(filter_c2usfops(cache), cache_fops, sizeof(*cache_fops)); } FEXIT; }