return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
}
-STATIC ssize_t
-xfs_file_sendfile(
- struct file *filp,
- loff_t *pos,
- size_t count,
- read_actor_t actor,
- void *target)
-{
- return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode),
- filp, pos, 0, count, actor, target, NULL);
-}
-
-STATIC ssize_t
-xfs_file_sendfile_invis(
- struct file *filp,
- loff_t *pos,
- size_t count,
- read_actor_t actor,
- void *target)
-{
- return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode),
- filp, pos, IO_INVIS, count, actor, target, NULL);
-}
-
STATIC ssize_t
xfs_file_splice_read(
struct file *infilp,
return -bhv_vop_open(vn_from_inode(inode), NULL);
}
-STATIC int
-xfs_file_close(
- struct file *filp,
- fl_owner_t id)
-{
- return -bhv_vop_close(vn_from_inode(filp->f_path.dentry->d_inode), 0,
- file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
-}
-
STATIC int
xfs_file_release(
struct inode *inode,
}
#ifdef CONFIG_XFS_DMAPI
-STATIC struct page *
-xfs_vm_nopage(
- struct vm_area_struct *area,
- unsigned long address,
- int *type)
+STATIC int
+xfs_vm_fault(
+ struct vm_area_struct *vma,
+ struct vm_fault *vmf)
{
- struct inode *inode = area->vm_file->f_path.dentry->d_inode;
+ 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), area, 0))
- return NULL;
- return filemap_nopage(area, address, type);
+ if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), vma, 0))
+ return VM_FAULT_SIGBUS;
+ return filemap_fault(vma, vmf);
}
#endif /* CONFIG_XFS_DMAPI */
struct vm_area_struct *vma)
{
vma->vm_ops = &xfs_file_vm_ops;
+ 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)
}
#endif /* HAVE_FOP_OPEN_EXEC */
+/*
+ * mmap()d file has taken write protection fault and is being made
+ * writable. We can set the page state up correctly for a writable
+ * page, which means we can do correct delalloc accounting (ENOSPC
+ * checking!) and unwritten extent mapping.
+ */
+STATIC int
+xfs_vm_page_mkwrite(
+ struct vm_area_struct *vma,
+ struct page *page)
+{
+ return block_page_mkwrite(vma, page, xfs_get_blocks);
+}
+
const struct file_operations xfs_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
.aio_read = xfs_file_aio_read,
.aio_write = xfs_file_aio_write,
- .sendfile = xfs_file_sendfile,
.splice_read = xfs_file_splice_read,
.splice_write = xfs_file_splice_write,
.unlocked_ioctl = xfs_file_ioctl,
#endif
.mmap = xfs_file_mmap,
.open = xfs_file_open,
- .flush = xfs_file_close,
.release = xfs_file_release,
.fsync = xfs_file_fsync,
#ifdef HAVE_FOP_OPEN_EXEC
.write = do_sync_write,
.aio_read = xfs_file_aio_read_invis,
.aio_write = xfs_file_aio_write_invis,
- .sendfile = xfs_file_sendfile_invis,
.splice_read = xfs_file_splice_read_invis,
.splice_write = xfs_file_splice_write_invis,
.unlocked_ioctl = xfs_file_ioctl_invis,
#endif
.mmap = xfs_file_mmap,
.open = xfs_file_open,
- .flush = xfs_file_close,
.release = xfs_file_release,
.fsync = xfs_file_fsync,
};
};
static struct vm_operations_struct xfs_file_vm_ops = {
- .nopage = filemap_nopage,
- .populate = filemap_populate,
+ .fault = filemap_fault,
+ .page_mkwrite = xfs_vm_page_mkwrite,
};
#ifdef CONFIG_XFS_DMAPI
static struct vm_operations_struct xfs_dmapi_file_vm_ops = {
- .nopage = xfs_vm_nopage,
- .populate = filemap_populate,
+ .fault = xfs_vm_fault,
+ .page_mkwrite = xfs_vm_page_mkwrite,
#ifdef HAVE_VMOP_MPROTECT
.mprotect = xfs_vm_mprotect,
#endif