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

📄 super.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: super.c,v 1.17 2003/02/10 04:08:02 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 voidwrapfs_read_inode(inode_t *inode){#ifndef FIST_FILTER_DATA    static struct address_space_operations wrapfs_empty_aops;#endif /* not FIST_FILTER_DATA */    print_entry_location();    itopd(inode) = kmalloc(sizeof(struct wrapfs_inode_info), GFP_KERNEL);    if (!itopd(inode)) {	printk("<0>%s:%s:%d: No kernel memory!\n", __FILE__, __FUNCTION__, __LINE__);	ASSERT(NULL);    }    itohi(inode) = NULL;#ifdef FIST_FILTER_SCA    itopd(inode)->idx_file = NULL;    memset(&(itopd(inode)->hdr), 0, sizeof(struct scafs_header));#endif /* FIST_FILTER_SCA */    inode->i_version = ++event;	/* increment inode version */    inode->i_op = &wrapfs_main_iops;    inode->i_fop = &wrapfs_main_fops;#if 0    /*     * XXX: To export a file system via NFS, it has to have the     * FS_REQUIRES_DEV flag, so turn it on.  But should we inherit it from     * the lower file system, or can we allow our file system to be exported     * even if the lower one cannot be natively exported.     */    inode->i_sb->s_type->fs_flags |= FS_REQUIRES_DEV;    /*     * OK, the above was a hack, which is now turned off because it may     * cause a panic/oops on some systems.  The correct way to export a     * "nodev" filesystem is via using nfs-utils > 1.0 and the "fsid=" export     * parameter, which requires 2.4.20 or later.     */#endif#ifdef FIST_FILTER_DATA    inode->i_mapping->a_ops = &wrapfs_aops;#else /* not FIST_FILTER_DATA */    /* I don't think ->a_ops is ever allowed to be NULL */    inode->i_mapping->a_ops = &wrapfs_empty_aops;    fist_dprint(7, "setting inode 0x%x a_ops to empty (0x%x)\n",		(int) inode, (int) inode->i_mapping->a_ops);#endif /* not FIST_FILTER_DATA */    print_exit_location();}#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)/* * No need to call write_inode() on the lower inode, as it * will have been marked 'dirty' anyway. But we might need * to write some of our own stuff to disk. */STATIC voidwrapfs_write_inode(inode_t *inode, int sync){    print_entry_location();#ifdef FIST_FILTER_SCA    wrapfs_idx_write(inode);#endif /* FIST_FILTER_SCA */    print_exit_location();}#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */STATIC voidwrapfs_put_inode(inode_t *inode){    print_entry_location();    fist_dprint(8, "%s i_count = %d, i_nlink = %d\n", __FUNCTION__,		atomic_read(&inode->i_count), inode->i_nlink);    /*     * This is really funky stuff:     * Basically, if i_count == 1, iput will then decrement it and this inode will be destroyed.     * It is currently holding a reference to the hidden inode.     * Therefore, it needs to release that reference by calling iput on the hidden inode.     * iput() _will_ do it for us (by calling our clear_inode), but _only_ if i_nlink == 0.     * The problem is, NFS keeps i_nlink == 1 for silly_rename'd files.     * So we must for our i_nlink to 0 here to trick iput() into calling our clear_inode.     */    if (atomic_read(&inode->i_count) == 1)	inode->i_nlink = 0;    print_exit_location();}#ifdef FIST_DEBUG/* * we now define delete_inode, because there are two VFS paths that may * destroy an inode: one of them calls clear inode before doing everything * else that's needed, and the other is fine.  This way we truncate the inode * size (and its pages) and then clear our own inode, which will do an iput * on our and the lower inode. */STATIC voidwrapfs_delete_inode(inode_t *inode){    print_entry_location();    fist_checkinode(inode, "wrapfs_delete_inode IN");    inode->i_size = 0;		/* every f/s seems to do that */    clear_inode(inode);    print_exit_location();}#endif /* FIST_DEBUG *//* final actions when unmounting a file system */STATIC voidwrapfs_put_super(super_block_t *sb){    print_entry_location();    if (stopd(sb)) {#ifndef FIST_MNTSTYLE_ATTACH	mntput(stopd(sb)->hidden_mnt);#endif	kfree(stopd(sb));	stopd(sb) = NULL;    }    fist_dprint(6, "wrapfs: released super\n");    print_exit_location();}#ifdef NOT_NEEDED/* * This is called in do_umount before put_super. * The superblock lock is not held yet. * We probably do not need to define this or call write_super * on the hidden_sb, because sync_supers() will get to hidden_sb * sooner or later.  But it is also called from file_fsync()... */STATIC voidwrapfs_write_super(super_block_t *sb){    return;}#endif /* NOT_NEEDED */#ifndef FIST_MNTSTYLE_ATTACHSTATIC intwrapfs_statfs(super_block_t *sb, struct statfs *buf){    int err = 0;    super_block_t *hidden_sb;    print_entry_location();    hidden_sb = stohs(sb);    err = vfs_statfs(hidden_sb, buf);    print_exit_status(err);    return err;}#endif /* not FIST_MNTSTYLE_ATTACH *//* * XXX: not implemented.  This is not allowed yet. * Should we call this on the hidden_sb?  Probably not. */STATIC intwrapfs_remount_fs(super_block_t *sb, int *flags, char *data){    return -ENOSYS;}/* * Called by iput() when the inode reference count reached zero * and the inode is not hashed anywhere.  Used to clear anything * that needs to be, before the inode is completely destroyed and put * on the inode free list. */STATIC voidwrapfs_clear_inode(inode_t *inode){#ifdef FIST_FILTER_SCA    int i;    struct scafs_header *hdr;#endif /* FIST_FILTER_SCA */    print_entry_location();    fist_checkinode(inode, "wrapfs_clear_inode IN");    /*     * Decrement a reference to a hidden_inode, which was incremented     * by our read_inode when it was created initially.     */    iput(itohi(inode));    // XXX: why this assertion fails?    // because it doesn't like us    // ASSERT((inode->i_state & I_DIRTY) == 0);#ifdef FIST_FILTER_SCA    if (itopd(inode)->idx_file != NULL)	wrapfs_idx_release(inode);    hdr = &itopd(inode)->hdr;    if (hdr->num_alloc > 0) { /* then offsets were allocated */	fist_print_scafs_header("CLEAR_INODE", hdr);	for (i = 0; i < hdr->num_pageslots; i++)	    free_page((unsigned long) hdr->offsets[i]);	kfree(hdr->offsets);    }#endif /* FIST_FILTER_SCA */    kfree(itopd(inode));    itopd(inode) = NULL;    print_exit_location();}/* * Called in do_umount() if the MNT_FORCE flag was used and this * function is defined.  See comment in linux/fs/super.c:do_umount(). * Used only in nfs, to kill any pending RPC tasks, so that subsequent * code can actually succeed and won't leave tasks that need handling. * * PS. I wonder if this is somehow useful to undo damage that was * left in the kernel after a user level file server (such as amd) * dies. */STATIC voidwrapfs_umount_begin(super_block_t *sb){    super_block_t *hidden_sb;    print_entry_location();#ifndef FIST_MNTSTYLE_ATTACH    hidden_sb = stohs(sb);    if (hidden_sb->s_op->umount_begin)	hidden_sb->s_op->umount_begin(hidden_sb);#endif    print_exit_location();}struct super_operations wrapfs_sops ={    read_inode:		wrapfs_read_inode,#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)    write_inode:	wrapfs_write_inode,#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */    put_inode:		wrapfs_put_inode,#ifdef FIST_DEBUG    delete_inode:	wrapfs_delete_inode,#endif /* FIST_DEBUG */    put_super:		wrapfs_put_super,    statfs:		wrapfs_statfs,    remount_fs:		wrapfs_remount_fs,    clear_inode:	wrapfs_clear_inode,    umount_begin:	wrapfs_umount_begin,};/* * Local variables: * c-basic-offset: 4 * End: */

⌨️ 快捷键说明

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