NFS: Ensure that setattr and getattr wait for O_DIRECT write completion
Use the same mechanism as the block devices are using, but move the helper functions from fs/direct-io.c into fs/inode.c to remove the dependency on CONFIG_BLOCK. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Fred Isaman <iisaman@netapp.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
2d117403b3
commit
1d59d61f60
47
fs/inode.c
47
fs/inode.c
@@ -1748,3 +1748,50 @@ bool inode_owner_or_capable(const struct inode *inode)
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(inode_owner_or_capable);
|
||||
|
||||
/*
|
||||
* Direct i/o helper functions
|
||||
*/
|
||||
static void __inode_dio_wait(struct inode *inode)
|
||||
{
|
||||
wait_queue_head_t *wq = bit_waitqueue(&inode->i_state, __I_DIO_WAKEUP);
|
||||
DEFINE_WAIT_BIT(q, &inode->i_state, __I_DIO_WAKEUP);
|
||||
|
||||
do {
|
||||
prepare_to_wait(wq, &q.wait, TASK_UNINTERRUPTIBLE);
|
||||
if (atomic_read(&inode->i_dio_count))
|
||||
schedule();
|
||||
} while (atomic_read(&inode->i_dio_count));
|
||||
finish_wait(wq, &q.wait);
|
||||
}
|
||||
|
||||
/**
|
||||
* inode_dio_wait - wait for outstanding DIO requests to finish
|
||||
* @inode: inode to wait for
|
||||
*
|
||||
* Waits for all pending direct I/O requests to finish so that we can
|
||||
* proceed with a truncate or equivalent operation.
|
||||
*
|
||||
* Must be called under a lock that serializes taking new references
|
||||
* to i_dio_count, usually by inode->i_mutex.
|
||||
*/
|
||||
void inode_dio_wait(struct inode *inode)
|
||||
{
|
||||
if (atomic_read(&inode->i_dio_count))
|
||||
__inode_dio_wait(inode);
|
||||
}
|
||||
EXPORT_SYMBOL(inode_dio_wait);
|
||||
|
||||
/*
|
||||
* inode_dio_done - signal finish of a direct I/O requests
|
||||
* @inode: inode the direct I/O happens on
|
||||
*
|
||||
* This is called once we've finished processing a direct I/O request,
|
||||
* and is used to wake up callers waiting for direct I/O to be quiesced.
|
||||
*/
|
||||
void inode_dio_done(struct inode *inode)
|
||||
{
|
||||
if (atomic_dec_and_test(&inode->i_dio_count))
|
||||
wake_up_bit(&inode->i_state, __I_DIO_WAKEUP);
|
||||
}
|
||||
EXPORT_SYMBOL(inode_dio_done);
|
||||
|
Reference in New Issue
Block a user