📄 main.c
字号:
/* * Copyright (c) 1997-2003 Erez Zadok * Copyright (c) 2001-2003 Stony Brook University * Copyright (c) 1997-2000 Columbia 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.21 2003/02/09 17:51:04 cwright Exp $ */#ifdef HAVE_CONFIG_H# include <config.h>#endif /* HAVE_CONFIG_H */#ifdef FISTGEN# include "fist_wrapfs.h"#endif /* FISTGEN */#include "fist.h"#include "wrapfs.h"#include <linux/module.h>// wrapfs_interpose(inode_t *hidden_inode, inode_t **result, super_block_t *super)intwrapfs_interpose(dentry_t *hidden_dentry, dentry_t *dentry, super_block_t *sb, int flag){ inode_t *hidden_inode = hidden_dentry->d_inode; int err = 0; inode_t *inode; print_entry_location(); ASSERT(hidden_inode != NULL); ASSERT(dentry->d_inode == NULL); /* check that the lower file system didn't cross a mount point */ if (hidden_inode->i_dev != stohs(sb)->s_dev) { err = -EXDEV; goto out; } /* * 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: fix assumption that hidden and our inode numbers are same -- maybe */ inode = iget(sb, hidden_inode->i_ino); if (!inode) { err = -EACCES; /* should be impossible??? */ goto out; } /* interpose the inode */ if (itohi(inode) == NULL) itohi(inode) = igrab(hidden_inode); /* Use different set of file ops for directories */ if (S_ISDIR(hidden_inode->i_mode)) inode->i_op = &wrapfs_dir_iops; /* 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;}#ifdef FIST_DEBUG/* find hidden dentry given wrapfs dentry */dentry_t *__wrapfs_hidden_dentry(char *file, char *func, int line, dentry_t *dentry){ dentry_t *hidden_dentry; ASSERT(dentry != NULL); ASSERT(dentry->d_op != NULL); ASSERT(dentry->d_op == &wrapfs_dops); ASSERT(dentry->d_sb->s_op == &wrapfs_sops); if (dentry->d_inode) ASSERT(dentry->d_inode->i_op == &wrapfs_main_iops || dentry->d_inode->i_op == &wrapfs_dir_iops); hidden_dentry = dtohd(dentry); ASSERT(hidden_dentry != NULL); return hidden_dentry;}#endif /* FIST_DEBUG */STATIC dentry_t *wrapfs_parse_options(super_block_t *sb, char *options){ dentry_t *hidden_root = ERR_PTR(-EINVAL); char *tmp, *end; print_entry_location(); for (end = options; *end; end++); while (options < end) { tmp = options; while (*tmp && *tmp != ',') tmp++; *tmp = '\0'; if (!strncmp("dir=", options, 4)) { fist_dprint(4, "wrapfs: using directory: %s\n", options + 4); hidden_root = lookup_dentry(options + 4, NULL, LOOKUP_FOLLOW); fist_dprint(6, "parse_options: new s_root, inode: 0x%x, 0x%x\n", (int) hidden_root, (int) 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 "wrapfs: unrecognized options '%s'\n", options); } options = tmp + 1; } print_exit_location(); return hidden_root;}super_block_t *wrapfs_read_super(super_block_t *sb, void *raw_data, int silent){ super_block_t *ret_sb = NULL; dentry_t *hidden_root; print_entry_location(); MOD_INC_USE_COUNT; lock_super(sb); if (!raw_data) { printk(KERN_WARNING "wrapfs_read_super: missing data argument\n"); goto out_module; } /* * Allocate superblock private data */ stopd(sb) = kmalloc(sizeof(struct wrapfs_sb_info), GFP_KERNEL); if (!stopd(sb)) { printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); goto out; } stohs(sb) = NULL; hidden_root = wrapfs_parse_options(sb, raw_data); if (IS_ERR(hidden_root)) { printk(KERN_WARNING "wrapfs_read_super: lookup_dentry failed (err = %ld)\n", PTR_ERR(hidden_root)); goto out_free; } if (!hidden_root->d_inode) { printk(KERN_WARNING "wrapfs_read_super: no directory to interpose on\n"); goto out_dput; } stohs(sb) = hidden_root->d_sb; sb->s_op = &wrapfs_sops; /* * we can't use d_alloc_root if we want to use * our own interpose function unchanged, * so we simply replicate *most* of the code in d_alloc_root here */ sb->s_root = d_alloc(NULL, &(const struct qstr) { "/", 1, 0 }); if (IS_ERR(sb->s_root)) { printk(KERN_WARNING "wrapfs_read_super: d_alloc failed\n"); goto out_dput; } sb->s_root->d_op = &wrapfs_dops; sb->s_root->d_sb = sb; sb->s_root->d_parent = sb->s_root; sb->s_blocksize = hidden_root->d_sb->s_blocksize; sb->s_blocksize_bits = hidden_root->d_sb->s_blocksize_bits; /* link the upper and lower dentries */ /* XXX allocate memory for dentry_private_data if needed */ dtohd(sb->s_root) = hidden_root; if (wrapfs_interpose(hidden_root, sb->s_root, sb, 0)) goto out_dput2; ret_sb = sb; fist_print_dentry(__FUNCTION__ "OUT hidden_dentry", hidden_root); goto out; out_dput2: dput(sb->s_root); out_dput: dput(hidden_root); out_free: kfree_s(stopd(sb), sizeof(struct wrapfs_sb_info)); stopd(sb) = NULL; out_module: MOD_DEC_USE_COUNT; out: fist_print_sb("OUT sb", sb); if (stopd(sb)) fist_print_sb("OUT hidden_sb", stohs(sb)); unlock_super(sb); print_exit_location(); return ret_sb;}/*----*/STATIC struct file_system_type wrapfs_fs_type ={ "wrapfs", /* name */ 0, /* flags */ wrapfs_read_super, /* read_super function */ NULL /* next file_system_type */};intinit_wrapfs_fs(void){ return register_filesystem(&wrapfs_fs_type);}/* Every kernel module contains stuff like this. */#ifdef MODULEintinit_module(void){ printk("Inserting module wrapfs version $Id: main.c,v 1.21 2003/02/09 17:51:04 cwright Exp $\n"); return init_wrapfs_fs();}voidcleanup_module(void){ printk("Removing module wrapfs version $Id: main.c,v 1.21 2003/02/09 17:51:04 cwright Exp $\n"); unregister_filesystem(&wrapfs_fs_type);}voidfist_mod_dec_use_count(void){ MOD_DEC_USE_COUNT;}EXPORT_NO_SYMBOLS;MODULE_AUTHOR("Erez Zadok <ezk@cs.columbia.edu>");MODULE_DESCRIPTION("FiST-generated wrapfs filesystem");MODULE_PARM(fist_debug_var, "i");MODULE_PARM_DESC(fist_debug_var, "Debug level");#endif /* MODULE *//* * Local variables: * c-basic-offset: 4 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -