📄 file.c
字号:
STATIC unsigned intwrapfs_poll(file_t *file, poll_table *wait){ unsigned int mask = DEFAULT_POLLMASK; file_t *hidden_file = ftohf(file); 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;}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;#ifdef FIST_DEBUG int val;#endif /* FIST_DEBUG */ 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: got arg %d\n", val); err = put_user(val, (int *) arg); 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 */ /* 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; /* for unknown ioctls */ } /* end of switch statement */ print_exit_status(err); return err;}#ifdef NOT_NEEDEDSTATIC intwrapfs_mmap(file_t *file, vm_area_t *vma){ int err = 0; file_t *hidden_file = ftohf(file); inode_t *inode = file->f_dentry->d_inode; inode_t *hidden_inode = itohi(inode); vm_area_t *hidden_vma = (vm_area_t *) 0xdeadc0de; print_entry_location(); fist_dprint(6, "MMAP1: inode 0x%x, hidden_inode 0x%x, inode->i_count %d, hidden_inode->i_count %d\n", (int) inode, (int) hidden_inode, (int) inode->i_count, (int) hidden_inode->i_count); if (!hidden_file->f_op || !hidden_file->f_op->mmap) { err = -ENODEV; goto out; } /* * Most of this code comes straight from generic_file_mmap * in mm/filemap.c. */ if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) { vma->vm_ops = &wrapfs_shared_vmops; /* share_page() can only guarantee proper page sharing if * the offsets * are all page aligned. */ if (vma->vm_offset & (PAGE_SIZE - 1)) { err = -EINVAL; goto out; } } else { vma->vm_ops = &wrapfs_private_vmops; if (vma->vm_offset & (hidden_inode->i_sb->s_blocksize - 1)) { err = -EINVAL; goto out; } } if (!inode->i_sb || !S_ISREG(inode->i_mode)) { err = -EACCES; goto out; } if (!hidden_inode->i_op || !hidden_inode->i_op->readpage) { err = -ENOEXEC; goto out; } UPDATE_ATIME(inode);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,3) vma->vm_file = file; file->f_count++;#endif /* * Now we do the hidden stuff, but only for shared maps. */ if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) { hidden_vma = kmalloc(sizeof(vm_area_t), GFP_KERNEL); if (!hidden_vma) { printk("MMAP: Out of memory\n"); err = -ENOMEM; goto out; } // ION, is this right? memcpy(hidden_vma, vma, sizeof(vm_area_t)); vmatohvma(vma) = hidden_vma; err = hidden_file->f_op->mmap(hidden_file, hidden_vma);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,3) hidden_vma->vm_file = hidden_file; hidden_file->f_count++;#endif } /* * XXX: do we need to insert_vm_struct and merge_segments as is * done in do_mmap()? */ out: fist_dprint(6, "MMAP2: inode 0x%x, hidden_inode 0x%x, inode->i_count %d, hidden_inode->i_count %d\n", (int) inode, (int) hidden_inode, (int) inode->i_count, (int) hidden_inode->i_count);#if 0 if (!err) { inode->i_mmap = vma; hidden_inode->i_mmap = hidden_vma; }#endif print_exit_status(err); return err;}#endif /* NOT_NEEDED */STATIC intwrapfs_open(inode_t *inode, file_t *file){ int err = -ENFILE; file_t *hidden_file; inode_t *hidden_inode = itohi(inode); dentry_t *hidden_dentry = wrapfs_hidden_dentry(file->f_dentry); print_entry_location(); fist_print_dentry(__FUNCTION__ " IN hidden_dentry", hidden_dentry); hidden_file = get_empty_filp(); if (!hidden_file) goto out; fist_dprint(8, "wrapfs_open: got empty hidden_file\n"); file->private_data = hidden_file; /* link two file's */ dget(hidden_dentry); fist_dprint(6, "wrapfs_open: got f_inode\n");#ifdef FIST_FILTER_DATA hidden_file->f_mode = file->f_mode | FMODE_READ; hidden_file->f_flags = file->f_flags; if (file->f_flags & O_APPEND) { fist_dprint(5, "file is opened in append-only mode\n"); hidden_file->f_flags &= ~O_APPEND; /* turn off O_APPEND flag */ }#else /* not FIST_FILTER_DATA */ hidden_file->f_mode = file->f_mode;#endif /* not FIST_FILTER_DATA */ hidden_file->f_pos = file->f_pos; hidden_file->f_reada = file->f_reada; if (hidden_file->f_mode & FMODE_WRITE) { err = get_write_access(hidden_inode); if (err) goto cleanup_dentry; } hidden_file->f_dentry = hidden_dentry; hidden_file->f_op = NULL; if (hidden_inode->i_op) hidden_file->f_op = hidden_inode->i_op->default_file_ops; fist_dprint(6, "wrapfs_open: pre open\n"); if (hidden_file->f_op && hidden_file->f_op->open) { err = hidden_file->f_op->open(hidden_inode, hidden_file); if (err) { printk(KERN_WARNING "wrapfs_open: error(%d)\n", err); goto cleanup_all; } } else { err = 0; } hidden_file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); fist_checkinode(inode, "post wrapfs_open"); fist_dprint(6, "wrapfs_open: done (%d)\n", err); goto out;cleanup_all: if (hidden_file->f_mode & FMODE_WRITE) put_write_access(hidden_inode);cleanup_dentry: hidden_file->f_dentry = NULL; dput(hidden_dentry); put_filp(hidden_file);out: fist_print_dentry(__FUNCTION__ " 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 = ftohf(file); 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 = ftohf(file); dentry_t *hidden_dentry; print_entry_location(); 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 err = -EINVAL; file_t *hidden_file = ftohf(file); dentry_t *hidden_dentry = wrapfs_hidden_dentry(dentry); print_entry_location(); 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); 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 = ftohf(file); 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_check_media_change(kdev_t dev){ int err = 0; super_block_t *sb; print_entry_location(); sb = get_super(dev); err = check_disk_change(stohs(sb)->s_dev); print_exit_status(err); return err;}#ifdef NOT_NEEDED/* * This is not needed, because our check_media_change will call * the generic check_disk_change() which will run the revalidate * function of the hidden file system, if implemented. */STATIC intwrapfs_file_revalidate(kdev_t dev){ return -ENOSYS;}#endif /* NOT_NEEDED */STATIC intwrapfs_lock(file_t *file, int cmd, struct file_lock *fl){ int err = 0; file_t *hidden_file = ftohf(file); 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_main_fops ={ llseek: wrapfs_llseek, read: wrapfs_read, write: wrapfs_write, readdir: wrapfs_readdir, poll: wrapfs_poll, ioctl: wrapfs_ioctl, mmap: generic_file_mmap, open: wrapfs_open, flush: wrapfs_flush, release: wrapfs_release, fsync: wrapfs_fsync, fasync: wrapfs_fasync, check_media_change: wrapfs_check_media_change,#ifdef NOT_NEEDED revalidate: wrapfs_file_revalidate,#endif /* NOT_NEEDED */ lock: wrapfs_lock,};struct file_operations wrapfs_dir_fops ={ llseek: wrapfs_llseek, read: wrapfs_dir_read, readdir: wrapfs_readdir, poll: wrapfs_poll, ioctl: wrapfs_ioctl, mmap: generic_file_mmap, open: wrapfs_open, flush: wrapfs_flush, release: wrapfs_release, fsync: wrapfs_fsync, fasync: wrapfs_fasync, check_media_change: wrapfs_check_media_change,#ifdef NOT_NEEDED revalidate: wrapfs_file_revalidate,#endif /* NOT_NEEDED */ lock: wrapfs_lock,};/* * Local variables: * c-basic-offset: 4 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -