Implement individual lock for SEEK_END for ext4 which directly calls
generic_file_llseek_size().

Signed-off-by: Eiichi Tsukata <de...@etsukata.com>
---
 fs/ext4/file.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 69d65d49837b..6479f3066043 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -477,6 +477,16 @@ loff_t ext4_llseek(struct file *file, loff_t offset, int 
whence)
        default:
                return generic_file_llseek_size(file, offset, whence,
                                                maxbytes, i_size_read(inode));
+       case SEEK_END:
+               /*
+                * protects against inode size race with write so that llseek
+                * doesn't see inode size being updated in generic_perform_write
+                */
+               inode_lock_shared(inode);
+               offset = generic_file_llseek_size(file, offset, whence,
+                                                 maxbytes, i_size_read(inode));
+               inode_unlock_shared(inode);
+               return offset;
        case SEEK_HOLE:
                inode_lock_shared(inode);
                offset = iomap_seek_hole(inode, offset, &ext4_iomap_ops);
-- 
2.19.1

Reply via email to