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: a5864c999d
("NFS: Do not serialise O_DIRECT reads and writes")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
b2036bb651
commit
9eb90f4354
|
@ -768,8 +768,10 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
|||
trace_nfs_setattr_enter(inode);
|
||||
|
||||
/* Write all dirty data */
|
||||
if (S_ISREG(inode->i_mode))
|
||||
if (S_ISREG(inode->i_mode)) {
|
||||
nfs_file_block_o_direct(NFS_I(inode));
|
||||
nfs_sync_inode(inode);
|
||||
}
|
||||
|
||||
fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
|
||||
if (fattr == NULL) {
|
||||
|
|
|
@ -532,6 +532,16 @@ static inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi)
|
|||
return test_bit(NFS_INO_ODIRECT, &nfsi->flags) == 0;
|
||||
}
|
||||
|
||||
/* Must be called with exclusively locked inode->i_rwsem */
|
||||
static inline void nfs_file_block_o_direct(struct nfs_inode *nfsi)
|
||||
{
|
||||
if (test_bit(NFS_INO_ODIRECT, &nfsi->flags)) {
|
||||
clear_bit(NFS_INO_ODIRECT, &nfsi->flags);
|
||||
inode_dio_wait(&nfsi->vfs_inode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* namespace.c */
|
||||
#define NFS_PATH_CANONICAL 1
|
||||
extern char *nfs_path(char **p, struct dentry *dentry,
|
||||
|
|
13
fs/nfs/io.c
13
fs/nfs/io.c
|
@ -14,15 +14,6 @@
|
|||
|
||||
#include "internal.h"
|
||||
|
||||
/* Call with exclusively locked inode->i_rwsem */
|
||||
static void nfs_block_o_direct(struct nfs_inode *nfsi, struct inode *inode)
|
||||
{
|
||||
if (test_bit(NFS_INO_ODIRECT, &nfsi->flags)) {
|
||||
clear_bit(NFS_INO_ODIRECT, &nfsi->flags);
|
||||
inode_dio_wait(inode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_start_io_read - declare the file is being used for buffered reads
|
||||
* @inode: file inode
|
||||
|
@ -57,7 +48,7 @@ nfs_start_io_read(struct inode *inode)
|
|||
err = down_write_killable(&inode->i_rwsem);
|
||||
if (err)
|
||||
return err;
|
||||
nfs_block_o_direct(nfsi, inode);
|
||||
nfs_file_block_o_direct(nfsi);
|
||||
downgrade_write(&inode->i_rwsem);
|
||||
|
||||
return 0;
|
||||
|
@ -90,7 +81,7 @@ nfs_start_io_write(struct inode *inode)
|
|||
|
||||
err = down_write_killable(&inode->i_rwsem);
|
||||
if (!err)
|
||||
nfs_block_o_direct(NFS_I(inode), inode);
|
||||
nfs_file_block_o_direct(NFS_I(inode));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue