www.pudn.com > cryptfs030905.rar > vm_area.c
/* * Copyright (c) 1997-2003 Erez Zadok * Copyright (c) 2001-2003 Stony Brook 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: vm_area.c,v 1.11 2003/07/29 18:17:21 ezk Exp $ */ #ifdef HAVE_CONFIG_H # include#endif /* HAVE_CONFIG_H */ #ifdef FISTGEN # include "fist_cryptfs.h" #endif /* FISTGEN */ #include "fist.h" #include "cryptfs.h" #ifdef NOT_NEEDED # error this is the old mmap method from file.c STATIC int cryptfs_mmap(file_t *file, vm_area_t *vma) { int err = 0; file_t *hidden_file = NULL; inode_t *inode; inode_t *hidden_inode; vm_area_t *hidden_vma = (vm_area_t *) 0xdeadc0de; print_entry_location(); if (ftopd(file) != NULL) hidden_file = ftohf(file); inode = file->f_dentry->d_inode; hidden_inode = itohi(inode); 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, atomic_read(&inode->i_count), atomic_read(&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 = &cryptfs_shared_vmops; } else { vma->vm_ops = &cryptfs_private_vmops; } if (!inode->i_sb || !S_ISREG(inode->i_mode)) { err = -EACCES; goto out; } if (!hidden_inode->i_op || !hidden_inode->i_mapping->a_ops->readpage) { err = -ENOEXEC; goto out; } UPDATE_ATIME(inode); /* * 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); hidden_vma->vm_file = hidden_file; atomic_inc(&hidden_file->f_count); } /* * 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, atomic_read(&inode->i_count), atomic_read(&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; } STATIC void cryptfs_vm_open(vm_area_t *vma) { vm_area_t *hidden_vma, *hidden_vma2; file_t *file; file_t *hidden_file = NULL; print_entry_location(); hidden_vma = vmatohvma(vma); file = vma->vm_file; if (ftopd(file) != NULL) hidden_file = ftohf(file); fist_dprint(6, "VM_OPEN: file 0x%x, hidden_file 0x%x, file->f_count %d, hidden_file->f_count %d\n", (int) file, (int) hidden_file, (int) atomic_read(&file->f_count), (int) atomic_read(&hidden_file->f_count)); if (hidden_vma->vm_ops->open) hidden_vma->vm_ops->open(hidden_vma); atomic_inc(&hidden_file->f_count); /* we need to duplicate the private data */ hidden_vma2 = kmalloc(sizeof(vm_area_t), GFP_KERNEL); if (!hidden_vma2) { printk("VM_OPEN: Out of memory\n"); goto out; } memcpy(hidden_vma2, hidden_vma, sizeof(vm_area_t)); vmatohvma(vma) = hidden_vma2; out: fist_dprint(6, "VM_OPEN2: file 0x%x, hidden_file 0x%x, file->f_count %d, hidden_file->f_count %d\n", (int) file, (int) hidden_file, (int) atomic_read(&file->f_count), (int) atomic_read(&hidden_file->f_count)); print_exit_location(); } STATIC void cryptfs_vm_close(vm_area_t *vma) { vm_area_t *hidden_vma; file_t *file; file_t *hidden_file = NULL; print_entry_location(); hidden_vma = vmatohvma(vma); file = vma->vm_file; if (ftopd(file) != NULL) hidden_file = ftohf(file); fist_dprint(6, "VM_CLOSE1: file 0x%x, hidden_file 0x%x, file->f_count %d, hidden_file->f_count %d\n", (int) file, (int) hidden_file, (int) atomic_read(&file->f_count), (int) atomic_read(&hidden_file->f_count)); ASSERT(hidden_vma != NULL); if (hidden_vma->vm_ops->close) hidden_vma->vm_ops->close(hidden_vma); fput(hidden_file); kfree(hidden_vma); vmatohvma(vma) = NULL; fist_dprint(6, "VM_CLOSE2: file 0x%x, hidden_file 0x%x, file->f_count %d, hidden_file->f_count %d\n", (int) file, (int) hidden_file, (int) atomic_read(&file->f_count), (int) atomic_read(&hidden_file->f_count)); print_exit_location(); } STATIC void cryptfs_vm_shared_unmap(vm_area_t *vma, unsigned long start, size_t len) { vm_area_t *hidden_vma; file_t *file; file_t *hidden_file = NULL; print_entry_location(); hidden_vma = vmatohvma(vma); file = vma->vm_file; if (ftopd(file) != NULL) hidden_file = ftohf(file); fist_dprint(6, "VM_S_UNMAP1: file 0x%x, hidden_file 0x%x, file->f_count %d, hidden_file->f_count %d\n", (int) file, (int) hidden_file, (int) atomic_read(&file->f_count), (int) atomic_read(&hidden_file->f_count)); /* * call sync (filemap_sync) because the default filemap_unmap * calls it too. */ filemap_sync(vma, start, len, MS_ASYNC); if (hidden_vma->vm_ops->unmap) hidden_vma->vm_ops->unmap(hidden_vma, start, len); fist_dprint(6, "VM_S_UNMAP2: file 0x%x, hidden_file 0x%x, file->f_count %d, hidden_file->f_count %d\n", (int) file, (int) hidden_file, (int) atomic_read(&file->f_count), (int) atomic_read(&hidden_file->f_count)); print_exit_location(); } /* * Shared mappings need to be able to do the right thing at * close/unmap/sync. They will also use the private file as * backing-store for swapping.. */ struct vm_operations_struct cryptfs_shared_vmops = { open: cryptfs_vm_open, close: cryptfs_vm_close, unmap: cryptfs_vm_shared_unmap, sync: filemap_sync, nopage: filemap_nopage, swapout: filemap_swapout, }; /* * Private mappings just need to be able to load in the map. * * (This is actually used for shared mappings as well, if we * know they can't ever get write permissions..) */ struct vm_operations_struct cryptfs_private_vmops = { nopage: filemap_nopage, }; #endif /* NOT_NEEDED */ /* * Local variables: * c-basic-offset: 4 * End: */