diff options
Diffstat (limited to 'fs/ncpfs/mmap.c')
| -rw-r--r-- | fs/ncpfs/mmap.c | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index 52d60c3d899..b359d12eb35 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -9,47 +9,47 @@ #include <linux/stat.h> #include <linux/time.h> #include <linux/kernel.h> +#include <linux/gfp.h> #include <linux/mm.h> #include <linux/shm.h> #include <linux/errno.h> #include <linux/mman.h> #include <linux/string.h> -#include <linux/slab.h> #include <linux/fcntl.h> -#include <linux/ncp_fs.h> +#include <linux/memcontrol.h> -#include "ncplib_kernel.h" #include <asm/uaccess.h> -#include <asm/system.h> + +#include "ncp_fs.h" /* * Fill in the supplied page for mmap + * XXX: how are we excluding truncate/invalidate here? Maybe need to lock + * page? */ -static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, - unsigned long address, int *type) +static int ncp_file_mmap_fault(struct vm_area_struct *area, + struct vm_fault *vmf) { struct file *file = area->vm_file; - struct dentry *dentry = file->f_dentry; + struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; - struct page* page; char *pg_addr; unsigned int already_read; unsigned int count; int bufsize; - int pos; + int pos; /* XXX: loff_t ? */ - page = alloc_page(GFP_HIGHUSER); /* ncpfs has nothing against high pages - as long as recvmsg and memset works on it */ - if (!page) - return page; - pg_addr = kmap(page); - address &= PAGE_MASK; - pos = address - area->vm_start + (area->vm_pgoff << PAGE_SHIFT); + /* + * ncpfs has nothing against high pages as long + * as recvmsg and memset works on it + */ + vmf->page = alloc_page(GFP_HIGHUSER); + if (!vmf->page) + return VM_FAULT_OOM; + pg_addr = kmap(vmf->page); + pos = vmf->pgoff << PAGE_SHIFT; count = PAGE_SIZE; - if (address + PAGE_SIZE > area->vm_end) { - count = area->vm_end - address; - } /* what we can read in one go */ bufsize = NCP_SERVER(inode)->buffer_size; @@ -83,32 +83,31 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, if (already_read < PAGE_SIZE) memset(pg_addr + already_read, 0, PAGE_SIZE - already_read); - flush_dcache_page(page); - kunmap(page); + flush_dcache_page(vmf->page); + kunmap(vmf->page); /* * If I understand ncp_read_kernel() properly, the above always * fetches from the network, here the analogue of disk. - * -- wli + * -- nyc */ - if (type) - *type = VM_FAULT_MAJOR; - inc_page_state(pgmajfault); - return page; + count_vm_event(PGMAJFAULT); + mem_cgroup_count_vm_event(area->vm_mm, PGMAJFAULT); + return VM_FAULT_MAJOR; } -static struct vm_operations_struct ncp_file_mmap = +static const struct vm_operations_struct ncp_file_mmap = { - .nopage = ncp_file_mmap_nopage, + .fault = ncp_file_mmap_fault, }; /* This is used for a general mmap of a ncp file */ int ncp_mmap(struct file *file, struct vm_area_struct *vma) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); - DPRINTK("ncp_mmap: called\n"); + ncp_dbg(1, "called\n"); if (!ncp_conn_valid(NCP_SERVER(inode))) return -EIO; @@ -118,7 +117,7 @@ int ncp_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; /* we do not support files bigger than 4GB... We eventually supports just 4GB... */ - if (((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff + if (vma_pages(vma) + vma->vm_pgoff > (1U << (32 - PAGE_SHIFT))) return -EFBIG; |
