mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
gfs2: Don't update inode timestamps for direct writes
During direct reads and writes, the caller is holding the inode glock in deferred mode, which doesn't allow metadata updates. However, a previous change caused callers to update the inode modification time before carrying out direct writes, which caused the inode glock to be converted to exclusive mode for the timestamp update, only to be immediately converted back to deferred mode for the direct write. This locks out other direct readers and writers and wreaks havoc on performance. Fix that by reverting to not updating the inode modification time for direct writes. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
parent
21d9067efc
commit
089f4eb003
@ -1120,14 +1120,16 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = file_update_time(file);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
if (iocb->ki_flags & IOCB_DIRECT) {
|
||||
struct address_space *mapping = file->f_mapping;
|
||||
ssize_t buffered, ret2;
|
||||
|
||||
/*
|
||||
* Note that under direct I/O, we don't allow and inode
|
||||
* timestamp updates, so we're not calling file_update_time()
|
||||
* here.
|
||||
*/
|
||||
|
||||
ret = gfs2_file_direct_write(iocb, from, &gh);
|
||||
if (ret < 0 || !iov_iter_count(from))
|
||||
goto out_unlock;
|
||||
@ -1154,6 +1156,10 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
if (!ret || ret2 > 0)
|
||||
ret += ret2;
|
||||
} else {
|
||||
ret = file_update_time(file);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = gfs2_file_buffered_write(iocb, from, &gh);
|
||||
if (likely(ret > 0))
|
||||
ret = generic_write_sync(iocb, ret);
|
||||
|
Loading…
Reference in New Issue
Block a user