📄 attach.c
字号:
d_instantiate(sb->s_root, inode); /* XXX: call d_add instead? */ /* initialize inode fields? */ // fist_copy_attr_all(inode, hidden_inode); inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; inode->i_blksize = 1024;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12) inode->i_blkbits = 10; /* XXX: correct? */#endif /* linux 2.4.12 and newer */ inode->i_nlink = 2; inode->i_size = PAGE_SIZE; /* XXX: correct? */ inode->i_blocks = PAGE_SIZE / inode->i_blksize; /* XXX: what a hack */ fist_print_inode("wrapfs_read_super OUT", inode); ret_sb = sb; goto out; out_dput2: dput(sb->s_root); out: fist_print_sb("wrapfs_read_super OUT", sb); print_exit_location(); return ret_sb;}/**************************************************************************** *** SUPERBLOCK OPS *** ****************************************************************************/STATIC intwrapfs_statfs(super_block_t *sb, struct statfs *buf){ int err = 0; attached_entry_t *ent; struct list_head *p; print_entry_location(); buf->f_type = WRAPFS_SUPER_MAGIC; buf->f_bsize = PAGE_SIZE / sizeof(long); buf->f_bfree = 0; buf->f_bavail = 0; buf->f_ffree = 0; buf->f_namelen = NAME_MAX; read_lock(&(stopd(sb)->attachlock)); list_for_each(p, &(stopd(sb)->attached)) { ent = list_entry(p, attached_entry_t, list); printk("ENT:%*s:\n", ent->e_dentry->d_name.len, ent->e_dentry->d_name.name); } read_unlock(&(stopd(sb)->attachlock)); print_exit_status(err); return err;}/**************************************************************************** *** INODE OPS *** ****************************************************************************/STATIC dentry_t *wrapfs_lookup_attach(inode_t *dir, dentry_t *dentry){ int err = -ENOENT; print_entry_location(); fist_print_inode("ALi", dir); fist_print_dentry("ALd", dentry); /* XXX: add code to lookup attached nodes in this attach node. look if node already exists and return that instead. */ // For now, fake success. // Returning NULL means OK, this entry "exists", even if it's yet // to be created via do_attach(). err = 0; print_exit_status(err); return ERR_PTR(err);}STATIC intwrapfs_permission_attach(inode_t *inode, int mask){ int err; print_entry_location(); // XXX: here's where cryptfs might want to check permissions (and/or keys // on the attach node. err = vfs_permission(inode, mask); print_exit_status(err); return err;}STATIC intwrapfs_inode_revalidate_attach(dentry_t *dentry){ int err = 0; print_entry_location(); // XXX: do we really need ->revalidate()? // Maybe only if we add/del attached nodes? print_exit_status(err); return err;}struct inode_operations wrapfs_dir_attach_iops ={ lookup: wrapfs_lookup_attach, permission: wrapfs_permission_attach, revalidate: wrapfs_inode_revalidate_attach,};/**************************************************************************** *** DENTRY OPS *** ****************************************************************************/struct dentry_operations wrapfs_attach_dops = { // d_revalidate: wrapfs_d_revalidate, // d_hash: wrapfs_d_hash, // d_compare: wrapfs_d_compare, d_release: wrapfs_d_release, d_delete: wrapfs_d_delete,#ifdef FIST_DEBUG d_iput: wrapfs_d_iput,#endif /* FIST_DEBUG */};/**************************************************************************** *** FILE OPS *** ****************************************************************************/STATIC intwrapfs_readdir_attach(file_t *file, void *dirent, filldir_t filldir){ int err = 1; unsigned int ino; int i; struct inode *inode; attached_entry_t *ent; struct list_head *p; print_entry_location(); inode = file->f_dentry->d_inode; /* CPW: Moved after print_entry */ ino = inode->i_ino; i = file->f_pos; switch (i) { case 0: if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) { err = 0; goto out; } i++; file->f_pos++; /* fall through */ case 1: if (filldir(dirent, "..", 2, i, file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { err = 0; goto out; } i++; file->f_pos++; /* fall through */ default: read_lock(&(stopd(inode->i_sb)->attachlock)); i -= 2; printk("I: %d\n", i); list_for_each(p, &(stopd(inode->i_sb)->attached)) { if (i <= 0) { ent = list_entry(p, attached_entry_t, list); fist_print_dentry("FD", ent->e_dentry); if (filldir(dirent, ent->e_dentry->d_name.name, ent->e_dentry->d_name.len, file->f_pos, ent->e_dentry->d_inode->i_ino, DT_DIR) < 0) { err = 0; read_unlock(&(stopd(inode->i_sb)->attachlock)); goto outlock; } file->f_pos++; } i--; } // printk("EZK: NOTHING TO DO YET HERE... %s\n", __FUNCTION__); } outlock: read_unlock(&(stopd(inode->i_sb)->attachlock)); out: print_exit_status(err); return err;}STATIC intwrapfs_ioctl_attach(inode_t *inode, file_t *file, unsigned int cmd, unsigned long arg){ int err = -EINVAL; /* don't fail by default */ int ret; super_block_t *sb; char *from = NULL, *to = NULL; /* These structures are 8 and 4 bytes respectively and mutually exclusive */ union { struct fist_ioctl_attach_data ad; struct fist_ioctl_detach_data dd; } u; print_entry_location(); sb = inode->i_sb; // XXX: verify we're only attaching to the top-level node! // XXX: not attaching to itself // only attaching to directories: done in do_attach /* check if asked for our commands */ switch (cmd) { case FIST_IOCTL_ATTACH: if (copy_from_user(&(u.ad), (const char *) arg, sizeof(struct fist_ioctl_attach_data))) { err = -EFAULT; goto out; } from = getname(u.ad.from); err = PTR_ERR(from); if (IS_ERR(from)) { goto out; } to = getname(u.ad.to); err = PTR_ERR(to); if (IS_ERR(to)) { goto outputfrom; } err = do_attach(inode, file, from, to); break; case FIST_IOCTL_DETACH: if (copy_from_user(&(u.dd), (const char *) arg, sizeof(struct fist_ioctl_detach_data))) { err = -EFAULT; goto out; } printk("Got structure: %p!\n", u.dd.from); from = getname(u.dd.from); printk("Got name: %p!\n", from); if (IS_ERR(from)) { err = PTR_ERR(from); goto out; } printk("XXX: DETACH %s\n", from); err = do_detach(inode, file, from); break; default: /* by default other ioctls are not allowed on the attach node */ break; } outputto: if (to) putname(to); outputfrom: if (from) putname(from); out: print_exit_status(err); return err;}struct file_operations wrapfs_dir_attach_fops ={ // XXX: followed model from procfs // llseek: wrapfs_llseek, // read: wrapfs_read, read: generic_file_read, // write: wrapfs_write, readdir: wrapfs_readdir_attach, // poll: wrapfs_poll, ioctl: wrapfs_ioctl_attach, // mmap: generic_file_mmap, // open: wrapfs_open, // flush: wrapfs_flush, // release: wrapfs_release, // fsync: wrapfs_fsync, // fasync: wrapfs_fasync, // lock: wrapfs_lock, /* not needed: readv */ /* not needed: writev */};/* * Local variables: * c-basic-offset: 4 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -