| From 63dc7a14e1958bcdc7b56625d9cfbc533ade5159 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sun, 28 Mar 2021 18:17:14 -0400 |
| Subject: NFSv4.2: Always flush out writes in nfs42_proc_fallocate() |
| |
| From: Trond Myklebust <trond.myklebust@hammerspace.com> |
| |
| [ Upstream commit 99f23783224355e7022ceea9b8d9f62c0fd01bd8 ] |
| |
| Whether we're allocating or delallocating space, we should flush out the |
| pending writes in order to avoid races with attribute updates. |
| |
| Fixes: 1e564d3dbd68 ("NFSv4.2: Fix a race in nfs42_proc_deallocate()") |
| Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/nfs/nfs42proc.c | 16 +++++++++------- |
| 1 file changed, 9 insertions(+), 7 deletions(-) |
| |
| diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c |
| index 52d8cc253a2b..948a4c69687c 100644 |
| --- a/fs/nfs/nfs42proc.c |
| +++ b/fs/nfs/nfs42proc.c |
| @@ -90,7 +90,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, |
| static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, |
| loff_t offset, loff_t len) |
| { |
| - struct nfs_server *server = NFS_SERVER(file_inode(filep)); |
| + struct inode *inode = file_inode(filep); |
| + struct nfs_server *server = NFS_SERVER(inode); |
| struct nfs4_exception exception = { }; |
| struct nfs_lock_context *lock; |
| int err; |
| @@ -99,9 +100,13 @@ static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, |
| if (IS_ERR(lock)) |
| return PTR_ERR(lock); |
| |
| - exception.inode = file_inode(filep); |
| + exception.inode = inode; |
| exception.state = lock->open_context->state; |
| |
| + err = nfs_sync_inode(inode); |
| + if (err) |
| + goto out; |
| + |
| do { |
| err = _nfs42_proc_fallocate(msg, filep, lock, offset, len); |
| if (err == -ENOTSUPP) { |
| @@ -110,7 +115,7 @@ static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, |
| } |
| err = nfs4_handle_exception(server, err, &exception); |
| } while (exception.retry); |
| - |
| +out: |
| nfs_put_lock_context(lock); |
| return err; |
| } |
| @@ -148,16 +153,13 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len) |
| return -EOPNOTSUPP; |
| |
| inode_lock(inode); |
| - err = nfs_sync_inode(inode); |
| - if (err) |
| - goto out_unlock; |
| |
| err = nfs42_proc_fallocate(&msg, filep, offset, len); |
| if (err == 0) |
| truncate_pagecache_range(inode, offset, (offset + len) -1); |
| if (err == -EOPNOTSUPP) |
| NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE; |
| -out_unlock: |
| + |
| inode_unlock(inode); |
| return err; |
| } |
| -- |
| 2.30.2 |
| |