⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 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.33 2003/02/09 17:50:53 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>/* This definition must only appear after we include <linux/module.h> */#ifndef MODULE_LICENSE#define MODULE_LICENSE(foo)#endif /* not MODULE_LICENSE *//* sb we pass is wrapfs's super_block */intwrapfs_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     */#ifdef FIST_DYNAMIC_INODE_NUMBERS    /* XXX: fist file systems reserve first 10 inodes */    inode = iget(sb, wrapfs_iunique(sb, 10));#else /* not FIST_DYNAMIC_INODE_NUMBERS */    /* 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;    }    inode = iget(sb, hidden_inode->i_ino);#endif /* not FIST_DYNAMIC_INODE_NUMBERS */    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 = &wrapfs_symlink_iops;    else if (S_ISDIR(hidden_inode->i_mode))	inode->i_op = &wrapfs_dir_iops;    /* Use different set of file ops for directories */    if (S_ISDIR(hidden_inode->i_mode))	inode->i_fop = &wrapfs_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);    }#ifndef FIST_FILTER_DATA    /* Fix our inode's address operations to that of the lower inode */    if (inode->i_mapping->a_ops != hidden_inode->i_mapping->a_ops) {	fist_dprint(7, "fixing inode 0x%x a_ops (0x%x -> 0x%x)\n",		    (int) inode, (int) inode->i_mapping->a_ops,		    (int) hidden_inode->i_mapping->a_ops);	inode->i_mapping->a_ops = hidden_inode->i_mapping->a_ops;    }#endif /* not FIST_FILTER_DATA */    /* 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 this wrapfs dentry */dentry_t *__wrapfs_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 == &wrapfs_dops#ifdef FIST_MNTSTYLE_ATTACH	    // XXX: we may need a special version of this fxn for attach mode	    || dentry->d_op == &wrapfs_attach_dops#endif /* FIST_MNTSTYLE_ATTACH */	    );    ASSERT2(dentry->d_sb->s_op == &wrapfs_sops);    if (dentry->d_inode)	ASSERT2(dentry->d_inode->i_op == &wrapfs_main_iops ||		dentry->d_inode->i_op == &wrapfs_dir_iops ||#ifdef FIST_MNTSTYLE_ATTACH		// XXX: we may need a special version of this fxn for attach mode		dentry->d_inode->i_op == &wrapfs_dir_attach_iops ||#endif /* FIST_MNTSTYLE_ATTACH */		dentry->d_inode->i_op == &wrapfs_symlink_iops);    hidden_dentry = dtohd(dentry);    ASSERT2(hidden_dentry != NULL);    return hidden_dentry;}#endif /* FIST_DEBUG *//* * 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 *wrapfs_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, "wrapfs: using directory: %s\n", name);	    if (path_init(name, LOOKUP_FOLLOW, &nd))		err = path_walk(name, &nd);	    if (err) {		printk("wrapfs: 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 "wrapfs: unrecognized option '%s'\n", options);	}	options = tmp + 1;    }out:    print_exit_location();    return hidden_root;}#ifndef FIST_MNTSTYLE_ATTACH/* for attach mode, we use a different ->read_super() in attach.c */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();    if (!raw_data) {	printk(KERN_WARNING "wrapfs_read_super: missing data argument\n");	goto out;    }    /*     * 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;#ifdef FIST_FILTER_SCA    stopd(sb)->sca_flags = 0;#endif /* FIST_FILTER_SCA */    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_free;    }    stohs(sb) = hidden_root->d_sb;    /*     * Linux 2.4.2-ac3 and beyond has code in     * mm/filemap.c:generic_file_write() that requires sb->s_maxbytes     * to be populated.  If not set, all write()s under that sb will     * return 0.     *     * Linux 2.4.4+ automatically sets s_maxbytes to MAX_NON_LFS;     * the filesystem should override it only if it supports LFS.     */#ifdef FIST_FILTER_SCA    /* SCA code is not yet LFS-clean */# if (LINUX_VERSION_CODE == KERNEL_VERSION(2,4,2)) || (LINUX_VERSION_CODE == KERNEL_VERSION(2,4,3))    sb->s_maxbytes = MAX_NON_LFS;# endif /* linux 2.4.[23] */#else  /* not FIST_FILTER_SCA */    /* non-SCA code is good to go with LFS */    sb->s_maxbytes = hidden_root->d_sb->s_maxbytes;#endif /* not FIST_FILTER_SCA */    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;    /* link the upper and lower dentries */    dtopd(sb->s_root) = (struct wrapfs_dentry_info *) kmalloc(sizeof(struct wrapfs_dentry_info), GFP_KERNEL);    if (!dtopd(sb->s_root)) {	goto out_dput2;    }    dtohd(sb->s_root) = hidden_root;#ifdef FIST_FILTER_SCA    dtopd(sb->s_root)->idx_dentry = NULL;#endif /* FIST_FILTER_SCA */    if (wrapfs_interpose(hidden_root, sb->s_root, sb, 0))	goto out_dput2;    ret_sb = sb;    fist_print_dentry("wrapfs_read_super OUT hidden_dentry", hidden_root);    fist_print_inode("wrapfs_read_super OUT hidden_inode", hidden_root->d_inode);    // next line causes null ptr deref at mount(2) time    // fist_print_dentry("%s OUT sb->s_root", __FUNCTION__, sb->s_root);    goto out; out_dput2:    dput(sb->s_root); out_dput:    dput(hidden_root); out_free:    kfree(stopd(sb));    stopd(sb) = NULL; out:    fist_print_sb("OUT sb", sb);    if (stopd(sb))	fist_print_sb("OUT hidden_sb", stohs(sb));    print_exit_location();    return ret_sb;}#endif /* not FIST_MNTSTYLE_ATTACH */#ifdef FIST_DYNAMIC_INODE_NUMBERS/* wrapper to iunique to warn if we have a wrap-around */ino_twrapfs_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;}#endif /* FIST_DYNAMIC_INODE_NUMBERS *//*----*/// this structure *must* be static!!! (or the memory for 'name' gets// corrupted in 2.3...)static DECLARE_FSTYPE(wrapfs_fs_type, "wrapfs", wrapfs_read_super, 0);static int __init init_wrapfs_fs(void){    printk("Registering wrapfs version $Id: main.c,v 1.33 2003/02/09 17:50:53 cwright Exp $\n");    return register_filesystem(&wrapfs_fs_type);}static void __exit exit_wrapfs_fs(void){    printk("Unregistering wrapfs version $Id: main.c,v 1.33 2003/02/09 17:50:53 cwright Exp $\n");    unregister_filesystem(&wrapfs_fs_type);}EXPORT_NO_SYMBOLS;MODULE_AUTHOR("Erez Zadok <ezk@cs.columbia.edu>");MODULE_DESCRIPTION("FiST-generated wrapfs filesystem");MODULE_LICENSE("LGPL");MODULE_PARM(fist_debug_var, "i");MODULE_PARM_DESC(fist_debug_var, "Debug level");module_init(init_wrapfs_fs)module_exit(exit_wrapfs_fs)/* * Local variables: * c-basic-offset: 4 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -