mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 11:29:36 +03:00
zfs does not honor NFS sync write semantics
The linux kernel's nfsd implementation use RWF_SYNC to determine if the write is synchronous or not. This flag is used to set the kernel's I/O control block flags. Unfortunately, ZFS was not updated to inspect these flags so NFS sync writes were not being honored. This change maps the IOCB_* flags to the ZFS equivalent. Reviewed-by: Don Brady <don.brady@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: George Wilson <george.wilson@delphix.com> Closes #8474 Closes #8452 Closes #8486
This commit is contained in:
parent
1118f99449
commit
b1b94e9644
@ -216,6 +216,30 @@ zpl_aio_fsync(struct kiocb *kiocb, int datasync)
|
|||||||
#error "Unsupported fops->fsync() implementation"
|
#error "Unsupported fops->fsync() implementation"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
zfs_io_flags(struct kiocb *kiocb)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
#if defined(IOCB_DSYNC)
|
||||||
|
if (kiocb->ki_flags & IOCB_DSYNC)
|
||||||
|
flags |= FDSYNC;
|
||||||
|
#endif
|
||||||
|
#if defined(IOCB_SYNC)
|
||||||
|
if (kiocb->ki_flags & IOCB_SYNC)
|
||||||
|
flags |= FSYNC;
|
||||||
|
#endif
|
||||||
|
#if defined(IOCB_APPEND)
|
||||||
|
if (kiocb->ki_flags & IOCB_APPEND)
|
||||||
|
flags |= FAPPEND;
|
||||||
|
#endif
|
||||||
|
#if defined(IOCB_DIRECT)
|
||||||
|
if (kiocb->ki_flags & IOCB_DIRECT)
|
||||||
|
flags |= FDIRECT;
|
||||||
|
#endif
|
||||||
|
return (flags);
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
zpl_read_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count,
|
zpl_read_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count,
|
||||||
unsigned long nr_segs, loff_t *ppos, uio_seg_t segment, int flags,
|
unsigned long nr_segs, loff_t *ppos, uio_seg_t segment, int flags,
|
||||||
@ -266,10 +290,12 @@ zpl_iter_read_common(struct kiocb *kiocb, const struct iovec *iovp,
|
|||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
struct file *filp = kiocb->ki_filp;
|
struct file *filp = kiocb->ki_filp;
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
|
unsigned int f_flags = filp->f_flags;
|
||||||
|
|
||||||
|
f_flags |= zfs_io_flags(kiocb);
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
read = zpl_read_common_iovec(filp->f_mapping->host, iovp, count,
|
read = zpl_read_common_iovec(filp->f_mapping->host, iovp, count,
|
||||||
nr_segs, &kiocb->ki_pos, seg, filp->f_flags, cr, skip);
|
nr_segs, &kiocb->ki_pos, seg, f_flags, cr, skip);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
|
|
||||||
file_accessed(filp);
|
file_accessed(filp);
|
||||||
@ -362,10 +388,12 @@ zpl_iter_write_common(struct kiocb *kiocb, const struct iovec *iovp,
|
|||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
struct file *filp = kiocb->ki_filp;
|
struct file *filp = kiocb->ki_filp;
|
||||||
ssize_t wrote;
|
ssize_t wrote;
|
||||||
|
unsigned int f_flags = filp->f_flags;
|
||||||
|
|
||||||
|
f_flags |= zfs_io_flags(kiocb);
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
wrote = zpl_write_common_iovec(filp->f_mapping->host, iovp, count,
|
wrote = zpl_write_common_iovec(filp->f_mapping->host, iovp, count,
|
||||||
nr_segs, &kiocb->ki_pos, seg, filp->f_flags, cr, skip);
|
nr_segs, &kiocb->ki_pos, seg, f_flags, cr, skip);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
|
|
||||||
return (wrote);
|
return (wrote);
|
||||||
|
Loading…
Reference in New Issue
Block a user