Skip to content

Commit 320a095

Browse files
Trond Myklebustgregkh
authored andcommitted
NFS: Serialise O_DIRECT i/o and truncate()
[ Upstream commit 9eb90f4 ] Ensure that all O_DIRECT reads and writes are complete, and prevent the initiation of new i/o until the setattr operation that will truncate the file is complete. Fixes: a5864c9 ("NFS: Do not serialise O_DIRECT reads and writes") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 275d9fd commit 320a095

File tree

3 files changed

+15
-12
lines changed

3 files changed

+15
-12
lines changed

fs/nfs/inode.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,8 +645,10 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
645645
trace_nfs_setattr_enter(inode);
646646

647647
/* Write all dirty data */
648-
if (S_ISREG(inode->i_mode))
648+
if (S_ISREG(inode->i_mode)) {
649+
nfs_file_block_o_direct(NFS_I(inode));
649650
nfs_sync_inode(inode);
651+
}
650652

651653
fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
652654
if (fattr == NULL) {

fs/nfs/internal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,16 @@ static inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi)
474474
return test_bit(NFS_INO_ODIRECT, &nfsi->flags) == 0;
475475
}
476476

477+
/* Must be called with exclusively locked inode->i_rwsem */
478+
static inline void nfs_file_block_o_direct(struct nfs_inode *nfsi)
479+
{
480+
if (test_bit(NFS_INO_ODIRECT, &nfsi->flags)) {
481+
clear_bit(NFS_INO_ODIRECT, &nfsi->flags);
482+
inode_dio_wait(&nfsi->vfs_inode);
483+
}
484+
}
485+
486+
477487
/* namespace.c */
478488
#define NFS_PATH_CANONICAL 1
479489
extern char *nfs_path(char **p, struct dentry *dentry,

fs/nfs/io.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@
1414

1515
#include "internal.h"
1616

17-
/* Call with exclusively locked inode->i_rwsem */
18-
static void nfs_block_o_direct(struct nfs_inode *nfsi, struct inode *inode)
19-
{
20-
if (test_bit(NFS_INO_ODIRECT, &nfsi->flags)) {
21-
clear_bit(NFS_INO_ODIRECT, &nfsi->flags);
22-
inode_dio_wait(inode);
23-
}
24-
}
25-
2617
/**
2718
* nfs_start_io_read - declare the file is being used for buffered reads
2819
* @inode: file inode
@@ -57,7 +48,7 @@ nfs_start_io_read(struct inode *inode)
5748
err = down_write_killable(&inode->i_rwsem);
5849
if (err)
5950
return err;
60-
nfs_block_o_direct(nfsi, inode);
51+
nfs_file_block_o_direct(nfsi);
6152
downgrade_write(&inode->i_rwsem);
6253

6354
return 0;
@@ -90,7 +81,7 @@ nfs_start_io_write(struct inode *inode)
9081

9182
err = down_write_killable(&inode->i_rwsem);
9283
if (!err)
93-
nfs_block_o_direct(NFS_I(inode), inode);
84+
nfs_file_block_o_direct(NFS_I(inode));
9485
return err;
9586
}
9687

0 commit comments

Comments
 (0)