[XFS] Provide XFS support for the splice syscall.
Signed-off-by: Nathan Scott <nathans@sgi.com>
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 85997b1..ae4c475 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -69,7 +69,6 @@
return rval;
}
-
STATIC ssize_t
xfs_file_aio_read(
struct kiocb *iocb,
@@ -90,7 +89,6 @@
return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
}
-
STATIC inline ssize_t
__xfs_file_write(
struct kiocb *iocb,
@@ -113,7 +111,6 @@
return rval;
}
-
STATIC ssize_t
xfs_file_aio_write(
struct kiocb *iocb,
@@ -134,7 +131,6 @@
return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
}
-
STATIC inline ssize_t
__xfs_file_readv(
struct file *file,
@@ -179,7 +175,6 @@
return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
}
-
STATIC inline ssize_t
__xfs_file_writev(
struct file *file,
@@ -204,7 +199,6 @@
return rval;
}
-
STATIC ssize_t
xfs_file_writev(
struct file *file,
@@ -228,7 +222,7 @@
STATIC ssize_t
xfs_file_sendfile(
struct file *filp,
- loff_t *ppos,
+ loff_t *pos,
size_t count,
read_actor_t actor,
void *target)
@@ -236,10 +230,80 @@
vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
ssize_t rval;
- VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, rval);
+ VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
return rval;
}
+STATIC ssize_t
+xfs_file_sendfile_invis(
+ struct file *filp,
+ loff_t *pos,
+ size_t count,
+ read_actor_t actor,
+ void *target)
+{
+ vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
+ ssize_t rval;
+
+ VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
+ return rval;
+}
+
+STATIC ssize_t
+xfs_file_splice_read(
+ struct file *infilp,
+ struct inode *pipe,
+ size_t len,
+ unsigned int flags)
+{
+ vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
+ ssize_t rval;
+
+ VOP_SPLICE_READ(vp, infilp, pipe, len, flags, 0, NULL, rval);
+ return rval;
+}
+
+STATIC ssize_t
+xfs_file_splice_read_invis(
+ struct file *infilp,
+ struct inode *pipe,
+ size_t len,
+ unsigned int flags)
+{
+ vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
+ ssize_t rval;
+
+ VOP_SPLICE_READ(vp, infilp, pipe, len, flags, IO_INVIS, NULL, rval);
+ return rval;
+}
+
+STATIC ssize_t
+xfs_file_splice_write(
+ struct inode *pipe,
+ struct file *outfilp,
+ size_t len,
+ unsigned int flags)
+{
+ vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
+ ssize_t rval;
+
+ VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, 0, NULL, rval);
+ return rval;
+}
+
+STATIC ssize_t
+xfs_file_splice_write_invis(
+ struct inode *pipe,
+ struct file *outfilp,
+ size_t len,
+ unsigned int flags)
+{
+ vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
+ ssize_t rval;
+
+ VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, IO_INVIS, NULL, rval);
+ return rval;
+}
STATIC int
xfs_file_open(
@@ -251,13 +315,10 @@
if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
return -EFBIG;
-
- ASSERT(vp);
VOP_OPEN(vp, NULL, error);
return -error;
}
-
STATIC int
xfs_file_release(
struct inode *inode,
@@ -271,7 +332,6 @@
return -error;
}
-
STATIC int
xfs_file_fsync(
struct file *filp,
@@ -285,21 +345,11 @@
if (datasync)
flags |= FSYNC_DATA;
-
- ASSERT(vp);
VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error);
return -error;
}
-/*
- * xfs_file_readdir maps to VOP_READDIR().
- * We need to build a uio, cred, ...
- */
-
-#define nextdp(dp) ((struct xfs_dirent *)((char *)(dp) + (dp)->d_reclen))
-
#ifdef CONFIG_XFS_DMAPI
-
STATIC struct page *
xfs_vm_nopage(
struct vm_area_struct *area,
@@ -319,10 +369,8 @@
return filemap_nopage(area, address, type);
}
-
#endif /* CONFIG_XFS_DMAPI */
-
STATIC int
xfs_file_readdir(
struct file *filp,
@@ -330,7 +378,7 @@
filldir_t filldir)
{
int error = 0;
- vnode_t *vp;
+ vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
uio_t uio;
iovec_t iov;
int eof = 0;
@@ -340,9 +388,6 @@
xfs_off_t start_offset, curr_offset;
xfs_dirent_t *dbp = NULL;
- vp = vn_from_inode(filp->f_dentry->d_inode);
- ASSERT(vp);
-
/* Try fairly hard to get memory */
do {
if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL)))
@@ -387,7 +432,7 @@
}
size -= dbp->d_reclen;
curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */;
- dbp = nextdp(dbp);
+ dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
}
}
done:
@@ -402,7 +447,6 @@
return -error;
}
-
STATIC int
xfs_file_mmap(
struct file *filp,
@@ -457,11 +501,10 @@
unsigned int cmd,
unsigned long arg)
{
- int error;
struct inode *inode = filp->f_dentry->d_inode;
vnode_t *vp = vn_from_inode(inode);
+ int error;
- ASSERT(vp);
VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
VMODIFY(vp);
@@ -537,6 +580,8 @@
.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,
#ifdef CONFIG_COMPAT
.compat_ioctl = xfs_file_compat_ioctl,
@@ -558,7 +603,9 @@
.writev = xfs_file_writev_invis,
.aio_read = xfs_file_aio_read_invis,
.aio_write = xfs_file_aio_write_invis,
- .sendfile = xfs_file_sendfile,
+ .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,
#ifdef CONFIG_COMPAT
.compat_ioctl = xfs_file_compat_invis_ioctl,