www.pudn.com > cryptfs030905.rar > main.c
/* * Copyright (c) 1997-2003 Erez Zadok * Copyright (c) 2001-2003 Stony Brook University * * For specific licensing information, see the COPYING file distributed with * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. * * This Copyright notice must be kept intact and distributed with all * fistgen sources INCLUDING sources generated by fistgen. */ /* * $Id: main.c,v 1.36 2003/07/29 18:17:20 ezk Exp $ */ #ifdef HAVE_CONFIG_H # include#endif /* HAVE_CONFIG_H */ #ifdef FISTGEN # include "fist_cryptfs.h" #endif /* FISTGEN */ #include "fist.h" #include "cryptfs.h" #include /* This definition must only appear after we include */ #ifndef MODULE_LICENSE # define MODULE_LICENSE(bison) #endif /* not MODULE_LICENSE */ /* sb we pass is cryptfs's super_block */ int cryptfs_interpose(dentry_t *hidden_dentry, dentry_t *dentry, super_block_t *sb, int flag) { inode_t *hidden_inode; int err = 0; inode_t *inode; print_entry_location(); hidden_inode = hidden_dentry->d_inode; /* CPW: moved after print_entry_location */ ASSERT(hidden_inode != NULL); ASSERT(dentry->d_inode == NULL); /* * We allocate our new inode below, by calling iget. * iget will call our read_inode which will initialize some * of the new inode's fields */ /* XXX: fist file systems reserve first 10 inodes */ inode = iget(sb, cryptfs_iunique(sb, 10)); if (!inode) { err = -EACCES; /* should be impossible??? */ goto out; } /* * interpose the inode if not already interposed * this is possible if the inode is being reused * XXX: what happens if we get_empty_inode() but there's another already? * for now, ASSERT() that this can't happen; fix later. */ if (itohi(inode) == NULL) itohi(inode) = igrab(hidden_inode); /* Use different set of inode ops for symlinks & directories*/ if (S_ISLNK(hidden_inode->i_mode)) inode->i_op = &cryptfs_symlink_iops; else if (S_ISDIR(hidden_inode->i_mode)) inode->i_op = &cryptfs_dir_iops; /* Use different set of file ops for directories */ if (S_ISDIR(hidden_inode->i_mode)) inode->i_fop = &cryptfs_dir_fops; /* properly initialize special inodes */ if (S_ISBLK(hidden_inode->i_mode) || S_ISCHR(hidden_inode->i_mode) || S_ISFIFO(hidden_inode->i_mode) || S_ISSOCK(hidden_inode->i_mode)) { init_special_inode(inode, hidden_inode->i_mode, hidden_inode->i_rdev); } /* only (our) lookup wants to do a d_add */ if (flag) d_add(dentry, inode); else d_instantiate(dentry, inode); ASSERT(dtopd(dentry) != NULL); /* all well, copy inode attributes */ fist_copy_attr_all(inode, hidden_inode); out: print_exit_status(err); return err; } /* find hidden dentry given this cryptfs dentry */ dentry_t * __cryptfs_hidden_dentry(char *file, char *func, int line, dentry_t *dentry) { dentry_t *hidden_dentry; ASSERT2(dentry != NULL); ASSERT2(dentry->d_op != NULL); ASSERT2(dentry->d_op == &cryptfs_dops // XXX: we may need a special version of this fxn for attach mode || dentry->d_op == &cryptfs_attach_dops ); ASSERT2(dentry->d_sb->s_op == &cryptfs_sops); if (dentry->d_inode) ASSERT2(dentry->d_inode->i_op == &cryptfs_main_iops || dentry->d_inode->i_op == &cryptfs_dir_iops || // XXX: we may need a special version of this fxn for attach mode dentry->d_inode->i_op == &cryptfs_dir_attach_iops || dentry->d_inode->i_op == &cryptfs_symlink_iops); hidden_dentry = dtohd(dentry); ASSERT2(hidden_dentry != NULL); return hidden_dentry; } /* * Parse mount options: dir=XXX and debug=N * * Returns the dentry object of the lower-level (hidden) directory; * We want to mount our stackable file system on top of that hidden directory. * * Sets default debugging level to N, if any. */ dentry_t * cryptfs_parse_options(super_block_t *sb, char *options) { dentry_t *hidden_root = ERR_PTR(-EINVAL); struct nameidata nd; char *name, *tmp, *end; int err = 0; print_entry_location(); /* We don't want to go off the end of our arguments later on. */ for (end = options; *end; end++); while (options < end) { tmp = options; while (*tmp && *tmp != ',') tmp++; *tmp = '\0'; if (!strncmp("dir=", options, 4)) { /* note: the name passed need not be encoded */ name = options + 4; fist_dprint(4, "cryptfs: using directory: %s\n", name); if (path_init(name, LOOKUP_FOLLOW, &nd)) err = path_walk(name, &nd); if (err) { printk("cryptfs: error accessing hidden directory '%s'\n", name); hidden_root = ERR_PTR(err); goto out; } hidden_root = nd.dentry; stopd(sb)->hidden_mnt = nd.mnt; fist_dprint(6, "parse_options: new s_root, inode: 0x%lx, 0x%lx\n", (long) hidden_root, (long) hidden_root->d_inode); } else if (!strncmp("debug=", options, 6)) { int debug = simple_strtoul(options + 6, NULL, 0); fist_set_debug_value(debug); } else { printk(KERN_WARNING "cryptfs: unrecognized option '%s'\n", options); } options = tmp + 1; } out: print_exit_location(); return hidden_root; } /* wrapper to iunique to warn if we have a wrap-around */ ino_t cryptfs_iunique(struct super_block *sb, ino_t maxreserved) { static ino_t counter = 0; ino_t ret; ret = iunique(sb, maxreserved); if (ret < counter) { printk(KERN_WARNING "%s iunique may have wrapped around!\n", __FUNCTION__); } counter = ret; return ret; } /*----*/ // this structure *must* be static!!! (or the memory for 'name' gets // corrupted in 2.3...) static DECLARE_FSTYPE(cryptfs_fs_type, "cryptfs", cryptfs_read_super, 0); static int __init init_cryptfs_fs(void) { printk("Registering cryptfs version $Id: main.c,v 1.36 2003/07/29 18:17:20 ezk Exp $\n"); return register_filesystem(&cryptfs_fs_type); } static void __exit exit_cryptfs_fs(void) { printk("Unregistering cryptfs version $Id: main.c,v 1.36 2003/07/29 18:17:20 ezk Exp $\n"); unregister_filesystem(&cryptfs_fs_type); } EXPORT_NO_SYMBOLS; MODULE_AUTHOR("Erez Zadok "); MODULE_DESCRIPTION("FiST-generated cryptfs filesystem"); MODULE_LICENSE("LGPL"); MODULE_PARM(fist_debug_var, "i"); MODULE_PARM_DESC(fist_debug_var, "Debug level"); module_init(init_cryptfs_fs) module_exit(exit_cryptfs_fs) /* * Local variables: * c-basic-offset: 4 * End: */