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

📄 file.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: file.c,v 1.20 2003/01/20 23:01:20 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"/******************* * File Operations * *******************/STATIC loff_twrapfs_llseek(file_t *file, loff_t offset, int origin){    loff_t err;    file_t *hidden_file;    print_entry_location();    hidden_file = ftohf(file); /* CPW: Moved to after print_entry_location */    fist_dprint(6, "wrapfs_llseek: file=%x, offset=0x%x, origin=%d\n",		(int) file, (int) offset, origin);#ifndef FIST_FILTER_SCA    /* always set hidden position to this one */    hidden_file->f_pos = file->f_pos;    if (file->f_reada) { /* update readahead information if needed */	hidden_file->f_reada = file->f_reada;	hidden_file->f_ramax = file->f_ramax;	hidden_file->f_raend = file->f_raend;	hidden_file->f_ralen = file->f_ralen;	hidden_file->f_rawin = file->f_rawin;    }    ASSERT(hidden_file->f_reada == file->f_reada);    ASSERT(hidden_file->f_ramax == file->f_ramax);    ASSERT(hidden_file->f_raend == file->f_raend);    ASSERT(hidden_file->f_ralen == file->f_ralen);    ASSERT(hidden_file->f_rawin == file->f_rawin);    if (hidden_file->f_op && hidden_file->f_op->llseek)	err = hidden_file->f_op->llseek(hidden_file, offset, origin);    else	err = generic_file_llseek(hidden_file, offset, origin);    if (err < 0)	goto out;    if (err != file->f_pos) {	file->f_pos = err;	// ION maybe this?	// 	file->f_pos = hidden_file->f_pos;	file->f_reada = 0;	file->f_version = ++event;    }#else /* FIST_FILTER_SCA */    fist_print_file("wrapfs_llseek IN Virtual file", file);    fist_print_inode("wrapfs_llseek IN Virtual inode", file->f_dentry->d_inode);	/*	 * There is no need to deal with any read ahead information, since	 * the SCA is not matched with the real read aheads.  Adjust to the	 * new position	 */	switch (origin) {		case SEEK_END:			offset += file->f_dentry->d_inode->i_size;			break;		case SEEK_CUR:			offset += file->f_pos;	}	err = -EINVAL;	/* Check file boundaries */	if (offset >= 0 && offset <= file->f_dentry->d_inode->i_size) {		if (offset != file->f_pos) {			file->f_pos = offset;			file->f_reada = 0;			file->f_version = ++event;		}		err = offset;	}    fist_print_inode("wrapfs_llseek OUT Virtual inode", file->f_dentry->d_inode);    fist_print_file("wrapfs_llseek OUT Virtual file", file);#endif /* FIST_FILTER_SCA */out:    print_exit_status(err);    return err;}#ifdef FIST_FILTER_DATA/* * generic_file_read updates the atime of upper layer inode. * But, it doesn't give us a chance to update the atime of * the lower layer inode. This function is a wrapper to * generic_file_read. it Updates the atime of the lower level * inode if generic_file_read returns without any errors * This is to be used only for file reads and only if * FIST_FILTER_DATA is defined. The function to be * used for directory reads is wrapfs_read */STATIC ssize_twrapfs_read_update_atime(file_t *file, char* buf, size_t count, loff_t *ppos){    int err = 0;    print_entry_location();    err = generic_file_read(file, buf, count, ppos);    if (err >= 0)	UPDATE_ATIME(itohi(file->f_dentry->d_inode));    print_exit_status(err);    return err;}#endif /* FIST_FILTER_DATA */STATIC ssize_twrapfs_read(file_t *file, char *buf, size_t count, loff_t *ppos){    int err = -EINVAL;    file_t *hidden_file;    loff_t pos = *ppos;    print_entry_location();    hidden_file = ftohf(file); /* CPW: Moved to after print_entry_location */    if (!hidden_file->f_op || !hidden_file->f_op->read)	goto out;    err = hidden_file->f_op->read(hidden_file, buf, count, &pos);    if (err >= 0) {	/* atime should also be updated for reads of size zero or more */	fist_copy_attr_atime(file->f_dentry->d_inode,			     hidden_file->f_dentry->d_inode);    }    // MAJOR HACK    /*     * because pread() does not have any way to tell us that it is     * our caller, then we don't know for sure if we have to update     * the file positions.  This hack relies on read() having passed us     * the "real" pointer of its struct file's f_pos field.     */    if (ppos == &file->f_pos)	hidden_file->f_pos = *ppos = pos;    if (hidden_file->f_reada) { /* update readahead information if needed */	file->f_reada = hidden_file->f_reada;	file->f_ramax = hidden_file->f_ramax;	file->f_raend = hidden_file->f_raend;	file->f_ralen = hidden_file->f_ralen;	file->f_rawin = hidden_file->f_rawin;    }out:    print_exit_status(err);    return err;}/* this wrapfs_write() does not modify data pages! */STATIC ssize_twrapfs_write(file_t *file, const char *buf, size_t count, loff_t *ppos){    int err = -EINVAL;    file_t *hidden_file;    inode_t *inode;    inode_t *hidden_inode;    loff_t pos = *ppos;    print_entry_location();    hidden_file = ftohf(file); /* CPW: Moved to after print_entry_location */    inode = file->f_dentry->d_inode;    hidden_inode = itohi(inode);    if (!hidden_file->f_op || !hidden_file->f_op->write)	goto out;    /* adjust for append -- seek to the end of the file */    if (file->f_flags & O_APPEND)	pos = inode->i_size;    err = hidden_file->f_op->write(hidden_file, buf, count, &pos);    /*     * copy ctime and mtime from lower layer attributes     * atime is unchanged for both layers     */    if (err >= 0)	fist_copy_attr_times(inode, hidden_inode);    /*     * XXX: MAJOR HACK     *     * because pwrite() does not have any way to tell us that it is     * our caller, then we don't know for sure if we have to update     * the file positions.  This hack relies on write() having passed us     * the "real" pointer of its struct file's f_pos field.     */    if (ppos == &file->f_pos)	hidden_file->f_pos = *ppos = pos;    /* update this inode's size */    if (pos > inode->i_size)	inode->i_size = pos;out:    print_exit_status(err);    return err;}#if defined(FIST_FILTER_NAME) || defined(FIST_FILTER_SCA)struct wrapfs_getdents_callback {    void *dirent;    dentry_t *dentry;    filldir_t filldir;};/* copied from generic filldir in fs/readir.c */STATIC int# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)wrapfs_filldir(void *dirent, const char *name, int namlen, loff_t offset, ino_t ino, unsigned int d_type)# else /* kernel older than 2.4.9 */wrapfs_filldir(void *dirent, const char *name, int namlen, off_t offset, ino_t ino, unsigned int d_type)# endif /* kernel older than 2.4.9 */{    struct wrapfs_getdents_callback *buf = (struct wrapfs_getdents_callback *) dirent;    int err;# ifdef FIST_FILTER_NAME    char *decoded_name;    int decoded_length;# endif /* FIST_FILTER_NAME */# ifdef FIST_FILTER_SCA    /* skip .idx files */    if (namlen > INDEX_EXTENSION_LEN-1 &&	strncmp(&name[namlen-INDEX_EXTENSION_LEN+1],		INDEX_EXTENSION,		INDEX_EXTENSION_LEN-1) == 0) {	//don't do this, it's not zero-terminated!!!	//fist_dprint(7, "filldir: skip \"%s\"\n", name);	return 0;    }# endif /* FIST_FILTER_SCA */# ifdef FIST_FILTER_NAME    decoded_length = wrapfs_decode_filename(name, namlen, &decoded_name, SKIP_DOTS,					    buf->dentry->d_inode, buf->dentry->d_sb);    if (decoded_length < 0)	return 0;			/* no error, just skip the entry */    FIST_OP_READDIR_CALL;    err = buf->filldir(buf->dirent, decoded_name, decoded_length, offset, ino, d_type);    kfree(decoded_name);# else /* not FIST_FILTER_NAME */    err = buf->filldir(buf->dirent, name, namlen, offset, ino, d_type);# endif /* not FIST_FILTER_NAME */    return err;}#endif /* FIST_FILTER_NAME || FIST_FILTER_SCA */STATIC intwrapfs_readdir(file_t *file, void *dirent, filldir_t filldir){    int err = -ENOTDIR;    file_t *hidden_file;    inode_t *inode;#if defined(FIST_FILTER_NAME) || defined(FIST_FILTER_SCA)    struct wrapfs_getdents_callback buf;#endif /* FIST_FILTER_NAME || FIST_FILTER_SCA */    print_entry_location();    hidden_file = ftohf(file); /* CPW: Moved to after print_entry_location */    inode = file->f_dentry->d_inode;    fist_checkinode(inode, "wrapfs_readdir");#if defined(FIST_FILTER_NAME) || defined(FIST_FILTER_SCA)    /* prepare for callback */    buf.dirent = dirent;    buf.dentry = file->f_dentry;    buf.filldir = filldir;    err = vfs_readdir(hidden_file, wrapfs_filldir, (void *) &buf);#else /* not FIST_FILTER_NAME */    err = vfs_readdir(hidden_file, filldir, dirent);#endif /* not FIST_FILTER_NAME */    file->f_pos = hidden_file->f_pos;    if (err > 0)	fist_copy_attr_atime(inode, hidden_file->f_dentry->d_inode);    fist_checkinode(inode, "post wrapfs_readdir");    print_exit_status(err);    return err;}STATIC unsigned intwrapfs_poll(file_t *file, poll_table *wait){    unsigned int mask = DEFAULT_POLLMASK;    file_t *hidden_file;    print_entry_location();    hidden_file = ftohf(file); /* CPW: Moved to after print_entry_location */    if (!hidden_file->f_op || !hidden_file->f_op->poll)	goto out;    mask = hidden_file->f_op->poll(hidden_file, wait);out:    print_exit_status(mask);    return mask;}

⌨️ 快捷键说明

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