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

📄 inode.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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: inode.c,v 1.23 2003/02/10 04:08:13 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"STATIC intwrapfs_create(inode_t *dir, dentry_t *dentry, int mode){    int err = -EACCES;    dentry_t *hidden_dentry = wrapfs_hidden_dentry(dentry);    dentry_t *hidden_dir_dentry;    print_entry_location();    ASSERT(hidden_dentry != NULL);    fist_checkinode(dir, "wrapfs_create");    hidden_dir_dentry = lock_parent(hidden_dentry);    if (IS_ERR(hidden_dir_dentry)) {	err = PTR_ERR(hidden_dir_dentry);	goto out;    }    if (!hidden_dir_dentry->d_inode->i_op || !hidden_dir_dentry->d_inode->i_op->create)	goto out_lock;    err = hidden_dir_dentry->d_inode->i_op->create(hidden_dir_dentry->d_inode,						   hidden_dentry, mode);    if (err || !hidden_dentry->d_inode)	goto out_lock;    err = wrapfs_interpose(hidden_dentry, dentry, dir->i_sb, 0);    if (err)	goto out_lock;    fist_copy_attr_timesizes(dir, hidden_dir_dentry->d_inode);    fist_checkinode(dir, "post wrapfs_create"); out_lock:    unlock_dir(hidden_dir_dentry);    if (!dentry->d_inode)	d_drop(dentry); out:    print_exit_status(err);    return err;}/* * Before 2.2.7: lookup must fill in dentry and return errno (0 if ok) * Since 2.2.7: if err, returns ERR_PTR, else 0. */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,7)STATIC dentry_t *#else /* kernel before 2.2.7 */STATIC int#endif /* kernel before 2.2.7 */wrapfs_lookup(inode_t *dir, dentry_t *dentry){    int err = 0;    dentry_t *hidden_dir_dentry = wrapfs_hidden_dentry(dentry->d_parent);    dentry_t *hidden_dentry;    const char *name = dentry->d_name.name;    vnode_t *this_vnode;    dentry_t *this_dir;#ifdef FIST_FILTER_NAME    unsigned int namelen = dentry->d_name.len;    char *encoded_name;    unsigned int encoded_namelen;#endif /* FIST_FILTER_NAME */    print_entry_location();    fist_checkinode(dir, "wrapfs_lookup");    this_vnode = dir;    this_dir = hidden_dir_dentry;    fist_print_dentry("LOOKUP: dentry IN", dentry);    fist_print_dentry("LOOKUP: dentry->d_parent IN", dentry->d_parent);    fist_print_dentry("LOOKUP: hidden_dir_dentry IN", hidden_dir_dentry);    fist_print_inode("LOOKUP: dir IN", dir);    if (hidden_dir_dentry->d_inode)	fist_print_inode("LOOKUP: hidden_dir_dentry->d_inode",			 hidden_dir_dentry->d_inode);    /* must initialize dentry operations */    dentry->d_op = &wrapfs_dops;    FIST_OP_LOOKUP_PRECALL;    /* increase refcount of base dentry (lookup_dentry will decrement) */    // THIS IS RIGHT! (don't "fix" it)    dget(hidden_dir_dentry);#ifndef FIST_FILTER_NAME    /* will allocate a new hidden dentry if needed */    hidden_dentry = lookup_dentry(name, hidden_dir_dentry, 0);#else /* FIST_FILTER_NAME */    encoded_namelen = wrapfs_encode_filename(name,					     namelen,					     &encoded_name,					     SKIP_DOTS, dir, dir->i_sb);    /* will allocate a new hidden dentry if needed */    hidden_dentry = lookup_dentry(encoded_name, hidden_dir_dentry, 0);    kfree_s(encoded_name, encoded_namelen);#endif /* FIST_FILTER_NAME */    if (IS_ERR(hidden_dentry)) {	/*	 * this produces an unusual dentry: one that has neither an	 * inode, nor a private structure attached to it. All cleanup	 * methods (d_delete, d_release, etc) must be prepared to deal	 * with such dentries. Ion 09/29/2001	 */	printk("ERR from hidden_dentry!!!\n");	err = PTR_ERR(hidden_dentry);	goto out;    }    FIST_OP_LOOKUP_POSTCALL;    /* update parent directory's atime */    fist_copy_attr_atime(dir, hidden_dir_dentry->d_inode);    /* link the upper and lower dentries */    /* XXX allocate dentry_private_data if necessary */    dtohd(dentry) = hidden_dentry;    /* lookup is special: it needs to handle negative dentries */    if (!hidden_dentry->d_inode) {	d_add(dentry, NULL);	fist_print_dentry("lookup hidden", hidden_dentry);	goto out;    }    fist_dprint(6, "lookup \"%s\" -> inode %d\n", name, hidden_dentry->d_inode->i_ino);    err = wrapfs_interpose(hidden_dentry, dentry, dir->i_sb, 1);    if (err)	goto out_free;    fist_checkinode(dentry->d_inode, "wrapfs_lookup OUT: dentry->d_inode:");    fist_checkinode(dir, "wrapfs_lookup OUT: dir:");    fist_print_dentry(__FUNCTION__ " OUT hidden_dentry", hidden_dentry);    fist_print_dentry(__FUNCTION__ " OUT hidden_dir_dentry", hidden_dir_dentry);    /* All is well */    goto out; out_free:    d_drop(dentry);    /* XXX free dentry_private_data if necessary */    dtopd(dentry) = NULL;out:    fist_print_dentry("LOOKUP: dentry OUT", dentry);    print_exit_status(err);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,7)    return ERR_PTR(err);#else /* kernel before 2.2.7 */    return err;#endif /* kernel before 2.2.7 */}STATIC intwrapfs_link(dentry_t *old_dentry, inode_t *dir, dentry_t *new_dentry){    int err;    dentry_t *hidden_old_dentry = wrapfs_hidden_dentry(old_dentry);    dentry_t *hidden_new_dentry = wrapfs_hidden_dentry(new_dentry);    dentry_t *hidden_dir_dentry;    print_entry_location();    fist_checkinode(dir, "wrapfs_link-dir");    fist_checkinode(old_dentry->d_inode, "wrapfs_link-oldinode");    dget(hidden_old_dentry);    dget(hidden_new_dentry);    hidden_dir_dentry = lock_parent(hidden_new_dentry);    err = -ENOENT;    if (!check_parent(hidden_dir_dentry, hidden_new_dentry))	goto out_lock;    err = -EXDEV;    if (hidden_dir_dentry->d_inode->i_dev != hidden_old_dentry->d_inode->i_dev)	goto out_lock;    err = -EPERM;    if (!hidden_dir_dentry->d_inode->i_op || !hidden_dir_dentry->d_inode->i_op->link)	goto out_lock;    DQUOT_INIT(hidden_dir_dentry->d_inode);    err = hidden_dir_dentry->d_inode->i_op->link(hidden_old_dentry,						 hidden_dir_dentry->d_inode,						 hidden_new_dentry);    if (err || !hidden_new_dentry->d_inode)	goto out_lock;    err = wrapfs_interpose(hidden_new_dentry, new_dentry, dir->i_sb, 0);    if (err)	goto out_lock;    /*     * XXX: we have to do a wrapfs_copy_inode (or subset thereof) in     * *ALL* functions, all file systems, and all OSs!!!     */    fist_copy_attr_timesizes(dir, hidden_new_dentry->d_inode); out_lock:    unlock_dir(hidden_dir_dentry);    dput(hidden_new_dentry);    dput(hidden_old_dentry);    if (!new_dentry->d_inode)	d_drop(new_dentry);    print_exit_status(err);    return err;}STATIC intwrapfs_unlink(inode_t *dir, dentry_t *dentry){    int err = 0;    inode_t *hidden_dir = itohi(dir);    dentry_t *hidden_dentry = wrapfs_hidden_dentry(dentry);    dentry_t *hidden_dir_dentry;    print_entry_location();    ASSERT(hidden_dentry != NULL);    fist_checkinode(dir, "wrapfs_unlink-dir");    dget(dentry);    hidden_dir_dentry = lock_parent(hidden_dentry);    if (!check_parent(hidden_dir_dentry, hidden_dentry))	goto out_lock;    /* avoid destroying the hidden inode if the file is in use */    dget(hidden_dentry);    err = vfs_unlink(hidden_dir, hidden_dentry);    dput(hidden_dentry);    if (!err)	d_delete(hidden_dentry); out_lock:    fist_copy_attr_times(dir, hidden_dir);    /* propagate number of hard-links */    dentry->d_inode->i_nlink = itohi(dentry->d_inode)->i_nlink;    unlock_dir(hidden_dir_dentry);    /*     * call d_drop so the system "forgets" about us     */    if (!err)	d_drop(dentry);    dput(dentry);    print_exit_status(err);    return err;}STATIC intwrapfs_symlink(inode_t *dir, dentry_t *dentry, const char *symname){    int err;    dentry_t *hidden_dentry = wrapfs_hidden_dentry(dentry);    dentry_t *hidden_dir_dentry;    const char *hidden_symname = symname; /* XXX: can modify this */#ifdef FIST_FILTER_NAME    char *encoded_symname;    unsigned int encoded_symlen;#endif /* FIST_FILTER_NAME */    print_entry_location();    fist_checkinode(dir, "wrapfs_symlink-dir");    dget(hidden_dentry);    hidden_dir_dentry = lock_parent(hidden_dentry);    err = -ENOENT;    if (!check_parent(hidden_dir_dentry, hidden_dentry))	goto out_lock;    if (!hidden_dir_dentry->d_inode->i_op ||	!hidden_dir_dentry->d_inode->i_op->symlink) {	err = -EPERM;	goto out_lock;    }#ifndef FIST_FILTER_NAME    err = hidden_dir_dentry->d_inode->i_op->symlink(hidden_dir_dentry->d_inode,						    hidden_dentry,						    hidden_symname);#else /* FIST_FILTER_NAME */    encoded_symlen = wrapfs_encode_filename(symname,					    strlen(symname),					    &encoded_symname,					    DO_DOTS, dir, dir->i_sb);    err = hidden_dir_dentry->d_inode->i_op->symlink(hidden_dir_dentry->d_inode,						    hidden_dentry,						    encoded_symname);    kfree_s(encoded_symname, encoded_symlen);#endif /* FIST_FILTER_NAME */    if (err || !hidden_dentry->d_inode)	goto out_lock;    err = wrapfs_interpose(hidden_dentry, dentry, dir->i_sb, 0);    if (err)	goto out_lock;    fist_copy_attr_timesizes(dir, hidden_dir_dentry->d_inode);    fist_checkinode(dir, "post wrapfs_symlink-dir"); out_lock:    unlock_dir(hidden_dir_dentry);    dput(hidden_dentry);    if (!dentry->d_inode)	d_drop(dentry);    print_exit_status(err);    return err;}STATIC intwrapfs_mkdir(inode_t *dir, dentry_t *dentry, int mode){    int err;    dentry_t *hidden_dentry = wrapfs_hidden_dentry(dentry);    dentry_t *hidden_dir_dentry;    print_entry_location();    fist_checkinode(dir, "wrapfs_mkdir-dir");    hidden_dir_dentry = lock_parent(hidden_dentry);    err = -ENOENT;    if (!check_parent(hidden_dir_dentry, hidden_dentry))	goto out_lock;    if (!hidden_dir_dentry->d_inode->i_op ||	!hidden_dir_dentry->d_inode->i_op->mkdir) {	err = -EPERM;	goto out_lock;    }    err = hidden_dir_dentry->d_inode->i_op->mkdir(hidden_dir_dentry->d_inode,						  hidden_dentry,						  mode);    if (err || !hidden_dentry->d_inode)	goto out_lock;    err = wrapfs_interpose(hidden_dentry, dentry, dir->i_sb, 0);    if (err)	goto out_lock;    fist_copy_attr_timesizes(dir, hidden_dir_dentry->d_inode);    /* update number of links on parent directory */    dir->i_nlink = hidden_dir_dentry->d_inode->i_nlink;    fist_checkinode(dir, "post wrapfs_mkdir-dir"); out_lock:    unlock_dir(hidden_dir_dentry);    if (!dentry->d_inode)	d_drop(dentry); out:    print_exit_status(err);    return err;}STATIC intwrapfs_rmdir(inode_t *dir, dentry_t *dentry){    int err = 0;    dentry_t *hidden_dentry = wrapfs_hidden_dentry(dentry);    dentry_t *hidden_dir_dentry;    print_entry_location();    fist_checkinode(dir, "wrapfs_rmdir-dir");    dget(dentry);    hidden_dir_dentry = dget(hidden_dentry->d_parent);

⌨️ 快捷键说明

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