Skip to content

Commit 9eb90f4

Browse files
author
Trond Myklebust
committed
NFS: Serialise O_DIRECT i/o and truncate()
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 <[email protected]>
1 parent b2036bb commit 9eb90f4

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
@@ -768,8 +768,10 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
768768
trace_nfs_setattr_enter(inode);
769769

770770
/* Write all dirty data */
771-
if (S_ISREG(inode->i_mode))
771+
if (S_ISREG(inode->i_mode)) {
772+
nfs_file_block_o_direct(NFS_I(inode));
772773
nfs_sync_inode(inode);
774+
}
773775

774776
fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
775777
if (fattr == NULL) {

fs/nfs/internal.h

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

535+
/* Must be called with exclusively locked inode->i_rwsem */
536+
static inline void nfs_file_block_o_direct(struct nfs_inode *nfsi)
537+
{
538+
if (test_bit(NFS_INO_ODIRECT, &nfsi->flags)) {
539+
clear_bit(NFS_INO_ODIRECT, &nfsi->flags);
540+
inode_dio_wait(&nfsi->vfs_inode);
541+
}
542+
}
543+
544+
535545
/* namespace.c */
536546
#define NFS_PATH_CANONICAL 1
537547
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)