/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
#include "xfs_inode.h"
#include "xfs_error.h"
#include "xfs_rw.h"
+#include "xfs_ioctl32.h"
#include <linux/dcache.h>
+#include <linux/smp_lock.h>
static struct vm_operations_struct linvfs_file_vm_ops;
STATIC inline ssize_t
__linvfs_read(
struct kiocb *iocb,
- char __user *buf,
+ char __user *buf,
int ioflags,
size_t count,
loff_t pos)
STATIC ssize_t
-linvfs_read(
+linvfs_aio_read(
struct kiocb *iocb,
- char __user *buf,
+ char __user *buf,
size_t count,
loff_t pos)
{
- return __linvfs_read(iocb, buf, 0, count, pos);
+ return __linvfs_read(iocb, buf, IO_ISAIO, count, pos);
}
STATIC ssize_t
-linvfs_read_invis(
+linvfs_aio_read_invis(
struct kiocb *iocb,
- char __user *buf,
+ char __user *buf,
size_t count,
loff_t pos)
{
- return __linvfs_read(iocb, buf, IO_INVIS, count, pos);
+ return __linvfs_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
}
STATIC inline ssize_t
__linvfs_write(
struct kiocb *iocb,
- const char *buf,
+ const char __user *buf,
int ioflags,
size_t count,
loff_t pos)
{
- struct iovec iov = {(void *)buf, count};
+ struct iovec iov = {(void __user *)buf, count};
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode);
ssize_t rval;
BUG_ON(iocb->ki_pos != pos);
- if (unlikely(file->f_flags & O_DIRECT)) {
+ if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
- VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
- ioflags, NULL, rval);
- } else {
- down(&inode->i_sem);
- VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
- ioflags, NULL, rval);
- up(&inode->i_sem);
- }
+ VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
return rval;
}
STATIC ssize_t
-linvfs_write(
+linvfs_aio_write(
struct kiocb *iocb,
- const char __user *buf,
+ const char __user *buf,
size_t count,
loff_t pos)
{
- return __linvfs_write(iocb, buf, 0, count, pos);
+ return __linvfs_write(iocb, buf, IO_ISAIO, count, pos);
}
STATIC ssize_t
-linvfs_write_invis(
+linvfs_aio_write_invis(
struct kiocb *iocb,
- const char __user *buf,
+ const char __user *buf,
size_t count,
loff_t pos)
{
- return __linvfs_write(iocb, buf, IO_INVIS, count, pos);
+ return __linvfs_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
}
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
- if (rval == -EIOCBQUEUED)
- rval = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
return rval;
init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = *ppos;
- if (unlikely(file->f_flags & O_DIRECT)) {
+ if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
- VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
- ioflags, NULL, rval);
- } else {
- down(&inode->i_sem);
- VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
- ioflags, NULL, rval);
- up(&inode->i_sem);
- }
- if (rval == -EIOCBQUEUED)
- rval = wait_on_sync_kiocb(&kiocb);
+ VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
*ppos = kiocb.ki_pos;
return rval;
vattr_t va = { .va_mask = XFS_AT_UPDATIME };
int error;
- if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
+ if (vp->v_vfsp->vfs_flag & VFS_DMI) {
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
error = -XFS_SEND_MMAP(mp, vma, 0);
vma->vm_ops = &linvfs_file_vm_ops;
VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
+ if (!error)
+ vn_revalidate(vp); /* update Linux inode flags */
return 0;
}
-STATIC int
+STATIC long
linvfs_ioctl(
- struct inode *inode,
struct file *filp,
unsigned int cmd,
unsigned long arg)
{
int error;
+ struct inode *inode = filp->f_dentry->d_inode;
vnode_t *vp = LINVFS_GET_VP(inode);
- ASSERT(vp);
- VOP_IOCTL(vp, inode, filp, 0, cmd, arg, error);
+ VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error);
VMODIFY(vp);
/* NOTE: some of the ioctl's return positive #'s as a
return error;
}
-STATIC int
+STATIC long
linvfs_ioctl_invis(
- struct inode *inode,
struct file *filp,
unsigned int cmd,
unsigned long arg)
{
int error;
+ struct inode *inode = filp->f_dentry->d_inode;
vnode_t *vp = LINVFS_GET_VP(inode);
ASSERT(vp);
- VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, arg, error);
+ VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
VMODIFY(vp);
/* NOTE: some of the ioctl's return positive #'s as a
vnode_t *vp = LINVFS_GET_VP(vma->vm_file->f_dentry->d_inode);
int error = 0;
- if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
+ if (vp->v_vfsp->vfs_flag & VFS_DMI) {
if ((vma->vm_flags & VM_MAYSHARE) &&
(newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE)) {
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
.write = do_sync_write,
.readv = linvfs_readv,
.writev = linvfs_writev,
- .aio_read = linvfs_read,
- .aio_write = linvfs_write,
+ .aio_read = linvfs_aio_read,
+ .aio_write = linvfs_aio_write,
.sendfile = linvfs_sendfile,
- .ioctl = linvfs_ioctl,
+ .unlocked_ioctl = linvfs_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = xfs_compat_ioctl,
+#endif
.mmap = linvfs_file_mmap,
.open = linvfs_open,
.release = linvfs_release,
.write = do_sync_write,
.readv = linvfs_readv_invis,
.writev = linvfs_writev_invis,
- .aio_read = linvfs_read_invis,
- .aio_write = linvfs_write_invis,
+ .aio_read = linvfs_aio_read_invis,
+ .aio_write = linvfs_aio_write_invis,
.sendfile = linvfs_sendfile,
- .ioctl = linvfs_ioctl_invis,
+ .unlocked_ioctl = linvfs_ioctl_invis,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = xfs_compat_invis_ioctl,
+#endif
.mmap = linvfs_file_mmap,
.open = linvfs_open,
.release = linvfs_release,
struct file_operations linvfs_dir_operations = {
.read = generic_read_dir,
.readdir = linvfs_readdir,
- .ioctl = linvfs_ioctl,
+ .unlocked_ioctl = linvfs_ioctl,
.fsync = linvfs_fsync,
};
static struct vm_operations_struct linvfs_file_vm_ops = {
.nopage = filemap_nopage,
+ .populate = filemap_populate,
#ifdef HAVE_VMOP_MPROTECT
.mprotect = linvfs_mprotect,
#endif