📄 file.c
字号:
STATIC intwrapfs_ioctl(inode_t *inode, file_t *file, unsigned int cmd, unsigned long arg){ int err = 0; /* don't fail by default */ 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; fist_dprint(6, "IOCTL SET: got arg %d\n", val); if (val < 0 || val > 20) { err = -EINVAL; break; } fist_set_debug_value(val); break;#endif /* FIST_DEBUG */#ifdef FIST_FILTER_SCA case FIST_IOCTL_GET_FAST_TAIL_VALUE: val = (stopd(inode->i_sb)->sca_flags != 0); printk("IOCTL GET: send arg %d\n", val); err = put_user(val, (int *) arg); break;# ifdef FIST_FAST_TAILS case FIST_IOCTL_SET_FAST_TAIL_VALUE: err = get_user(val, (int *) arg); if (err) break; fist_dprint(6, "IOCTL SET: got arg %d\n", val); if (val == 1) { stopd(inode->i_sb)->sca_flags |= SCA_FLAG_FASTTAIL; } else if (val == 0) { stopd(inode->i_sb)->sca_flags &= ~SCA_FLAG_FASTTAIL; } else { err = -EINVAL; } break;# endif /* FIST_FAST_TAILS */#endif /* FIST_FILTER_SCA */ /* add non-debugging fist ioctl's here */FIST_IOCTL_ECLS default: hidden_file = ftohf(file); /* pass operation to hidden filesystem, and return status */ if (hidden_file->f_op && hidden_file->f_op->ioctl) err = hidden_file->f_op->ioctl(itohi(inode), hidden_file, cmd, arg); else err = -ENOTTY; /* this is an unknown ioctl */ } /* end of outer switch statement */ print_exit_status(err); return err;}#ifndef FIST_FILTER_DATA/* FIST-LITE special version of mmap */STATIC intwrapfs_mmap(file_t *file, vm_area_t *vma){ int err = 0; file_t *hidden_file; inode_t *inode; inode_t *hidden_inode; print_entry_location(); hidden_file = ftohf(file); /* CPW: Moved to after print_entry_location */ ASSERT(hidden_file != NULL); ASSERT(hidden_file->f_op != NULL); ASSERT(hidden_file->f_op->mmap != NULL); vma->vm_file = hidden_file; err = hidden_file->f_op->mmap(hidden_file, vma); get_file(hidden_file); /* make sure it doesn't get freed on us */ fput(file); /* no need to keep extra ref on ours */ out: print_exit_status(err); return err;}#endif /* not FIST_FILTER_DATA */STATIC intwrapfs_open(inode_t *inode, file_t *file){ int err = 0; int hidden_mode, hidden_flags; file_t *hidden_file; dentry_t *hidden_dentry = NULL; print_entry_location(); ftopd(file) = kmalloc(sizeof(struct wrapfs_file_info *), GFP_KERNEL); if (!ftopd(file)) { err = -ENOMEM; goto out; } hidden_dentry = wrapfs_hidden_dentry(file->f_dentry); /* CPW: Moved after print_entry */ fist_print_dentry("wrapfs_open IN hidden_dentry", hidden_dentry); dget(hidden_dentry); hidden_flags = file->f_flags;#ifdef FIST_FILTER_DATA if ((hidden_flags & O_ACCMODE) == O_WRONLY) hidden_flags = (hidden_flags & O_ACCMODE) | O_RDWR; if (file->f_flags & O_APPEND) { fist_dprint(5, "file is opened in append-only mode\n"); hidden_flags &= ~O_APPEND; /* turn off O_APPEND flag */ }#endif /* not FIST_FILTER_DATA */ /* * dentry_open will decrement mnt refcnt if err. * otherwise fput() will do an mntput() for us upon file close. */ mntget(stopd(inode->i_sb)->hidden_mnt); hidden_file = dentry_open(hidden_dentry, stopd(inode->i_sb)->hidden_mnt, hidden_flags); if (IS_ERR(hidden_file)) { err = PTR_ERR(hidden_file); goto out; } ftohf(file) = hidden_file; /* link two files */ out: if (err < 0 && ftopd(file)) { kfree(ftopd(file)); } fist_print_dentry("wrapfs_open OUT hidden_dentry", hidden_dentry); print_exit_status(err); return err;}STATIC intwrapfs_flush(file_t *file){ int err = 0; /* assume ok (see open.c:close_fp) */ file_t *hidden_file; print_entry_location(); hidden_file = ftohf(file); /* CPW: Moved after print_entry_location */ if (!hidden_file->f_op || !hidden_file->f_op->flush) goto out; err = hidden_file->f_op->flush(hidden_file);out: print_exit_status(err); return err;}STATIC intwrapfs_release(inode_t *inode, file_t *file){ int err = 0; file_t *hidden_file; dentry_t *hidden_dentry; print_entry_location(); hidden_file = ftohf(file); kfree(ftopd(file)); ASSERT(hidden_file != NULL); fist_print_dentry("wrapfs_release IN hidden_dentry", hidden_file->f_dentry); fist_checkinode(inode, "wrapfs_release"); fist_dprint(6, "wrapfs_release IN, file->f_count=%d\n", file->f_count); /* * will decrement file refcount, and if 0, destroy the file, * which will call the lower file system's file release function. */ hidden_dentry = hidden_file->f_dentry; fput(hidden_file); fist_dprint(6, "wrapfs_release done\n"); fist_checkinode(inode, "post wrapfs_release"); fist_print_dentry("wrapfs_release OUT hidden_dentry", hidden_dentry); print_exit_status(err); return err;}STATIC intwrapfs_fsync(file_t *file, dentry_t *dentry, int datasync){ int err = -EINVAL; file_t *hidden_file; dentry_t *hidden_dentry; print_entry_location(); hidden_file = ftohf(file); /* CPW: Moved to after print_entry_location */ hidden_dentry = wrapfs_hidden_dentry(dentry); if (hidden_file->f_op && hidden_file->f_op->fsync) { down(&hidden_dentry->d_inode->i_sem); err = hidden_file->f_op->fsync(hidden_file, hidden_dentry, datasync); up(&hidden_dentry->d_inode->i_sem); } print_exit_status(err); return err;}STATIC intwrapfs_fasync(int fd, file_t *file, int flag){ int err = 0; 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->fasync) err = hidden_file->f_op->fasync(fd, hidden_file, flag); print_exit_status(err); return err;}STATIC intwrapfs_lock(file_t *file, int cmd, struct file_lock *fl){ int err = 0; file_t *hidden_file; print_entry_location(); hidden_file = ftohf(file); /* CPW: Moved to after print_entry_location */ if (hidden_file->f_op->lock) { err = hidden_file->f_op->lock(hidden_file, F_GETLK, fl); } else { posix_test_lock(hidden_file, fl); } print_exit_status(err); return err;}struct file_operations wrapfs_dir_fops ={ llseek: wrapfs_llseek, read: wrapfs_read, write: wrapfs_write, readdir: wrapfs_readdir, poll: wrapfs_poll, ioctl: wrapfs_ioctl,#ifdef FIST_FILTER_DATA mmap: generic_file_mmap,#else /* not FIST_FILTER_DATA */ mmap: wrapfs_mmap,#endif /* not FIST_FILTER_DATA */ open: wrapfs_open, flush: wrapfs_flush, release: wrapfs_release, fsync: wrapfs_fsync, fasync: wrapfs_fasync, lock: wrapfs_lock, /* not needed: readv */ /* not needed: writev */ /* not implemented: sendpage */ /* not implemented: get_unmapped_area */};struct file_operations wrapfs_main_fops ={ llseek: wrapfs_llseek,#ifdef FIST_FILTER_DATA read: wrapfs_read_update_atime, write: generic_file_write,#else /* not FIST_FILTER_DATA */ read: wrapfs_read, write: wrapfs_write,#endif /* not FIST_FILTER_DATA */ readdir: wrapfs_readdir, poll: wrapfs_poll, ioctl: wrapfs_ioctl,#ifdef FIST_FILTER_DATA mmap: generic_file_mmap,#else /* not FIST_FILTER_DATA */ mmap: wrapfs_mmap,#endif /* not FIST_FILTER_DATA */ open: wrapfs_open, flush: wrapfs_flush, release: wrapfs_release, fsync: wrapfs_fsync, fasync: wrapfs_fasync, lock: wrapfs_lock, /* not needed: readv */ /* not needed: writev */ /* not implemented: sendpage */ /* not implemented: get_unmapped_area */};/* * Local variables: * c-basic-offset: 4 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -