Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.39 126 lines 2.9 kB view raw
1/* 2 * mmap.c 3 * 4 * Copyright (C) 1995, 1996 by Volker Lendecke 5 * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache 6 * 7 */ 8 9#include <linux/stat.h> 10#include <linux/time.h> 11#include <linux/kernel.h> 12#include <linux/gfp.h> 13#include <linux/mm.h> 14#include <linux/shm.h> 15#include <linux/errno.h> 16#include <linux/mman.h> 17#include <linux/string.h> 18#include <linux/fcntl.h> 19 20#include <asm/uaccess.h> 21#include <asm/system.h> 22 23#include "ncp_fs.h" 24 25/* 26 * Fill in the supplied page for mmap 27 * XXX: how are we excluding truncate/invalidate here? Maybe need to lock 28 * page? 29 */ 30static int ncp_file_mmap_fault(struct vm_area_struct *area, 31 struct vm_fault *vmf) 32{ 33 struct file *file = area->vm_file; 34 struct dentry *dentry = file->f_path.dentry; 35 struct inode *inode = dentry->d_inode; 36 char *pg_addr; 37 unsigned int already_read; 38 unsigned int count; 39 int bufsize; 40 int pos; /* XXX: loff_t ? */ 41 42 /* 43 * ncpfs has nothing against high pages as long 44 * as recvmsg and memset works on it 45 */ 46 vmf->page = alloc_page(GFP_HIGHUSER); 47 if (!vmf->page) 48 return VM_FAULT_OOM; 49 pg_addr = kmap(vmf->page); 50 pos = vmf->pgoff << PAGE_SHIFT; 51 52 count = PAGE_SIZE; 53 /* what we can read in one go */ 54 bufsize = NCP_SERVER(inode)->buffer_size; 55 56 already_read = 0; 57 if (ncp_make_open(inode, O_RDONLY) >= 0) { 58 while (already_read < count) { 59 int read_this_time; 60 int to_read; 61 62 to_read = bufsize - (pos % bufsize); 63 64 to_read = min_t(unsigned int, to_read, count - already_read); 65 66 if (ncp_read_kernel(NCP_SERVER(inode), 67 NCP_FINFO(inode)->file_handle, 68 pos, to_read, 69 pg_addr + already_read, 70 &read_this_time) != 0) { 71 read_this_time = 0; 72 } 73 pos += read_this_time; 74 already_read += read_this_time; 75 76 if (read_this_time < to_read) { 77 break; 78 } 79 } 80 ncp_inode_close(inode); 81 82 } 83 84 if (already_read < PAGE_SIZE) 85 memset(pg_addr + already_read, 0, PAGE_SIZE - already_read); 86 flush_dcache_page(vmf->page); 87 kunmap(vmf->page); 88 89 /* 90 * If I understand ncp_read_kernel() properly, the above always 91 * fetches from the network, here the analogue of disk. 92 * -- wli 93 */ 94 count_vm_event(PGMAJFAULT); 95 return VM_FAULT_MAJOR; 96} 97 98static const struct vm_operations_struct ncp_file_mmap = 99{ 100 .fault = ncp_file_mmap_fault, 101}; 102 103 104/* This is used for a general mmap of a ncp file */ 105int ncp_mmap(struct file *file, struct vm_area_struct *vma) 106{ 107 struct inode *inode = file->f_path.dentry->d_inode; 108 109 DPRINTK("ncp_mmap: called\n"); 110 111 if (!ncp_conn_valid(NCP_SERVER(inode))) 112 return -EIO; 113 114 /* only PAGE_COW or read-only supported now */ 115 if (vma->vm_flags & VM_SHARED) 116 return -EINVAL; 117 /* we do not support files bigger than 4GB... We eventually 118 supports just 4GB... */ 119 if (((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff 120 > (1U << (32 - PAGE_SHIFT))) 121 return -EFBIG; 122 123 vma->vm_ops = &ncp_file_mmap; 124 file_accessed(file); 125 return 0; 126}