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

📄 inode.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
				void *data){	struct page *page = __read_cache_page(inode, offset, filler, data);	int err;	if (IS_ERR(page) || PageUptodate(page))		goto out;	wait_on_page(page);	if (PageUptodate(page))		goto out;	set_bit(PG_locked, &page->flags);	err = filler(data, page);	if (err < 0) {		page_cache_release(page);		page = ERR_PTR(err);	} out:	return page;}#endif /* kernels older than 2.2.18 */STATIC intwrapfs_readpage(file_t *file, page_t *page){    int err = 0;    inode_t *inode = file->f_dentry->d_inode;    inode_t *hidden_inode = itohi(inode);    file_t *hidden_file = ftohf(file);    page_t *hidden_page;    unsigned long page_data, hidden_page_data;    print_entry_location();    /*     * readpage is called from generic_file_read and the fault handler.     * If your file system uses generic_file_read for the read op, it     * must implement readpage.     */    ASSERT(hidden_inode->i_op != NULL);    atomic_inc(&page->count);    set_bit(PG_locked, &page->flags);    set_bit(PG_free_after, &page->flags);    fist_print_page_flags("READPAGE flags (entry)", page);    fist_dprint(6, "READPAGE: f_pos:0x%x inode:0x%x i_size:0x%x hidden_inode:0x%x page->inode:0x%x page->offset:%lu page->count:%d\n",		(int) file->f_pos, (int) inode, inode->i_size, (int) hidden_inode,		(int) page->inode, page->offset, atomic_read(&page->count));    hidden_page = read_cache_page(hidden_inode, page->offset,				  (filler_t *)hidden_inode->i_op->readpage,				  hidden_file);    if (IS_ERR(hidden_page)) {	err = PTR_ERR(hidden_page);	/* XXX: we might have to do some unlocking on this error path */	goto out;    }    /*     * decode hidden_page data onto page     */    page_data = page_address(page);    hidden_page_data = page_address(hidden_page);    wrapfs_decode_block((char *) hidden_page_data, (char *) page_data, PAGE_SIZE, inode, inode->i_sb);    /* release our reference to the hidden page */    page_cache_release(hidden_page);    /*     * adjust flags and wake up processes waiting on the page     */    set_bit(PG_uptodate, &page->flags);out:    /*     * we have to unlock our page, b/c we locked it above     */    clear_bit(PG_locked, &page->flags);    wake_up(&page->wait);    after_unlock_page(page);    fist_dprint(6, "READPAGE (exit/page): f_pos:0x%x inode:0x%x i_size:0x%x hidden_inode:0x%x page->inode:0x%x page->offset:%lu page->count:%d\n",		(int) file->f_pos, (int) inode, inode->i_size, (int) hidden_inode,		(int) page->inode, page->offset, atomic_read(&page->count));    fist_dprint(6, "READPAGE (exit/hidden_page): f_pos:0x%x inode:0x%x i_size:0x%x hidden_inode:0x%x page->inode:0x%x page->offset:%lu page->count:%d\n",		(int) file->f_pos, (int) inode, inode->i_size, (int) hidden_inode,		(int) hidden_page->inode, hidden_page->offset, atomic_read(&hidden_page->count));    fist_print_page_flags("READPAGE flags (exit)", page);    fist_print_page_flags("READPAGE hidden_flags (exit)", hidden_page);    print_exit_status(err);    return err;}#ifdef NOT_NEEDED#error ARE YOU SURE YOU WANT TO DEFINE WRITEPAGE???/* XXX: the VFS never calls writepage */STATIC intwrapfs_writepage(file_t *file, page_t *page){    int err = -EIO;    file_t *hidden_file = ftohf(file);    inode_t *hidden_inode = hidden_file->f_dentry->d_inode;    print_entry_location();    if (hidden_inode->i_op && hidden_inode->i_op->writepage) {	fist_dprint(2, "non-generic writepage\n");	err = hidden_inode->i_op->writepage(hidden_file, page);	if (err >= 0)	    fist_copy_attr_times(file->f_dentry->d_inode, hidden_inode);    }    print_exit_status(err);    return err;}#endif /* NOT_NEEDED */STATIC intwrapfs_bmap(inode_t *inode, int block){    int err = -EINVAL;    inode_t *hidden_inode = itohi(inode);    print_entry_location();    if (hidden_inode->i_op && hidden_inode->i_op->bmap)	err = hidden_inode->i_op->bmap(hidden_inode, block);    print_exit_status(err);    return err;}STATIC voidwrapfs_truncate(inode_t *inode){    inode_t *hidden_inode = itohi(inode);    print_entry_location();    fist_checkinode(inode, "wrapfs_truncate");    if (!hidden_inode->i_op || !hidden_inode->i_op->truncate)	goto out;    down(&hidden_inode->i_sem);    hidden_inode->i_op->truncate(hidden_inode);    up(&hidden_inode->i_sem);    fist_copy_attr_timesizes(inode, hidden_inode); out:    print_exit_location();}STATIC intwrapfs_permission(inode_t *inode, int mask){    inode_t *hidden_inode = itohi(inode);    int mode = inode->i_mode;    int err;    print_entry_location();    if ((mask & S_IWOTH) && IS_RDONLY(inode) &&	(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) {	err = -EROFS; /* Nobody gets write access to a read-only fs */	goto out;    }    err = permission(hidden_inode, mask); out:    print_exit_status(err);    return err;}STATIC intwrapfs_smap(inode_t *inode, int block){    int err = -EINVAL;    inode_t *hidden_inode = itohi(inode);    print_entry_location();    if (hidden_inode->i_op && hidden_inode->i_op->smap)	err = hidden_inode->i_op->smap(hidden_inode, block);    else	err = bmap(hidden_inode, block);    print_exit_status(err);    return err;}#ifdef NOT_NEEDED/* * We don't need this because we will implement file_write, which will * call the hidden file_write, and the latter, if set to generic_file_write, * will call hidden's update_page (if implemented by lower file system). */STATIC intwrapfs_updatepage(file_t *file, page_t *page, const char *buf,		  unsigned long offset, unsigned int count, int sync){    int err = -EIO;    file_t *hidden_file = ftohf(file);    char *hidden_buf, *page_data;    mm_segment_t old_fs;    loff_t hidden_file_offset = file->f_pos;    print_entry_location();    fist_dprint(6, "UPDATEPAGE1: buf[0]=%d, offset=0x%x, count=%d, sync=%d\n",		(int) buf[0], (int) offset, count, sync);    if (!hidden_file->f_op || !hidden_file->f_op->write)	goto out;    fist_print_file("Updatepage BEFORE file", file);    fist_print_file("Updatepage BEFORE hidden_file", hidden_file);    hidden_buf = kmalloc(count, GFP_KERNEL);    if (!hidden_buf) {	err = -ENOMEM;	goto out;    }    wrapfs_encode_block(buf, hidden_buf, count, page->inode, page->inode->i_sb);    old_fs = get_fs();    set_fs(KERNEL_DS);    hidden_file->f_pos = file->f_pos;    err = hidden_file->f_op->write(hidden_file,				   hidden_buf,				   count,				   &hidden_file_offset);    set_fs(old_fs);    fist_print_file("Updatepage AFTER file", file);    fist_print_file("Updatepage AFTER hidden_file", hidden_file);    if (err >= 0) {	//	file->f_pos = hidden_file_offset;	page_data = (char *) page_address(page);	memcpy(page_data, buf, count);	//	file->f_pos = hidden_file->f_pos;    }    kfree_s(hidden_buf, count); out:    print_exit_status(err);    return err;}#endif /* NOT_NEEDED */STATIC intwrapfs_inode_revalidate(dentry_t *dentry){    int err = 0;    dentry_t *hidden_dentry = wrapfs_hidden_dentry(dentry);    inode_t *hidden_inode = hidden_dentry->d_inode;    print_entry_location();    //    fist_print_dentry("inode_revalidate IN", dentry);    if (hidden_inode->i_op && hidden_inode->i_op->revalidate) {	err = hidden_inode->i_op->revalidate(hidden_dentry);	if (!err)	    fist_copy_attr_all(dentry->d_inode, hidden_inode);    }    //    fist_print_dentry("inode_revalidate OUT", dentry);    print_exit_status(err);    return err;}#if 0#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,18)/* * XXX: we may not need this function if not FIST_FILTER_DATA. * XXX: for FIST_FILTER_SCA, get all lower pages and sync them each. */STATIC intwrapfs_sync_page(page_t *page){    int err = 0;    inode_t *inode = (inode_t *) page->inode;    inode_t *hidden_inode = itohi(inode);    page_t *hidden_page;    print_entry_location();    /*     * find lower page. returns a locked page, and may also return     * a newly allocated page.     * XXX: if page is allocated, it may not have any data in it.  What do     * we do then? (What are the exact semantics of ->sync_page?     */    hidden_page = get_cached_page(hidden_inode, page->offset, 1);    if (!hidden_page)	goto out;    err = sync_page(hidden_page);    UnlockPage(hidden_page);	/* b/c get_cached_page locked it */    page_cache_release(hidden_page); /* b/c get_cached_page increased refcnt */out:    print_exit_location();    return err;}STATIC intwrapfs_prepare_write(file_t *file, page_t *page, unsigned from, unsigned to){#error need to be ported correctly from 2.4. For now, wrapfs over nfs in 2.2#error will not work.}#endif /* kernel 2.2.18 or newer */#endifstruct inode_operations wrapfs_main_iops ={    default_file_ops:	&wrapfs_main_fops,    create:		wrapfs_create,    lookup:		wrapfs_lookup,    link:		wrapfs_link,    unlink:		wrapfs_unlink,    symlink:		wrapfs_symlink,    mkdir:		wrapfs_mkdir,    rmdir:		wrapfs_rmdir,    mknod:		wrapfs_mknod,    rename:		wrapfs_rename,    readlink:		wrapfs_readlink,    follow_link:	wrapfs_follow_link,    readpage:		wrapfs_readpage,#ifdef NOT_NEEDED    write_page:		wrapfs_writepage,#endif /* NOT_NEEDED */    bmap:		wrapfs_bmap,    truncate:		wrapfs_truncate,    permission:		wrapfs_permission,    smap:		wrapfs_smap,#ifdef NOT_NEEDED    updatepage:		wrapfs_updatepage,#endif /* NOT_NEEDED */    revalidate:		wrapfs_inode_revalidate,#if 0#error need proper porting#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,18)    prepare_write:	wrapfs_prepare_write,    sync_page:		wrapfs_sync_page,#endif /* kernel 2.2.18 or newer */#endif};struct inode_operations wrapfs_dir_iops ={    default_file_ops:	&wrapfs_dir_fops,    create:		wrapfs_create,    lookup:		wrapfs_lookup,    link:		wrapfs_link,    unlink:		wrapfs_unlink,    symlink:		wrapfs_symlink,    mkdir:		wrapfs_mkdir,    rmdir:		wrapfs_rmdir,    mknod:		wrapfs_mknod,    rename:		wrapfs_rename,    readlink:		wrapfs_readlink,    follow_link:	wrapfs_follow_link,    readpage:		wrapfs_readpage,#ifdef NOT_NEEDED    write_page:		wrapfs_writepage,#endif /* NOT_NEEDED */    bmap:		wrapfs_bmap,    truncate:		wrapfs_truncate,    permission:		wrapfs_permission,    smap:		wrapfs_smap,#ifdef NOT_NEEDED    updatepage:		wrapfs_updatepage,#endif /* NOT_NEEDED */    revalidate:		wrapfs_inode_revalidate,#if 0#error need proper porting#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,18)    prepare_write:	wrapfs_prepare_write,    sync_page:		wrapfs_sync_page,#endif /* kernel 2.2.18 or newer */#endif};/* * Local variables: * c-basic-offset: 4 * End: */

⌨️ 快捷键说明

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