📄 file.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: file.c,v 1.29 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"/******************* * File Operations * *******************/STATIC loff_twrapfs_llseek(file_t *file, loff_t offset, int origin){ loff_t err; file_t *hidden_file = ftohf(file); print_entry_location(); fist_dprint(6, "wrapfs_llseek: file=%x, offset=0x%x, origin=%d\n", (int) file, (int) offset, origin); /* 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 = default_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; }out: print_exit_status(err); return err;}#ifndef FIST_FILTER_DATA#error do not use wrapfs_readSTATIC ssize_twrapfs_read(file_t *file, char *buf, size_t count, loff_t *ppos){ int err = -EINVAL; file_t *hidden_file = ftohf(file); loff_t pos = *ppos; 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) { 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;}#endif /* not FIST_FILTER_DATA */#ifndef FIST_FILTER_DATA#error do not use wrapfs_write/* this wrapfs_write() does not modifying 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 = ftohf(file); inode_t *inode = file->f_dentry->d_inode; inode_t *hidden_inode = itohi(inode); loff_t pos = *ppos; print_entry_location(); if (!hidden_file->f_op || !hidden_file->f_op->read) 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); if (err > 0) fist_copy_attr_atime(inode, hidden_inode); /* * XXX: 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; /* update this inode's size */ if (pos > inode->i_size) inode->i_size = pos;out: print_exit_status(err); return err;}#endif /* not FIST_FILTER_DATA */#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 intwrapfs_filldir(void *dirent, const char *name, int namlen, off_t offset, ino_t ino){ 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); kfree_s(decoded_name, decoded_length);#else /* ! FIST_FILTER_NAME */ err = buf->filldir(buf->dirent,name,namlen,offset,ino);#endif /* 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 = ftohf(file); inode_t *inode = file->f_dentry->d_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(); 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){ int err = 0; file_t *hidden_file = ftohf(file); print_entry_location(); if (!hidden_file->f_op || !hidden_file->f_op->poll) goto out; err = hidden_file->f_op->poll(hidden_file, wait);out: print_exit_status(err); return err;}STATIC intwrapfs_ioctl(inode_t *inode, file_t *file, unsigned int cmd, unsigned long arg){ int err = 0; file_t *hidden_file; vfs_t *this_vfs; vnode_t *this_vnode; int val;# ifdef FIST_COUNT_WRITES extern unsigned long count_writes, count_writes_middle;# endif /* FIST_COUNT_WRITES */ print_entry_location(); this_vfs = inode->i_sb; this_vnode = inode; /* check if asked for local commands */ switch (cmd) {#ifdef FIST_DEBUG case FIST_IOCTL_GET_DEBUG_VALUE: val = fist_get_debug_value(); printk("IOCTL GET: send arg %d\n", val); err = put_user(val, (int *) arg);# ifdef FIST_COUNT_WRITES printk("COUNT_WRITES:%lu:%lu\n", count_writes, count_writes_middle);# endif /* FIST_COUNT_WRITES */ break; case FIST_IOCTL_SET_DEBUG_VALUE: err = get_user(val, (int *) arg); if (err) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -