mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
NFS: Add support for eager writes
Support eager writing to the server, meaning that we write the data to cache on the server, and wait for that to complete. This ensures that we see ENOSPC errors immediately. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
75cfb200cd
commit
ed7bcdb374
@ -606,8 +606,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
|
|||||||
{
|
{
|
||||||
struct file *file = iocb->ki_filp;
|
struct file *file = iocb->ki_filp;
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
unsigned long written = 0;
|
unsigned int mntflags = NFS_SERVER(inode)->flags;
|
||||||
ssize_t result;
|
ssize_t result, written;
|
||||||
errseq_t since;
|
errseq_t since;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -648,6 +648,21 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
|
|||||||
|
|
||||||
written = result;
|
written = result;
|
||||||
iocb->ki_pos += written;
|
iocb->ki_pos += written;
|
||||||
|
|
||||||
|
if (mntflags & NFS_MOUNT_WRITE_EAGER) {
|
||||||
|
result = filemap_fdatawrite_range(file->f_mapping,
|
||||||
|
iocb->ki_pos - written,
|
||||||
|
iocb->ki_pos - 1);
|
||||||
|
if (result < 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (mntflags & NFS_MOUNT_WRITE_WAIT) {
|
||||||
|
result = filemap_fdatawait_range(file->f_mapping,
|
||||||
|
iocb->ki_pos - written,
|
||||||
|
iocb->ki_pos - 1);
|
||||||
|
if (result < 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
result = generic_write_sync(iocb, written);
|
result = generic_write_sync(iocb, written);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -712,16 +712,23 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
|
|||||||
{
|
{
|
||||||
struct inode *inode = mapping->host;
|
struct inode *inode = mapping->host;
|
||||||
struct nfs_pageio_descriptor pgio;
|
struct nfs_pageio_descriptor pgio;
|
||||||
struct nfs_io_completion *ioc;
|
struct nfs_io_completion *ioc = NULL;
|
||||||
|
unsigned int mntflags = NFS_SERVER(inode)->flags;
|
||||||
|
int priority = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
|
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
|
||||||
|
|
||||||
ioc = nfs_io_completion_alloc(GFP_KERNEL);
|
if (!(mntflags & NFS_MOUNT_WRITE_EAGER) || wbc->for_kupdate ||
|
||||||
if (ioc)
|
wbc->for_background || wbc->for_sync || wbc->for_reclaim) {
|
||||||
nfs_io_completion_init(ioc, nfs_io_completion_commit, inode);
|
ioc = nfs_io_completion_alloc(GFP_KERNEL);
|
||||||
|
if (ioc)
|
||||||
|
nfs_io_completion_init(ioc, nfs_io_completion_commit,
|
||||||
|
inode);
|
||||||
|
priority = wb_priority(wbc);
|
||||||
|
}
|
||||||
|
|
||||||
nfs_pageio_init_write(&pgio, inode, wb_priority(wbc), false,
|
nfs_pageio_init_write(&pgio, inode, priority, false,
|
||||||
&nfs_async_write_completion_ops);
|
&nfs_async_write_completion_ops);
|
||||||
pgio.pg_io_completion = ioc;
|
pgio.pg_io_completion = ioc;
|
||||||
err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
|
err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
|
||||||
|
@ -153,6 +153,8 @@ struct nfs_server {
|
|||||||
#define NFS_MOUNT_LOCAL_FCNTL 0x200000
|
#define NFS_MOUNT_LOCAL_FCNTL 0x200000
|
||||||
#define NFS_MOUNT_SOFTERR 0x400000
|
#define NFS_MOUNT_SOFTERR 0x400000
|
||||||
#define NFS_MOUNT_SOFTREVAL 0x800000
|
#define NFS_MOUNT_SOFTREVAL 0x800000
|
||||||
|
#define NFS_MOUNT_WRITE_EAGER 0x01000000
|
||||||
|
#define NFS_MOUNT_WRITE_WAIT 0x02000000
|
||||||
|
|
||||||
unsigned int caps; /* server capabilities */
|
unsigned int caps; /* server capabilities */
|
||||||
unsigned int rsize; /* read size */
|
unsigned int rsize; /* read size */
|
||||||
|
Loading…
Reference in New Issue
Block a user