diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/ops_file.c | 2 | ||||
-rw-r--r-- | fs/gfs2/ops_vm.c | 47 | ||||
-rw-r--r-- | fs/ncpfs/mmap.c | 38 | ||||
-rw-r--r-- | fs/ocfs2/mmap.c | 30 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 14 |
5 files changed, 62 insertions, 69 deletions
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 581ac11b2656..1a5e8e893d75 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c @@ -364,8 +364,6 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) else vma->vm_ops = &gfs2_vm_ops_private; - vma->vm_flags |= VM_CAN_INVALIDATE|VM_CAN_NONLINEAR; - gfs2_glock_dq_uninit(&i_gh); return error; diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index e9fe6eb74e75..dc287d2e3a66 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c @@ -27,13 +27,12 @@ #include "trans.h" #include "util.h" -static struct page *gfs2_private_fault(struct vm_area_struct *vma, - struct fault_data *fdata) +static int gfs2_private_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct gfs2_inode *ip = GFS2_I(vma->vm_file->f_mapping->host); set_bit(GIF_PAGED, &ip->i_flags); - return filemap_fault(vma, fdata); + return filemap_fault(vma, vmf); } static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) @@ -104,55 +103,55 @@ out: return error; } -static struct page *gfs2_sharewrite_fault(struct vm_area_struct *vma, - struct fault_data *fdata) +static int gfs2_sharewrite_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) { struct file *file = vma->vm_file; struct gfs2_file *gf = file->private_data; struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); struct gfs2_holder i_gh; - struct page *result = NULL; int alloc_required; int error; + int ret = VM_FAULT_MINOR; error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); if (error) - return NULL; + goto out; set_bit(GIF_PAGED, &ip->i_flags); set_bit(GIF_SW_PAGED, &ip->i_flags); error = gfs2_write_alloc_required(ip, - (u64)fdata->pgoff << PAGE_CACHE_SHIFT, + (u64)vmf->pgoff << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE, &alloc_required); if (error) { - fdata->type = VM_FAULT_OOM; /* XXX: are these right? */ - goto out; + ret = VM_FAULT_OOM; /* XXX: are these right? */ + goto out_unlock; } set_bit(GFF_EXLOCK, &gf->f_flags); - result = filemap_fault(vma, fdata); + ret = filemap_fault(vma, vmf); clear_bit(GFF_EXLOCK, &gf->f_flags); - if (!result) - goto out; + if (ret & (VM_FAULT_ERROR | FAULT_RET_NOPAGE)) + goto out_unlock; if (alloc_required) { - error = alloc_page_backing(ip, result); + /* XXX: do we need to drop page lock around alloc_page_backing?*/ + error = alloc_page_backing(ip, vmf->page); if (error) { - if (vma->vm_flags & VM_CAN_INVALIDATE) - unlock_page(result); - page_cache_release(result); - fdata->type = VM_FAULT_OOM; - result = NULL; - goto out; + if (ret & FAULT_RET_LOCKED) + unlock_page(vmf->page); + page_cache_release(vmf->page); + ret = VM_FAULT_OOM; + goto out_unlock; } - set_page_dirty(result); + set_page_dirty(vmf->page); } -out: +out_unlock: gfs2_glock_dq_uninit(&i_gh); - - return result; +out: + return ret; } struct vm_operations_struct gfs2_vm_ops_private = { diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index af48b792ca04..a94473d3072c 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -24,33 +24,35 @@ /* * 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_fault(struct vm_area_struct *area, - struct fault_data *fdata) +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_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) { - fdata->type = VM_FAULT_OOM; - return NULL; - } - pg_addr = kmap(page); - pos = fdata->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 (fdata->address + PAGE_SIZE > area->vm_end) { + if ((unsigned long)vmf->virtual_address + PAGE_SIZE > area->vm_end) { WARN_ON(1); /* shouldn't happen? */ - count = area->vm_end - fdata->address; + count = area->vm_end - (unsigned long)vmf->virtual_address; } /* what we can read in one go */ bufsize = NCP_SERVER(inode)->buffer_size; @@ -85,17 +87,16 @@ static struct page* ncp_file_mmap_fault(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 */ - fdata->type = VM_FAULT_MAJOR; count_vm_event(PGMAJFAULT); - return page; + return VM_FAULT_MAJOR; } static struct vm_operations_struct ncp_file_mmap = @@ -124,7 +125,6 @@ int ncp_mmap(struct file *file, struct vm_area_struct *vma) return -EFBIG; vma->vm_ops = &ncp_file_mmap; - vma->vm_flags |= VM_CAN_INVALIDATE; file_accessed(file); return 0; } diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index cd75508b1c8a..ee64749e2eeb 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c @@ -60,30 +60,28 @@ static inline int ocfs2_vm_op_unblock_sigs(sigset_t *oldset) return sigprocmask(SIG_SETMASK, oldset, NULL); } -static struct page *ocfs2_fault(struct vm_area_struct *area, - struct fault_data *fdata) +static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) { - struct page *page = NULL; sigset_t blocked, oldset; - int ret; + int error, ret; - mlog_entry("(area=%p, page offset=%lu)\n", area, fdata->pgoff); + mlog_entry("(area=%p, page offset=%lu)\n", area, vmf->pgoff); - ret = ocfs2_vm_op_block_sigs(&blocked, &oldset); - if (ret < 0) { - fdata->type = VM_FAULT_SIGBUS; - mlog_errno(ret); + error = ocfs2_vm_op_block_sigs(&blocked, &oldset); + if (error < 0) { + mlog_errno(error); + ret = VM_FAULT_SIGBUS; goto out; } - page = filemap_fault(area, fdata); + ret = filemap_fault(area, vmf); - ret = ocfs2_vm_op_unblock_sigs(&oldset); - if (ret < 0) - mlog_errno(ret); + error = ocfs2_vm_op_unblock_sigs(&oldset); + if (error < 0) + mlog_errno(error); out: - mlog_exit_ptr(page); - return page; + mlog_exit_ptr(vmf->page); + return ret; } static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, @@ -225,7 +223,7 @@ int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) ocfs2_meta_unlock(file->f_dentry->d_inode, lock_level); out: vma->vm_ops = &ocfs2_file_vm_ops; - vma->vm_flags |= VM_CAN_INVALIDATE | VM_CAN_NONLINEAR; + vma->vm_flags |= VM_CAN_NONLINEAR; return 0; } diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index f12e80a69c68..2d4be2f247b2 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -212,20 +212,18 @@ xfs_file_fsync( } #ifdef CONFIG_XFS_DMAPI -STATIC struct page * +STATIC int xfs_vm_fault( struct vm_area_struct *vma, - struct fault_data *fdata) + struct vm_fault *vmf) { struct inode *inode = vma->vm_file->f_path.dentry->d_inode; bhv_vnode_t *vp = vn_from_inode(inode); ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); - if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), vma, 0)) { - fdata->type = VM_FAULT_SIGBUS; - return NULL; - } - return filemap_fault(vma, fdata); + if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), vma, 0)) + return VM_FAULT_SIGBUS; + return filemap_fault(vma, vmf); } #endif /* CONFIG_XFS_DMAPI */ @@ -311,7 +309,7 @@ xfs_file_mmap( struct vm_area_struct *vma) { vma->vm_ops = &xfs_file_vm_ops; - vma->vm_flags |= VM_CAN_INVALIDATE | VM_CAN_NONLINEAR; + vma->vm_flags |= VM_CAN_NONLINEAR; #ifdef CONFIG_XFS_DMAPI if (vn_from_inode(filp->f_path.dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI) |