Message ID | 157270038074.4812.7980855544557488880.stgit@buzz (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2,1/3] fs: remove redundant cache invalidation after async direct-io write | expand |
On Sat 02-11-19 16:13:00, Konstantin Khlebnikov wrote: > This helper prints warning if direct I/O write failed to invalidate cache, > and set EIO at inode to warn usersapce about possible data corruption. > See also commit 5a9d929d6e13 ("iomap: report collisions between directio and > buffered writes to userspace"). > > Direct I/O is supported by non-disk filesystems, for example NFS. > Thus generic code needs this even in kernel without CONFIG_BLOCK. > > Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Looks good to me. You can add: Reviewed-by: Jan Kara <jack@suse.cz> Honza > --- > fs/direct-io.c | 21 --------------------- > include/linux/fs.h | 6 +++++- > mm/filemap.c | 21 +++++++++++++++++++++ > 3 files changed, 26 insertions(+), 22 deletions(-) > > diff --git a/fs/direct-io.c b/fs/direct-io.c > index 9329ced91f1d..0ec4f270139f 100644 > --- a/fs/direct-io.c > +++ b/fs/direct-io.c > @@ -220,27 +220,6 @@ static inline struct page *dio_get_page(struct dio *dio, > return dio->pages[sdio->head]; > } > > -/* > - * Warn about a page cache invalidation failure during a direct io write. > - */ > -void dio_warn_stale_pagecache(struct file *filp) > -{ > - static DEFINE_RATELIMIT_STATE(_rs, 86400 * HZ, DEFAULT_RATELIMIT_BURST); > - char pathname[128]; > - struct inode *inode = file_inode(filp); > - char *path; > - > - errseq_set(&inode->i_mapping->wb_err, -EIO); > - if (__ratelimit(&_rs)) { > - path = file_path(filp, pathname, sizeof(pathname)); > - if (IS_ERR(path)) > - path = "(unknown)"; > - pr_crit("Page cache invalidation failure on direct I/O. Possible data corruption due to collision with buffered I/O!\n"); > - pr_crit("File: %s PID: %d Comm: %.20s\n", path, current->pid, > - current->comm); > - } > -} > - > /* > * dio_complete() - called when all DIO BIO I/O has been completed > * > diff --git a/include/linux/fs.h b/include/linux/fs.h > index e0d909d35763..b4e4560d1c38 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -3153,7 +3153,6 @@ enum { > }; > > void dio_end_io(struct bio *bio); > -void dio_warn_stale_pagecache(struct file *filp); > > ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, > struct block_device *bdev, struct iov_iter *iter, > @@ -3198,6 +3197,11 @@ static inline void inode_dio_end(struct inode *inode) > wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); > } > > +/* > + * Warn about a page cache invalidation failure diring a direct I/O write. > + */ > +void dio_warn_stale_pagecache(struct file *filp); > + > extern void inode_set_flags(struct inode *inode, unsigned int flags, > unsigned int mask); > > diff --git a/mm/filemap.c b/mm/filemap.c > index 288e38199068..189b8f318da2 100644 > --- a/mm/filemap.c > +++ b/mm/filemap.c > @@ -3161,6 +3161,27 @@ int pagecache_write_end(struct file *file, struct address_space *mapping, > } > EXPORT_SYMBOL(pagecache_write_end); > > +/* > + * Warn about a page cache invalidation failure during a direct I/O write. > + */ > +void dio_warn_stale_pagecache(struct file *filp) > +{ > + static DEFINE_RATELIMIT_STATE(_rs, 86400 * HZ, DEFAULT_RATELIMIT_BURST); > + char pathname[128]; > + struct inode *inode = file_inode(filp); > + char *path; > + > + errseq_set(&inode->i_mapping->wb_err, -EIO); > + if (__ratelimit(&_rs)) { > + path = file_path(filp, pathname, sizeof(pathname)); > + if (IS_ERR(path)) > + path = "(unknown)"; > + pr_crit("Page cache invalidation failure on direct I/O. Possible data corruption due to collision with buffered I/O!\n"); > + pr_crit("File: %s PID: %d Comm: %.20s\n", path, current->pid, > + current->comm); > + } > +} > + > ssize_t > generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from) > { >
diff --git a/fs/direct-io.c b/fs/direct-io.c index 9329ced91f1d..0ec4f270139f 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -220,27 +220,6 @@ static inline struct page *dio_get_page(struct dio *dio, return dio->pages[sdio->head]; } -/* - * Warn about a page cache invalidation failure during a direct io write. - */ -void dio_warn_stale_pagecache(struct file *filp) -{ - static DEFINE_RATELIMIT_STATE(_rs, 86400 * HZ, DEFAULT_RATELIMIT_BURST); - char pathname[128]; - struct inode *inode = file_inode(filp); - char *path; - - errseq_set(&inode->i_mapping->wb_err, -EIO); - if (__ratelimit(&_rs)) { - path = file_path(filp, pathname, sizeof(pathname)); - if (IS_ERR(path)) - path = "(unknown)"; - pr_crit("Page cache invalidation failure on direct I/O. Possible data corruption due to collision with buffered I/O!\n"); - pr_crit("File: %s PID: %d Comm: %.20s\n", path, current->pid, - current->comm); - } -} - /* * dio_complete() - called when all DIO BIO I/O has been completed * diff --git a/include/linux/fs.h b/include/linux/fs.h index e0d909d35763..b4e4560d1c38 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3153,7 +3153,6 @@ enum { }; void dio_end_io(struct bio *bio); -void dio_warn_stale_pagecache(struct file *filp); ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, struct block_device *bdev, struct iov_iter *iter, @@ -3198,6 +3197,11 @@ static inline void inode_dio_end(struct inode *inode) wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); } +/* + * Warn about a page cache invalidation failure diring a direct I/O write. + */ +void dio_warn_stale_pagecache(struct file *filp); + extern void inode_set_flags(struct inode *inode, unsigned int flags, unsigned int mask); diff --git a/mm/filemap.c b/mm/filemap.c index 288e38199068..189b8f318da2 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3161,6 +3161,27 @@ int pagecache_write_end(struct file *file, struct address_space *mapping, } EXPORT_SYMBOL(pagecache_write_end); +/* + * Warn about a page cache invalidation failure during a direct I/O write. + */ +void dio_warn_stale_pagecache(struct file *filp) +{ + static DEFINE_RATELIMIT_STATE(_rs, 86400 * HZ, DEFAULT_RATELIMIT_BURST); + char pathname[128]; + struct inode *inode = file_inode(filp); + char *path; + + errseq_set(&inode->i_mapping->wb_err, -EIO); + if (__ratelimit(&_rs)) { + path = file_path(filp, pathname, sizeof(pathname)); + if (IS_ERR(path)) + path = "(unknown)"; + pr_crit("Page cache invalidation failure on direct I/O. Possible data corruption due to collision with buffered I/O!\n"); + pr_crit("File: %s PID: %d Comm: %.20s\n", path, current->pid, + current->comm); + } +} + ssize_t generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from) {
This helper prints warning if direct I/O write failed to invalidate cache, and set EIO at inode to warn usersapce about possible data corruption. See also commit 5a9d929d6e13 ("iomap: report collisions between directio and buffered writes to userspace"). Direct I/O is supported by non-disk filesystems, for example NFS. Thus generic code needs this even in kernel without CONFIG_BLOCK. Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> --- fs/direct-io.c | 21 --------------------- include/linux/fs.h | 6 +++++- mm/filemap.c | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 22 deletions(-)