📄 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.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 + -