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

📄 inode.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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.53 2002/12/27 20:19:01 ezk 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;    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);    err = PTR_ERR(hidden_dir_dentry);    if (IS_ERR(hidden_dir_dentry))	goto out;    err = vfs_create(hidden_dir_dentry->d_inode, hidden_dentry, mode);    if (err)	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);#ifdef FIST_FILTER_SCA    err = wrapfs_idx_create(hidden_dir_dentry->d_inode, dentry, mode);    if (err) {	/*	 * PROBLEM: we created an empty data file at this point.	 * should we unlink it?  maybe.  Another solution might be	 * to change SCA semantics so that a zero-length file need not	 * have an index file.	 */	printk("wrapfs_create: couldn't create idx file %s: %d\n",	       dtopd(dentry)->idx_dentry->d_name.name, err);	goto out_lock;    }    wrapfs_idx_open(dentry, FMODE_WRITE, O_WRONLY);#endif /* FIST_FILTER_SCA */ out_lock:    unlock_dir(hidden_dir_dentry); out:    fist_checkinode(dir, "post wrapfs_create");    print_exit_status(err);    return err;}STATIC dentry_t *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_one will decrement) */    // THIS IS RIGHT! (don't "fix" it)    // NO THIS IS WRONG IN 2.3.99-pre6. lookup_one will NOT decrement    // dget(hidden_dir_dentry);#ifndef FIST_FILTER_NAME    /* will allocate a new hidden dentry if needed */    hidden_dentry = lookup_one(name, hidden_dir_dentry);#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_one(encoded_name, hidden_dir_dentry);    kfree_s(encoded_name, encoded_namelen);#endif /* FIST_FILTER_NAME */    if (IS_ERR(hidden_dentry)) {	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 */    dtopd(dentry) = (struct wrapfs_dentry_info *) kmalloc(sizeof(struct wrapfs_dentry_info), GFP_KERNEL);    if (!dtopd(dentry)) {	err = -ENOMEM;	goto out_dput;    }    dtohd(dentry) = hidden_dentry;#ifdef FIST_FILTER_SCA    /*     * Lookup index file.  Note that we create index files only     * for real files, but at this point we may not know the type     * of the to-be created inode.  We release idx_dentry's in d_release.     */    if (hidden_dentry->d_inode == NULL ||	S_ISREG(hidden_dentry->d_inode->i_mode)) {	dtopd(dentry)->idx_dentry = wrapfs_idx_lookup(hidden_dentry);	if (IS_ERR(dtopd(dentry)->idx_dentry)) {	    err = PTR_ERR(dtopd(dentry)->idx_dentry);	    goto out_free;	}	/* index file exists and data file does not, or viceversa */	if ((dtopd(dentry)->idx_dentry->d_inode == NULL) ^	    (hidden_dentry->d_inode == NULL)) {	    err = -ENOENT;	    goto out_free;	}    }    else	/* no need for index file */	dtopd(dentry)->idx_dentry = NULL;#endif /* FIST_FILTER_SCA */    /* 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_inode(__FUNCTION__ " OUT hidden_inode", hidden_dentry->d_inode);#ifdef FIST_FILTER_SCA    if (S_ISREG(hidden_dentry->d_inode->i_mode)) {	err = wrapfs_idx_open(dentry, FMODE_READ, O_RDONLY);	if (err)	    goto out_free;	err = wrapfs_idx_read(dentry->d_inode);	wrapfs_idx_release(dentry->d_inode);	if (err)	    goto out_free;	wrapfs_idx_open(dentry, FMODE_WRITE, O_WRONLY);    }#endif /* FIST_FILTER_SCA */    /* All is well */    goto out; out_free:    d_drop(dentry);		/* so that our bad dentry will get destroyed */#ifdef FIST_FILTER_SCA    if (dtopd(dentry)->idx_dentry)	dput(dtopd(dentry)->idx_dentry);#endif /* FIST_FILTER_SCA */    kfree_s(dtopd(dentry), sizeof(struct wrapfs_dentry_info));    dtopd(dentry) = NULL;	/* be safe */ out_dput:    dput(hidden_dentry); out:    fist_print_dentry("LOOKUP: dentry OUT", dentry);    print_exit_status(err);    return ERR_PTR(err);}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;#ifdef FIST_FILTER_SCA    /* Also link the index file */    if (old_dentry->d_inode && S_ISREG(old_dentry->d_inode->i_mode)) {	/* These must be in the same directory as the main file */	dentry_t *idx_old_dentry = dtopd(old_dentry)->idx_dentry;	dentry_t *idx_new_dentry = dtopd(new_dentry)->idx_dentry;	if (!check_parent(hidden_dir_dentry, idx_new_dentry))	    goto out_lock;	err = vfs_link(idx_old_dentry,		       hidden_dir_dentry->d_inode,		       idx_new_dentry);	if (err)	    goto out_lock;	fist_copy_attr_timesizes(dir, idx_new_dentry->d_inode);    }#endif    if (!check_parent(hidden_dir_dentry, hidden_new_dentry))	goto out_lock;    err = vfs_link(hidden_old_dentry,		   hidden_dir_dentry->d_inode,		   hidden_new_dentry);    if (err)	goto out_lock;    err = wrapfs_interpose(hidden_new_dentry, new_dentry, dir->i_sb, 0);    if (err)	goto out_lock;    fist_copy_attr_timesizes(dir, hidden_new_dentry->d_inode);    /* propagate number of hard-links */    old_dentry->d_inode->i_nlink = itohi(old_dentry->d_inode)->i_nlink; out_lock:    unlock_dir(hidden_dir_dentry);    dput(hidden_new_dentry);    dput(hidden_old_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);#ifdef FIST_FILTER_SCA    /* first unlink the index file */    if (dentry->d_inode) {	if (S_ISREG(dentry->d_inode->i_mode)) {	    dentry_t *idx_dentry = dtopd(dentry)->idx_dentry;	    if (!check_parent(hidden_dir_dentry, idx_dentry))		goto out_index;	    dget(idx_dentry);	    err = vfs_unlink(hidden_dir, idx_dentry);	    dput(idx_dentry);	    if (err)		printk("SCA unlink \"%s\" failed with error %d\n", dentry->d_name.name, err);	    fist_print_dentry("unlink idx_dentry", idx_dentry);	    if (idx_dentry->d_inode)		fist_print_inode("unlink idx_inode", idx_dentry->d_inode);	}    } else {	printk("No index file for %s!\n", dentry->d_name.name);    } out_index:#endif /* FIST_FILTER_SCA */    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 0    if (err && err != -ENOENT)	goto out_lock;#endif    if (!err)			/* dput does that */	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 || err == -ENOENT)	d_drop(dentry);    dput(dentry);    fist_checkinode(dir, "post wrapfs_unlink-dir");    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;#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;#ifndef FIST_FILTER_NAME    err = vfs_symlink(hidden_dir_dentry->d_inode,		      hidden_dentry,		      symname);#else /* FIST_FILTER_NAME */    encoded_symlen = wrapfs_encode_filename(symname,					    strlen(symname),					    &encoded_symname,					    DO_DOTS, dir, dir->i_sb);    err = vfs_symlink(hidden_dir_dentry->d_inode,		      hidden_dentry,		      encoded_symname);    kfree_s(encoded_symname, encoded_symlen);#endif /* FIST_FILTER_NAME */    if (err)	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);    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;    err = vfs_mkdir(hidden_dir_dentry->d_inode,		    hidden_dentry,		    mode);    if (err)	goto out;    err = wrapfs_interpose(hidden_dentry, dentry, dir->i_sb, 0);    if (err)	goto out;    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:    unlock_dir(hidden_dir_dentry);    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 = 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_rmdir(hidden_dir_dentry->d_inode, hidden_dentry);    dput(hidden_dentry);#if 0    if (err && err != -ENOENT)	goto out_lock;#endif    if (!err)			/* dput does that */	d_delete(hidden_dentry); out_lock:    fist_copy_attr_times(dir, hidden_dir_dentry->d_inode);    /* copy the nlink count for our dentry and our parent's dentry */    dir->i_nlink =  hidden_dir_dentry->d_inode->i_nlink;    /* copy nlink (has to be 0) to ours so iput destroys it */    dentry->d_inode->i_nlink = 0;    unlock_dir(hidden_dir_dentry);    /*     * call d_drop so the system "forgets" about us     */    if (!err || err == -ENOENT)	d_drop(dentry);    dput(dentry);    print_exit_status(err);    return err;}STATIC intwrapfs_mknod(inode_t *dir, dentry_t *dentry, int mode, int dev){    int err;    dentry_t *hidden_dentry = wrapfs_hidden_dentry(dentry);    dentry_t *hidden_dir_dentry;    print_entry_location();    fist_checkinode(dir, "wrapfs_mknod-dir");    hidden_dir_dentry = lock_parent(hidden_dentry);    err = -ENOENT;

⌨️ 快捷键说明

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