Signed-off-by: Andrew Morton --- fs/ext4/ext4.h | 1 + fs/ext4/file.c | 19 ++++++++++++++++++- fs/ext4/inode.c | 11 +++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff -puN fs/ext4/ext4.h~ext4-mm-ext4-page-mkwrite fs/ext4/ext4.h --- a/fs/ext4/ext4.h~ext4-mm-ext4-page-mkwrite +++ a/fs/ext4/ext4.h @@ -1049,6 +1049,7 @@ extern void ext4_set_aops(struct inode * extern int ext4_writepage_trans_blocks(struct inode *); extern int ext4_block_truncate_page(handle_t *handle, struct page *page, struct address_space *mapping, loff_t from); +extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page); /* ioctl.c */ extern long ext4_ioctl(struct file *, unsigned int, unsigned long); diff -puN fs/ext4/file.c~ext4-mm-ext4-page-mkwrite fs/ext4/file.c --- a/fs/ext4/file.c~ext4-mm-ext4-page-mkwrite +++ a/fs/ext4/file.c @@ -123,6 +123,23 @@ force_commit: return ret; } +static struct vm_operations_struct ext4_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = ext4_page_mkwrite, +}; + +static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct address_space *mapping = file->f_mapping; + + if (!mapping->a_ops->readpage) + return -ENOEXEC; + file_accessed(file); + vma->vm_ops = &ext4_file_vm_ops; + vma->vm_flags |= VM_CAN_NONLINEAR; + return 0; +} + const struct file_operations ext4_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, @@ -133,7 +150,7 @@ const struct file_operations ext4_file_o #ifdef CONFIG_COMPAT .compat_ioctl = ext4_compat_ioctl, #endif - .mmap = generic_file_mmap, + .mmap = ext4_file_mmap, .open = generic_file_open, .release = ext4_release_file, .fsync = ext4_sync_file, diff -puN fs/ext4/inode.c~ext4-mm-ext4-page-mkwrite fs/ext4/inode.c --- a/fs/ext4/inode.c~ext4-mm-ext4-page-mkwrite +++ a/fs/ext4/inode.c @@ -3510,3 +3510,14 @@ int ext4_change_inode_journal_flag(struc return err; } + +int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page) +{ + /* + * if ext4_get_block resulted in a split of an uninitialized extent, + * in file system full case, we will have to take the journal write + * access and zero out the page. The journal handle get initialized + * in ext4_get_block. + */ + return block_page_mkwrite(vma, page, ext4_get_block); +} _