Commit 8bd64089 authored by Christoph Hellwig's avatar Christoph Hellwig

[XFS] Add sendfile support

SGI Modid: 2.5.x-xfs:slinx:132980a
parent ca8eaf61
......@@ -138,6 +138,22 @@ linvfs_aio_write(
return linvfs_writev(iocb->ki_filp, &iov, 1, &iocb->ki_pos);
}
STATIC ssize_t
linvfs_sendfile(
struct file *filp,
loff_t *ppos,
size_t count,
read_actor_t actor,
void *target)
{
vnode_t *vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
int error;
VOP_SENDFILE(vp, filp, ppos, count, actor, target, NULL, error);
return error;
}
STATIC int
linvfs_open(
......@@ -348,6 +364,7 @@ struct file_operations linvfs_file_operations = {
.writev = linvfs_writev,
.aio_read = linvfs_aio_read,
.aio_write = linvfs_aio_write,
.sendfile = linvfs_sendfile,
.ioctl = linvfs_ioctl,
.mmap = linvfs_file_mmap,
.open = linvfs_open,
......
......@@ -205,6 +205,67 @@ xfs_read(
return ret;
}
ssize_t
xfs_sendfile(
bhv_desc_t *bdp,
struct file *filp,
loff_t *offp,
size_t count,
read_actor_t actor,
void *target,
cred_t *credp)
{
size_t size = 0;
ssize_t ret;
xfs_fsize_t n;
xfs_inode_t *ip;
xfs_mount_t *mp;
vnode_t *vp;
ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp);
mp = ip->i_mount;
vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address);
XFS_STATS_INC(xfsstats.xs_read_calls);
n = XFS_MAX_FILE_OFFSET - *offp;
if ((n <= 0) || (size == 0))
return 0;
if (n < size)
size = n;
if (XFS_FORCED_SHUTDOWN(mp)) {
return -EIO;
}
xfs_ilock(ip, XFS_IOLOCK_SHARED);
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
!(filp->f_mode & FINVIS)) {
int error;
vrwlock_t locktype = VRWLOCK_READ;
error = xfs_dm_send_data_event(DM_EVENT_READ, bdp, *offp,
size, FILP_DELAY_FLAG(filp), &locktype);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
return -error;
}
}
ret = generic_file_sendfile(filp, offp, count, actor, target);
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
if (!(filp->f_mode & FINVIS))
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
return ret;
}
/*
* This routine is called to handle zeroing any space in the last
* block of the file that is beyond the EOF. We do this since the
......
......@@ -180,6 +180,9 @@ typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct file *,
typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct file *,
const struct iovec *, unsigned long,
loff_t *, struct cred *);
typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
loff_t *, size_t, read_actor_t,
void *, struct cred *);
typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, unsigned int, unsigned long);
typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
struct cred *);
......@@ -232,6 +235,7 @@ typedef struct vnodeops {
vop_open_t vop_open;
vop_read_t vop_read;
vop_write_t vop_write;
vop_sendfile_t vop_sendfile;
vop_ioctl_t vop_ioctl;
vop_getattr_t vop_getattr;
vop_setattr_t vop_setattr;
......@@ -283,6 +287,12 @@ typedef struct vnodeops {
rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,cr);\
VN_BHV_READ_UNLOCK(&(vp)->v_bh); \
}
#define VOP_SENDFILE(vp,f,of,cnt,act,targ,cr,rv) \
{ \
VN_BHV_READ_LOCK(&(vp)->v_bh); \
rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,of,cnt,act,targ,cr);\
VN_BHV_READ_UNLOCK(&(vp)->v_bh); \
}
#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
{ \
VN_BHV_READ_LOCK(&(vp)->v_bh); \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment