linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ext2: implement ->page_mkwrite
@ 2020-12-18 13:27 Chengguang Xu
  2020-12-19 23:32 ` kernel test robot
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Chengguang Xu @ 2020-12-18 13:27 UTC (permalink / raw)
  To: jack; +Cc: linux-ext4, Chengguang Xu

Currently ext2 uses generic mmap operations for non DAX file and
filemap_page_mkwrite() does not check the block allocation for
shared writable mmapped area on pagefault. In some cases like
disk space exhaustion or disk quota limitation, it will cause silent
data loss. This patch tries to check and do block preallocation on
pagefault if necessary and explicitly return error to user when
allocation failure.

Signed-off-by: Chengguang Xu <cgxu519@mykernel.net>
---
 fs/ext2/file.c | 40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 96044f5dbc0e..a34119415ef1 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -25,10 +25,34 @@
 #include <linux/quotaops.h>
 #include <linux/iomap.h>
 #include <linux/uio.h>
+#include <linux/buffer_head.h>
 #include "ext2.h"
 #include "xattr.h"
 #include "acl.h"
 
+vm_fault_t ext2_page_mkwrite(struct vm_fault *vmf)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	struct inode *inode = file_inode(vma->vm_file);
+	int err;
+
+	if (unlikely(IS_IMMUTABLE(inode)))
+		return VM_FAULT_SIGBUS;
+
+	sb_start_pagefault(inode->i_sb);
+	file_update_time(vma->vm_file);
+	err = block_page_mkwrite(vma, vmf, ext2_get_block);
+	sb_end_pagefault(inode->i_sb);
+
+	return block_page_mkwrite_return(err);
+}
+
+const struct vm_operations_struct ext2_vm_ops = {
+	.fault		= filemap_fault,
+	.map_pages	= filemap_map_pages,
+	.page_mkwrite	= ext2_page_mkwrite,
+};
+
 #ifdef CONFIG_FS_DAX
 static ssize_t ext2_dax_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
@@ -123,15 +147,23 @@ static const struct vm_operations_struct ext2_dax_vm_ops = {
 
 static int ext2_file_mmap(struct file *file, struct vm_area_struct *vma)
 {
+	file_accessed(file);
 	if (!IS_DAX(file_inode(file)))
-		return generic_file_mmap(file, vma);
+		vma->vm_ops = &ext2_vm_ops;
+	else
+		vma->vm_ops = &ext2_dax_vm_ops;
 
-	file_accessed(file);
-	vma->vm_ops = &ext2_dax_vm_ops;
 	return 0;
 }
+
 #else
-#define ext2_file_mmap	generic_file_mmap
+static int ext2_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	file_accessed(file);
+	vma->vm_ops = &ext2_vm_ops;
+	return 0;
+}
+
 #endif
 
 /*
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-01-05 17:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-18 13:27 [PATCH] ext2: implement ->page_mkwrite Chengguang Xu
2020-12-19 23:32 ` kernel test robot
2020-12-26 23:54 ` kernel test robot
2020-12-26 23:54 ` [RFC PATCH] ext2: ext2_page_mkwrite() can be static kernel test robot
2021-01-05 17:53 ` [PATCH] ext2: implement ->page_mkwrite Jan Kara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).