Commit 36a49183 authored by Stephen Lord's avatar Stephen Lord Committed by Stephen Lord

Change the way XFS implements the invisible I/O mechanism used by

the online backup tools.
parent 79bfe848
......@@ -58,29 +58,55 @@
static struct vm_operations_struct linvfs_file_vm_ops;
STATIC ssize_t
linvfs_read(
STATIC inline ssize_t
__linvfs_read(
struct kiocb *iocb,
char __user *buf,
int ioflags,
size_t count,
loff_t pos)
{
struct iovec iov = {buf, count};
struct file *file = iocb->ki_filp;
vnode_t *vp;
int error;
BUG_ON(iocb->ki_pos != pos);
vp = LINVFS_GET_VP(iocb->ki_filp->f_dentry->d_inode);
VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, NULL, error);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
vp = LINVFS_GET_VP(file->f_dentry->d_inode);
VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, error);
return error;
}
STATIC ssize_t
linvfs_write(
linvfs_read(
struct kiocb *iocb,
char __user *buf,
size_t count,
loff_t pos)
{
return __linvfs_read(iocb, buf, 0, count, pos);
}
STATIC ssize_t
linvfs_read_invis(
struct kiocb *iocb,
char __user *buf,
size_t count,
loff_t pos)
{
return __linvfs_read(iocb, buf, IO_INVIS, count, pos);
}
STATIC inline ssize_t
__linvfs_write(
struct kiocb *iocb,
const char *buf,
int ioflags,
size_t count,
loff_t pos)
{
......@@ -89,25 +115,48 @@ linvfs_write(
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode);
int error;
int direct = file->f_flags & O_DIRECT;
BUG_ON(iocb->ki_pos != pos);
if (direct) {
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, NULL, error);
if (unlikely(file->f_flags & O_DIRECT)) {
ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
ioflags, NULL, error);
} else {
down(&inode->i_sem);
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, NULL, error);
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
ioflags, NULL, error);
up(&inode->i_sem);
}
return error;
}
STATIC ssize_t
linvfs_readv(
linvfs_write(
struct kiocb *iocb,
const char __user *buf,
size_t count,
loff_t pos)
{
return __linvfs_write(iocb, buf, 0, count, pos);
}
STATIC ssize_t
linvfs_write_invis(
struct kiocb *iocb,
const char __user *buf,
size_t count,
loff_t pos)
{
return __linvfs_write(iocb, buf, IO_INVIS, count, pos);
}
STATIC inline ssize_t
__linvfs_readv(
struct file *file,
const struct iovec *iov,
int ioflags,
unsigned long nr_segs,
loff_t *ppos)
{
......@@ -118,7 +167,10 @@ linvfs_readv(
init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = *ppos;
VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, NULL, error);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, error);
if (-EIOCBQUEUED == error)
error = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
......@@ -127,25 +179,49 @@ linvfs_readv(
}
STATIC ssize_t
linvfs_writev(
linvfs_readv(
struct file *file,
const struct iovec *iov,
unsigned long nr_segs,
loff_t *ppos)
{
return __linvfs_readv(file, iov, 0, nr_segs, ppos);
}
STATIC ssize_t
linvfs_readv_invis(
struct file *file,
const struct iovec *iov,
unsigned long nr_segs,
loff_t *ppos)
{
return __linvfs_readv(file, iov, IO_INVIS, nr_segs, ppos);
}
STATIC inline ssize_t
__linvfs_writev(
struct file *file,
const struct iovec *iov,
int ioflags,
unsigned long nr_segs,
loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode);
struct kiocb kiocb;
int error;
int direct = file->f_flags & O_DIRECT;
init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = *ppos;
if (direct) {
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, NULL, error);
if (unlikely(file->f_flags & O_DIRECT)) {
ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
ioflags, NULL, error);
} else {
down(&inode->i_sem);
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, NULL, error);
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
ioflags, NULL, error);
up(&inode->i_sem);
}
if (-EIOCBQUEUED == error)
......@@ -155,6 +231,27 @@ linvfs_writev(
return error;
}
STATIC ssize_t
linvfs_writev(
struct file *file,
const struct iovec *iov,
unsigned long nr_segs,
loff_t *ppos)
{
return __linvfs_writev(file, iov, 0, nr_segs, ppos);
}
STATIC ssize_t
linvfs_writev_invis(
struct file *file,
const struct iovec *iov,
unsigned long nr_segs,
loff_t *ppos)
{
return __linvfs_writev(file, iov, IO_INVIS, nr_segs, ppos);
}
STATIC ssize_t
linvfs_sendfile(
struct file *filp,
......@@ -166,8 +263,7 @@ linvfs_sendfile(
vnode_t *vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
int error;
VOP_SENDFILE(vp, filp, ppos, count, actor, target, NULL, error);
VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, error);
return error;
}
......@@ -260,7 +356,6 @@ linvfs_readdir(
return -ENOMEM;
uio.uio_iov = &iov;
uio.uio_fmode = filp->f_mode;
uio.uio_segflg = UIO_SYSSPACE;
curr_offset = filp->f_pos;
if (filp->f_pos != 0x7fffffff)
......@@ -346,7 +441,30 @@ linvfs_ioctl(
vnode_t *vp = LINVFS_GET_VP(inode);
ASSERT(vp);
VOP_IOCTL(vp, inode, filp, cmd, arg, error);
VOP_IOCTL(vp, inode, filp, 0, cmd, arg, error);
VMODIFY(vp);
/* NOTE: some of the ioctl's return positive #'s as a
* byte count indicating success, such as
* readlink_by_handle. So we don't "sign flip"
* like most other routines. This means true
* errors need to be returned as a negative value.
*/
return error;
}
STATIC int
linvfs_ioctl_invis(
struct inode *inode,
struct file *filp,
unsigned int cmd,
unsigned long arg)
{
int error;
vnode_t *vp = LINVFS_GET_VP(inode);
ASSERT(vp);
VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, arg, error);
VMODIFY(vp);
/* NOTE: some of the ioctl's return positive #'s as a
......@@ -396,6 +514,23 @@ struct file_operations linvfs_file_operations = {
.fsync = linvfs_fsync,
};
struct file_operations linvfs_invis_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
.readv = linvfs_readv_invis,
.writev = linvfs_writev_invis,
.aio_read = linvfs_read_invis,
.aio_write = linvfs_write_invis,
.sendfile = linvfs_sendfile,
.ioctl = linvfs_ioctl_invis,
.mmap = linvfs_file_mmap,
.open = linvfs_open,
.release = linvfs_release,
.fsync = linvfs_fsync,
};
struct file_operations linvfs_dir_operations = {
.read = generic_read_dir,
.readdir = linvfs_readdir,
......
......@@ -373,7 +373,8 @@ xfs_open_by_handle(
put_unused_fd(new_fd);
return -XFS_ERROR(-PTR_ERR(filp));
}
filp->f_mode |= FINVIS;
if (inode->i_mode & S_IFREG)
filp->f_op = &linvfs_invis_file_operations;
fd_install(new_fd, filp);
return new_fd;
......@@ -415,12 +416,11 @@ xfs_readlink_by_handle(
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_fmode = FINVIS;
auio.uio_offset = 0;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_resid = olen;
VOP_READLINK(vp, &auio, NULL, error);
VOP_READLINK(vp, &auio, IO_INVIS, NULL, error);
VN_RELE(vp);
return (olen - auio.uio_resid);
......@@ -575,6 +575,7 @@ xfs_ioc_space(
bhv_desc_t *bdp,
vnode_t *vp,
struct file *filp,
int flags,
unsigned int cmd,
unsigned long arg);
......@@ -606,6 +607,7 @@ STATIC int
xfs_ioc_getbmap(
bhv_desc_t *bdp,
struct file *filp,
int flags,
unsigned int cmd,
unsigned long arg);
......@@ -619,6 +621,7 @@ xfs_ioctl(
bhv_desc_t *bdp,
struct inode *inode,
struct file *filp,
int ioflags,
unsigned int cmd,
unsigned long arg)
{
......@@ -652,7 +655,7 @@ xfs_ioctl(
!capable(CAP_SYS_ADMIN))
return -EPERM;
return xfs_ioc_space(bdp, vp, filp, cmd, arg);
return xfs_ioc_space(bdp, vp, filp, ioflags, cmd, arg);
case XFS_IOC_DIOINFO: {
struct dioattr da;
......@@ -703,7 +706,7 @@ xfs_ioctl(
case XFS_IOC_GETBMAP:
case XFS_IOC_GETBMAPA:
return xfs_ioc_getbmap(bdp, filp, cmd, arg);
return xfs_ioc_getbmap(bdp, filp, ioflags, cmd, arg);
case XFS_IOC_GETBMAPX:
return xfs_ioc_getbmapx(bdp, arg);
......@@ -865,6 +868,7 @@ xfs_ioc_space(
bhv_desc_t *bdp,
vnode_t *vp,
struct file *filp,
int ioflags,
unsigned int cmd,
unsigned long arg)
{
......@@ -886,7 +890,7 @@ xfs_ioc_space(
if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
attr_flags |= ATTR_NONBLOCK;
if (filp->f_mode & FINVIS)
if (ioflags & IO_INVIS)
attr_flags |= ATTR_DMI;
error = xfs_change_file_space(bdp, cmd, &bf, filp->f_pos,
......@@ -1153,6 +1157,7 @@ STATIC int
xfs_ioc_getbmap(
bhv_desc_t *bdp,
struct file *filp,
int ioflags,
unsigned int cmd,
unsigned long arg)
{
......@@ -1167,7 +1172,7 @@ xfs_ioc_getbmap(
return -XFS_ERROR(EINVAL);
iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0);
if (filp->f_mode & FINVIS)
if (ioflags & IO_INVIS)
iflags |= BMV_IF_NO_DMAPI_READ;
error = xfs_getbmap(bdp, &bm, (struct getbmap *)arg+1, iflags);
......
......@@ -386,9 +386,8 @@ linvfs_readlink(
uio.uio_segflg = UIO_USERSPACE;
uio.uio_resid = size;
uio.uio_iovcnt = 1;
uio.uio_fmode = 0;
VOP_READLINK(vp, &uio, NULL, error);
VOP_READLINK(vp, &uio, 0, NULL, error);
if (error)
return -error;
......@@ -433,10 +432,9 @@ linvfs_follow_link(
uio->uio_offset = 0;
uio->uio_segflg = UIO_SYSSPACE;
uio->uio_resid = MAXNAMELEN;
uio->uio_fmode = 0;
uio->uio_iovcnt = 1;
VOP_READLINK(vp, uio, NULL, error);
VOP_READLINK(vp, uio, 0, NULL, error);
if (error) {
kfree(uio);
kfree(link);
......
......@@ -61,6 +61,7 @@ extern struct inode_operations linvfs_dir_inode_operations;
extern struct inode_operations linvfs_symlink_inode_operations;
extern struct file_operations linvfs_file_operations;
extern struct file_operations linvfs_invis_file_operations;
extern struct file_operations linvfs_dir_operations;
extern struct address_space_operations linvfs_aops;
......
......@@ -195,8 +195,6 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
#define MAXPATHLEN 1024
#define FINVIS 0x0100 /* don't update timestamps - XFS */
#define MIN(a,b) (min(a,b))
#define MAX(a,b) (max(a,b))
#define howmany(x, y) (((x)+((y)-1))/(y))
......
......@@ -149,6 +149,7 @@ xfs_read(
const struct iovec *iovp,
unsigned int segs,
loff_t *offset,
int ioflags,
cred_t *credp)
{
struct file *file = iocb->ki_filp;
......@@ -159,8 +160,6 @@ xfs_read(
xfs_mount_t *mp;
vnode_t *vp;
unsigned long seg;
int direct = (file->f_flags & O_DIRECT);
int invisible = (file->f_mode & FINVIS);
ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp);
......@@ -183,7 +182,7 @@ xfs_read(
}
/* END copy & waste from filemap.c */
if (direct) {
if (ioflags & IO_ISDIRECT) {
pb_target_t *target =
(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
mp->m_rtdev_targp : mp->m_ddev_targp;
......@@ -214,7 +213,8 @@ xfs_read(
*/
xfs_ilock(ip, XFS_IOLOCK_SHARED);
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && !invisible) {
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
!(ioflags & IO_INVIS)) {
int error;
vrwlock_t locktype = VRWLOCK_READ;
......@@ -226,14 +226,13 @@ xfs_read(
}
}
/* We need to deal with the iovec case seperately here */
ret = __generic_file_aio_read(iocb, iovp, segs, offset);
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
if (ret > 0)
XFS_STATS_ADD(xs_read_bytes, ret);
if (!invisible)
if (likely(!(ioflags & IO_INVIS)))
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
return ret;
......@@ -244,6 +243,7 @@ xfs_sendfile(
bhv_desc_t *bdp,
struct file *filp,
loff_t *offset,
int ioflags,
size_t count,
read_actor_t actor,
void *target,
......@@ -254,7 +254,6 @@ xfs_sendfile(
xfs_inode_t *ip;
xfs_mount_t *mp;
vnode_t *vp;
int invisible = (filp->f_mode & FINVIS);
ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp);
......@@ -274,7 +273,9 @@ xfs_sendfile(
return -EIO;
xfs_ilock(ip, XFS_IOLOCK_SHARED);
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && !invisible) {
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
(!(ioflags & IO_INVIS))) {
vrwlock_t locktype = VRWLOCK_READ;
int error;
......@@ -289,8 +290,7 @@ xfs_sendfile(
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
XFS_STATS_ADD(xs_read_bytes, ret);
if (!invisible)
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
return ret;
}
......@@ -518,6 +518,7 @@ xfs_write(
const struct iovec *iovp,
unsigned int segs,
loff_t *offset,
int ioflags,
cred_t *credp)
{
struct file *file = iocb->ki_filp;
......@@ -532,8 +533,6 @@ xfs_write(
vnode_t *vp;
unsigned long seg;
int iolock;
int direct = (file->f_flags & O_DIRECT);
int invisible = (file->f_mode & FINVIS);
int eventsent = 0;
vrwlock_t locktype;
......@@ -569,7 +568,7 @@ xfs_write(
return -EIO;
}
if (direct) {
if (ioflags & IO_ISDIRECT) {
pb_target_t *target =
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
mp->m_rtdev_targp : mp->m_ddev_targp;
......@@ -586,6 +585,7 @@ xfs_write(
}
xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
isize = xip->i_d.di_size;
limit = XFS_MAXIOFFSET(mp);
......@@ -608,7 +608,7 @@ xfs_write(
}
if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
!invisible && !eventsent)) {
!(ioflags & IO_INVIS) && !eventsent)) {
loff_t savedsize = *offset;
xfs_iunlock(xip, XFS_ILOCK_EXCL);
......@@ -642,7 +642,7 @@ xfs_write(
*
* We must update xfs' times since revalidate will overcopy xfs.
*/
if (size && !invisible)
if (size && !(ioflags & IO_INVIS))
xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
/*
......@@ -654,7 +654,7 @@ xfs_write(
* to zero it out up to the new size.
*/
if (!direct && (*offset > isize && isize)) {
if (!(ioflags & IO_ISDIRECT) && (*offset > isize && isize)) {
error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, *offset,
isize, *offset + size);
if (error) {
......@@ -683,14 +683,15 @@ xfs_write(
}
retry:
if (direct) {
if (ioflags & IO_ISDIRECT) {
xfs_inval_cached_pages(vp, &xip->i_iocore, *offset, 1, 1);
}
ret = generic_file_aio_write_nolock(iocb, iovp, segs, offset);
if ((ret == -ENOSPC) &&
DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) && !invisible) {
DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) &&
!(ioflags & IO_INVIS)) {
xfs_rwunlock(bdp, locktype);
error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
......
......@@ -56,12 +56,12 @@ extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
xfs_fsize_t, xfs_fsize_t);
extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
const struct iovec *, unsigned int,
loff_t *, struct cred *);
loff_t *, int, struct cred *);
extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
const struct iovec *, unsigned int,
loff_t *, struct cred *);
loff_t *, int, struct cred *);
extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
loff_t *, size_t, read_actor_t,
loff_t *, int, size_t, read_actor_t,
void *, struct cred *);
extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int,
......
......@@ -373,7 +373,7 @@ STATIC int
init_inodecache( void )
{
linvfs_inode_cachep = kmem_cache_create("linvfs_icache",
sizeof(vnode_t), 0,
sizeof(vnode_t), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
......@@ -579,7 +579,7 @@ linvfs_freeze_fs(
if (sb->s_flags & MS_RDONLY)
return;
VFS_ROOT(vfsp, &vp, error);
VOP_IOCTL(vp, LINVFS_GET_IP(vp), NULL, XFS_IOC_FREEZE, 0, error);
VOP_IOCTL(vp, LINVFS_GET_IP(vp), NULL, 0, XFS_IOC_FREEZE, 0, error);
VN_RELE(vp);
}
......@@ -592,7 +592,7 @@ linvfs_unfreeze_fs(
int error;
VFS_ROOT(vfsp, &vp, error);
VOP_IOCTL(vp, LINVFS_GET_IP(vp), NULL, XFS_IOC_THAW, 0, error);
VOP_IOCTL(vp, LINVFS_GET_IP(vp), NULL, 0, XFS_IOC_THAW, 0, error);
VN_RELE(vp);
}
......
......@@ -155,9 +155,17 @@ extern u_short vttoif_tab[];
#define VMODIFIED 0x8 /* XFS inode state possibly differs */
/* to the Linux inode state. */
typedef enum vrwlock { VRWLOCK_NONE, VRWLOCK_READ,
VRWLOCK_WRITE, VRWLOCK_WRITE_DIRECT,
VRWLOCK_TRY_READ, VRWLOCK_TRY_WRITE } vrwlock_t;
/*
* Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
*/
typedef enum vrwlock {
VRWLOCK_NONE,
VRWLOCK_READ,
VRWLOCK_WRITE,
VRWLOCK_WRITE_DIRECT,
VRWLOCK_TRY_READ,
VRWLOCK_TRY_WRITE
} vrwlock_t;
/*
* Return values for VOP_INACTIVE. A return value of
......@@ -182,15 +190,15 @@ typedef enum vchange {
typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
const struct iovec *, unsigned int,
loff_t *, struct cred *);
loff_t *, int, struct cred *);
typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
const struct iovec *, unsigned int,
loff_t *, struct cred *);
loff_t *, int, struct cred *);
typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
loff_t *, size_t, read_actor_t,
loff_t *, int, size_t, read_actor_t,
void *, struct cred *);
typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
unsigned int, unsigned long);
int, unsigned int, unsigned long);
typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
struct cred *);
typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int,
......@@ -212,7 +220,8 @@ typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
int *);
typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *,
char *, vnode_t **, struct cred *);
typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, struct cred *);
typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
struct cred *);
typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
xfs_off_t, xfs_off_t);
typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *);
......@@ -284,12 +293,12 @@ typedef struct vnodeops {
*/
#define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op)
#define VOP_READ(vp,file,iov,segs,offset,cr,rv) \
rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,cr)
#define VOP_WRITE(vp,file,iov,segs,offset,cr,rv) \
rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,cr)
#define VOP_SENDFILE(vp,f,off,cnt,act,targ,cr,rv) \
rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,cnt,act,targ,cr)
#define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv) \
rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
#define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv) \
rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
#define VOP_OPEN(vp, cr, rv) \
......@@ -318,8 +327,8 @@ typedef struct vnodeops {
rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
#define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \
rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
#define VOP_READLINK(vp,uiop,cr,rv) \
rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,cr)
#define VOP_READLINK(vp,uiop,fl,cr,rv) \
rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr)
#define VOP_FSYNC(vp,f,cr,b,e,rv) \
rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
#define VOP_INACTIVE(vp, cr, rv) \
......@@ -366,15 +375,20 @@ typedef struct vnodeops {
*/
#define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \
rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt)
#define VOP_IOCTL(vp, inode, filp, cmd, arg, rv) \
rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,cmd,arg)
#define VOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv) \
rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg)
#define VOP_IFLUSH(vp, flags, rv) \
rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags)
/*
* Flags for VOP_IFLUSH call
* Flags for read/write calls - same values as IRIX
*/
#define IO_ISDIRECT 0x00004 /* bypass page cache */
#define IO_INVIS 0x00020 /* don't update inode timestamps */
/*
* Flags for VOP_IFLUSH call
*/
#define FLUSH_SYNC 1 /* wait for flush to complete */
#define FLUSH_INODE 2 /* flush the inode itself */
#define FLUSH_LOG 4 /* force the last log entry for
......
......@@ -78,7 +78,7 @@
#define SYMLINK_MAPS 2
extern int xfs_ioctl(bhv_desc_t *, struct inode *, struct file *,
unsigned int, unsigned long);
int, unsigned int, unsigned long);
/*
......@@ -992,6 +992,7 @@ STATIC int
xfs_readlink(
bhv_desc_t *bdp,
uio_t *uiop,
int ioflags,
cred_t *credp)
{
xfs_inode_t *ip;
......@@ -1033,7 +1034,7 @@ xfs_readlink(
goto error_return;
}
if (!(uiop->uio_fmode & FINVIS)) {
if (!(ioflags & IO_INVIS)) {
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
}
......
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