Linux-Fsdevel Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/7] Switch to page_mkwrite_check_truncate
@ 2020-02-13 20:24 Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 1/7] fs: Un-inline page_mkwrite_check_truncate Andreas Gruenbacher
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-13 20:24 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher

Hi,

Darrick ended up not merge these changes through the xfs tree, so could
you please pick them up and put them in your trees for the next merge
window?  Luckily the changes are all independend of each other.

Thanks,
Andreas

Andreas Gruenbacher (7):
  fs: Un-inline page_mkwrite_check_truncate
  fs: Switch to page_mkwrite_check_truncate in block_page_mkwrite
  ubifs: Switch to page_mkwrite_check_truncate in ubifs_vm_page_mkwrite
  ext4: Switch to page_mkwrite_check_truncate in ext4_page_mkwrite
  f2fs: Switch to page_mkwrite_check_truncate in f2fs_vm_page_mkwrite
  ceph: Switch to page_mkwrite_check_truncate in ceph_page_mkwrite
  btrfs: Switch to page_mkwrite_check_truncate in btrfs_page_mkwrite

 fs/btrfs/inode.c        | 16 +++++-----------
 fs/buffer.c             | 16 +++-------------
 fs/ceph/addr.c          |  2 +-
 fs/ext4/inode.c         | 15 ++++-----------
 fs/f2fs/file.c          | 19 +++++++------------
 fs/ubifs/file.c         |  3 +--
 include/linux/pagemap.h | 28 +---------------------------
 mm/filemap.c            | 28 ++++++++++++++++++++++++++++
 8 files changed, 50 insertions(+), 77 deletions(-)

-- 
2.24.1


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

* [PATCH 1/7] fs: Un-inline page_mkwrite_check_truncate
  2020-02-13 20:24 [PATCH 0/7] Switch to page_mkwrite_check_truncate Andreas Gruenbacher
@ 2020-02-13 20:24 ` Andreas Gruenbacher
  2020-02-14 15:11   ` Jan Kara
  2020-02-14 20:10   ` [PATCH v2] " Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 2/7] fs: Switch to page_mkwrite_check_truncate in block_page_mkwrite Andreas Gruenbacher
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-13 20:24 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher, Jan Kara

Per review comments from Jan and Ted, un-inline page_mkwrite_check_truncate
and move it to mm/filemap.c.  This function doesn't seem worth inlining.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Theodore Y. Ts'o <tytso@mit.edu>
---
 include/linux/pagemap.h | 28 +---------------------------
 mm/filemap.c            | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index ccb14b6a16b5..6c9c5b88924d 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -636,32 +636,6 @@ static inline unsigned long dir_pages(struct inode *inode)
 			       PAGE_SHIFT;
 }
 
-/**
- * page_mkwrite_check_truncate - check if page was truncated
- * @page: the page to check
- * @inode: the inode to check the page against
- *
- * Returns the number of bytes in the page up to EOF,
- * or -EFAULT if the page was truncated.
- */
-static inline int page_mkwrite_check_truncate(struct page *page,
-					      struct inode *inode)
-{
-	loff_t size = i_size_read(inode);
-	pgoff_t index = size >> PAGE_SHIFT;
-	int offset = offset_in_page(size);
-
-	if (page->mapping != inode->i_mapping)
-		return -EFAULT;
-
-	/* page is wholly inside EOF */
-	if (page->index < index)
-		return PAGE_SIZE;
-	/* page is wholly past EOF */
-	if (page->index > index || !offset)
-		return -EFAULT;
-	/* page is partially inside EOF */
-	return offset;
-}
+int page_mkwrite_check_truncate(struct page *page, struct inode *inode);
 
 #endif /* _LINUX_PAGEMAP_H */
diff --git a/mm/filemap.c b/mm/filemap.c
index 1784478270e1..edcb4a8a6121 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2678,6 +2678,34 @@ const struct vm_operations_struct generic_file_vm_ops = {
 	.page_mkwrite	= filemap_page_mkwrite,
 };
 
+/**
+ * page_mkwrite_check_truncate - check if page was truncated
+ * @page: the page to check
+ * @inode: the inode to check the page against
+ *
+ * Returns the number of bytes in the page up to EOF,
+ * or -EFAULT if the page was truncated.
+ */
+int page_mkwrite_check_truncate(struct page *page, struct inode *inode)
+{
+	loff_t size = i_size_read(inode);
+	pgoff_t index = size >> PAGE_SHIFT;
+	int offset = offset_in_page(size);
+
+	if (page->mapping != inode->i_mapping)
+		return -EFAULT;
+
+	/* page is wholly inside EOF */
+	if (page->index < index)
+		return PAGE_SIZE;
+	/* page is wholly past EOF */
+	if (page->index > index || !offset)
+		return -EFAULT;
+	/* page is partially inside EOF */
+	return offset;
+}
+EXPORT_SYMBOL(page_mkwrite_check_truncate);
+
 /* This is used for a general mmap of a disk file */
 
 int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
-- 
2.24.1


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

* [PATCH 2/7] fs: Switch to page_mkwrite_check_truncate in block_page_mkwrite
  2020-02-13 20:24 [PATCH 0/7] Switch to page_mkwrite_check_truncate Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 1/7] fs: Un-inline page_mkwrite_check_truncate Andreas Gruenbacher
@ 2020-02-13 20:24 ` Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 3/7] ubifs: Switch to page_mkwrite_check_truncate in ubifs_vm_page_mkwrite Andreas Gruenbacher
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-13 20:24 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher

Use the "page has been truncated" logic in page_mkwrite_check_truncate
instead of reimplementing it here.  Other than with the existing code,
fail with -EFAULT / VM_FAULT_NOPAGE when page_offset(page) == size here
as well, as should be expected.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 fs/buffer.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index b8d28370cfd7..31a9a02878a2 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2499,23 +2499,13 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 	struct page *page = vmf->page;
 	struct inode *inode = file_inode(vma->vm_file);
 	unsigned long end;
-	loff_t size;
 	int ret;
 
 	lock_page(page);
-	size = i_size_read(inode);
-	if ((page->mapping != inode->i_mapping) ||
-	    (page_offset(page) > size)) {
-		/* We overload EFAULT to mean page got truncated */
-		ret = -EFAULT;
+	ret = page_mkwrite_check_truncate(page, inode);
+	if (ret < 0)
 		goto out_unlock;
-	}
-
-	/* page is wholly or partially inside EOF */
-	if (((page->index + 1) << PAGE_SHIFT) > size)
-		end = size & ~PAGE_MASK;
-	else
-		end = PAGE_SIZE;
+	end = ret;
 
 	ret = __block_write_begin(page, 0, end, get_block);
 	if (!ret)
-- 
2.24.1


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

* [PATCH 3/7] ubifs: Switch to page_mkwrite_check_truncate in ubifs_vm_page_mkwrite
  2020-02-13 20:24 [PATCH 0/7] Switch to page_mkwrite_check_truncate Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 1/7] fs: Un-inline page_mkwrite_check_truncate Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 2/7] fs: Switch to page_mkwrite_check_truncate in block_page_mkwrite Andreas Gruenbacher
@ 2020-02-13 20:24 ` Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 4/7] ext4: Switch to page_mkwrite_check_truncate in ext4_page_mkwrite Andreas Gruenbacher
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-13 20:24 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher

Use the "page has been truncated" logic in page_mkwrite_check_truncate
instead of reimplementing it here.  Other than with the existing code,
fail with -EFAULT / VM_FAULT_NOPAGE when page_offset(page) == size here
as well, as should be expected.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Acked-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/file.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 743928efffc1..395ff2081ecb 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1559,8 +1559,7 @@ static vm_fault_t ubifs_vm_page_mkwrite(struct vm_fault *vmf)
 	}
 
 	lock_page(page);
-	if (unlikely(page->mapping != inode->i_mapping ||
-		     page_offset(page) > i_size_read(inode))) {
+	if (unlikely(page_mkwrite_check_truncate(page, inode) < 0)) {
 		/* Page got truncated out from underneath us */
 		goto sigbus;
 	}
-- 
2.24.1


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

* [PATCH 4/7] ext4: Switch to page_mkwrite_check_truncate in ext4_page_mkwrite
  2020-02-13 20:24 [PATCH 0/7] Switch to page_mkwrite_check_truncate Andreas Gruenbacher
                   ` (2 preceding siblings ...)
  2020-02-13 20:24 ` [PATCH 3/7] ubifs: Switch to page_mkwrite_check_truncate in ubifs_vm_page_mkwrite Andreas Gruenbacher
@ 2020-02-13 20:24 ` Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 5/7] f2fs: Switch to page_mkwrite_check_truncate in f2fs_vm_page_mkwrite Andreas Gruenbacher
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-13 20:24 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher

Use the "page has been truncated" logic in page_mkwrite_check_truncate
instead of reimplementing it here.  Other than with the existing code,
fail with -EFAULT / VM_FAULT_NOPAGE when page_offset(page) == size here
as well, as should be expected.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Acked-by: Theodore Ts'o <tytso@mit.edu>
---
 fs/ext4/inode.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 1305b810c44a..4e00a6014fb3 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5902,13 +5902,11 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf)
 {
 	struct vm_area_struct *vma = vmf->vma;
 	struct page *page = vmf->page;
-	loff_t size;
 	unsigned long len;
 	int err;
 	vm_fault_t ret;
 	struct file *file = vma->vm_file;
 	struct inode *inode = file_inode(file);
-	struct address_space *mapping = inode->i_mapping;
 	handle_t *handle;
 	get_block_t *get_block;
 	int retries = 0;
@@ -5938,18 +5936,13 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf)
 	}
 
 	lock_page(page);
-	size = i_size_read(inode);
-	/* Page got truncated from under us? */
-	if (page->mapping != mapping || page_offset(page) > size) {
+	err = page_mkwrite_check_truncate(page, inode);
+	if (err < 0) {
 		unlock_page(page);
-		ret = VM_FAULT_NOPAGE;
-		goto out;
+		goto out_ret;
 	}
+	len = err;
 
-	if (page->index == size >> PAGE_SHIFT)
-		len = size & ~PAGE_MASK;
-	else
-		len = PAGE_SIZE;
 	/*
 	 * Return if we have all the buffers mapped. This avoids the need to do
 	 * journal_start/journal_stop which can block and take a long time
-- 
2.24.1


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

* [PATCH 5/7] f2fs: Switch to page_mkwrite_check_truncate in f2fs_vm_page_mkwrite
  2020-02-13 20:24 [PATCH 0/7] Switch to page_mkwrite_check_truncate Andreas Gruenbacher
                   ` (3 preceding siblings ...)
  2020-02-13 20:24 ` [PATCH 4/7] ext4: Switch to page_mkwrite_check_truncate in ext4_page_mkwrite Andreas Gruenbacher
@ 2020-02-13 20:24 ` Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 6/7] ceph: Switch to page_mkwrite_check_truncate in ceph_page_mkwrite Andreas Gruenbacher
  2020-02-13 20:24 ` [PATCH 7/7] btrfs: Switch to page_mkwrite_check_truncate in btrfs_page_mkwrite Andreas Gruenbacher
  6 siblings, 0 replies; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-13 20:24 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher, Chao Yu

Use the "page has been truncated" logic in page_mkwrite_check_truncate
instead of reimplementing it here.  Other than with the existing code,
fail with -EFAULT / VM_FAULT_NOPAGE when page_offset(page) == size here
as well, as should be expected.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Acked-by: Chao Yu <yuchao0@huawei.com>
---
 fs/f2fs/file.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 0d4da644df3b..0d5ac7a92230 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -52,7 +52,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	struct dnode_of_data dn;
 	bool need_alloc = true;
-	int err = 0;
+	int offset, err = 0;
 
 	if (unlikely(f2fs_cp_error(sbi))) {
 		err = -EIO;
@@ -91,11 +91,12 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
 	file_update_time(vmf->vma->vm_file);
 	down_read(&F2FS_I(inode)->i_mmap_sem);
 	lock_page(page);
-	if (unlikely(page->mapping != inode->i_mapping ||
-			page_offset(page) > i_size_read(inode) ||
-			!PageUptodate(page))) {
+	offset = -EFAULT;
+	if (likely(PageUptodate(page)))
+		offset = page_mkwrite_check_truncate(page, inode);
+	if (unlikely(offset < 0)) {
 		unlock_page(page);
-		err = -EFAULT;
+		err = offset;
 		goto out_sem;
 	}
 
@@ -124,14 +125,8 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
 	if (PageMappedToDisk(page))
 		goto out_sem;
 
-	/* page is wholly or partially inside EOF */
-	if (((loff_t)(page->index + 1) << PAGE_SHIFT) >
-						i_size_read(inode)) {
-		loff_t offset;
-
-		offset = i_size_read(inode) & ~PAGE_MASK;
+	if (offset != PAGE_SIZE)
 		zero_user_segment(page, offset, PAGE_SIZE);
-	}
 	set_page_dirty(page);
 	if (!PageUptodate(page))
 		SetPageUptodate(page);
-- 
2.24.1


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

* [PATCH 6/7] ceph: Switch to page_mkwrite_check_truncate in ceph_page_mkwrite
  2020-02-13 20:24 [PATCH 0/7] Switch to page_mkwrite_check_truncate Andreas Gruenbacher
                   ` (4 preceding siblings ...)
  2020-02-13 20:24 ` [PATCH 5/7] f2fs: Switch to page_mkwrite_check_truncate in f2fs_vm_page_mkwrite Andreas Gruenbacher
@ 2020-02-13 20:24 ` Andreas Gruenbacher
  2020-02-14  0:00   ` Jeff Layton
  2020-02-13 20:24 ` [PATCH 7/7] btrfs: Switch to page_mkwrite_check_truncate in btrfs_page_mkwrite Andreas Gruenbacher
  6 siblings, 1 reply; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-13 20:24 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher

Use the "page has been truncated" logic in page_mkwrite_check_truncate
instead of reimplementing it here.  Other than with the existing code,
fail with -EFAULT / VM_FAULT_NOPAGE when page_offset(page) == size here
as well, as should be expected.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Acked-by: Jeff Layton <jlayton@kernel.org>
---
 fs/ceph/addr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 7ab616601141..ef958aa4adb4 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -1575,7 +1575,7 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
 	do {
 		lock_page(page);
 
-		if ((off > size) || (page->mapping != inode->i_mapping)) {
+		if (page_mkwrite_check_truncate(page, inode) < 0) {
 			unlock_page(page);
 			ret = VM_FAULT_NOPAGE;
 			break;
-- 
2.24.1


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

* [PATCH 7/7] btrfs: Switch to page_mkwrite_check_truncate in btrfs_page_mkwrite
  2020-02-13 20:24 [PATCH 0/7] Switch to page_mkwrite_check_truncate Andreas Gruenbacher
                   ` (5 preceding siblings ...)
  2020-02-13 20:24 ` [PATCH 6/7] ceph: Switch to page_mkwrite_check_truncate in ceph_page_mkwrite Andreas Gruenbacher
@ 2020-02-13 20:24 ` Andreas Gruenbacher
  6 siblings, 0 replies; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-13 20:24 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher

Use the "page has been truncated" logic in page_mkwrite_check_truncate
instead of reimplementing it here.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Acked-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/inode.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5b3ec93ff911..532cc4aa9222 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8441,16 +8441,15 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
 		goto out_noreserve;
 	}
 
-	ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
 again:
 	lock_page(page);
-	size = i_size_read(inode);
 
-	if ((page->mapping != inode->i_mapping) ||
-	    (page_start >= size)) {
-		/* page got truncated out from underneath us */
+	ret2 = page_mkwrite_check_truncate(page, inode);
+	if (ret2 < 0) {
+		ret = block_page_mkwrite_return(ret2);
 		goto out_unlock;
 	}
+	zero_start = ret2;
 	wait_on_page_writeback(page);
 
 	lock_extent_bits(io_tree, page_start, page_end, &cached_state);
@@ -8471,6 +8470,7 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
 		goto again;
 	}
 
+	size = i_size_read(inode);
 	if (page->index == ((size - 1) >> PAGE_SHIFT)) {
 		reserved_space = round_up(size - page_start,
 					  fs_info->sectorsize);
@@ -8502,12 +8502,6 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
 		goto out_unlock;
 	}
 
-	/* page is wholly or partially inside EOF */
-	if (page_start + PAGE_SIZE > size)
-		zero_start = offset_in_page(size);
-	else
-		zero_start = PAGE_SIZE;
-
 	if (zero_start != PAGE_SIZE) {
 		kaddr = kmap(page);
 		memset(kaddr + zero_start, 0, PAGE_SIZE - zero_start);
-- 
2.24.1


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

* Re: [PATCH 6/7] ceph: Switch to page_mkwrite_check_truncate in ceph_page_mkwrite
  2020-02-13 20:24 ` [PATCH 6/7] ceph: Switch to page_mkwrite_check_truncate in ceph_page_mkwrite Andreas Gruenbacher
@ 2020-02-14  0:00   ` Jeff Layton
  0 siblings, 0 replies; 12+ messages in thread
From: Jeff Layton @ 2020-02-14  0:00 UTC (permalink / raw)
  To: Andreas Gruenbacher, Alexander Viro, David Sterba,
	Theodore Ts'o, Chao Yu, Richard Weinberger
  Cc: linux-fsdevel

On Thu, 2020-02-13 at 21:24 +0100, Andreas Gruenbacher wrote:
> Use the "page has been truncated" logic in page_mkwrite_check_truncate
> instead of reimplementing it here.  Other than with the existing code,
> fail with -EFAULT / VM_FAULT_NOPAGE when page_offset(page) == size here
> as well, as should be expected.
> 
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
> Acked-by: Jeff Layton <jlayton@kernel.org>
> ---
>  fs/ceph/addr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> index 7ab616601141..ef958aa4adb4 100644
> --- a/fs/ceph/addr.c
> +++ b/fs/ceph/addr.c
> @@ -1575,7 +1575,7 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
>  	do {
>  		lock_page(page);
>  
> -		if ((off > size) || (page->mapping != inode->i_mapping)) {
> +		if (page_mkwrite_check_truncate(page, inode) < 0) {
>  			unlock_page(page);
>  			ret = VM_FAULT_NOPAGE;
>  			break;

Thanks Andreas. Merged into the ceph-client/testing branch and should
make v5.7.

Thanks,
-- 
Jeff Layton <jlayton@kernel.org>


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

* Re: [PATCH 1/7] fs: Un-inline page_mkwrite_check_truncate
  2020-02-13 20:24 ` [PATCH 1/7] fs: Un-inline page_mkwrite_check_truncate Andreas Gruenbacher
@ 2020-02-14 15:11   ` Jan Kara
  2020-02-14 20:10   ` [PATCH v2] " Andreas Gruenbacher
  1 sibling, 0 replies; 12+ messages in thread
From: Jan Kara @ 2020-02-14 15:11 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger, linux-fsdevel, Jan Kara

On Thu 13-02-20 21:24:17, Andreas Gruenbacher wrote:
> Per review comments from Jan and Ted, un-inline page_mkwrite_check_truncate
> and move it to mm/filemap.c.  This function doesn't seem worth inlining.
> 
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Theodore Y. Ts'o <tytso@mit.edu>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> 
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index ccb14b6a16b5..6c9c5b88924d 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -636,32 +636,6 @@ static inline unsigned long dir_pages(struct inode *inode)
>  			       PAGE_SHIFT;
>  }
>  
> -/**
> - * page_mkwrite_check_truncate - check if page was truncated
> - * @page: the page to check
> - * @inode: the inode to check the page against
> - *
> - * Returns the number of bytes in the page up to EOF,
> - * or -EFAULT if the page was truncated.
> - */
> -static inline int page_mkwrite_check_truncate(struct page *page,
> -					      struct inode *inode)
> -{
> -	loff_t size = i_size_read(inode);
> -	pgoff_t index = size >> PAGE_SHIFT;
> -	int offset = offset_in_page(size);
> -
> -	if (page->mapping != inode->i_mapping)
> -		return -EFAULT;
> -
> -	/* page is wholly inside EOF */
> -	if (page->index < index)
> -		return PAGE_SIZE;
> -	/* page is wholly past EOF */
> -	if (page->index > index || !offset)
> -		return -EFAULT;
> -	/* page is partially inside EOF */
> -	return offset;
> -}
> +int page_mkwrite_check_truncate(struct page *page, struct inode *inode);
>  
>  #endif /* _LINUX_PAGEMAP_H */
> diff --git a/mm/filemap.c b/mm/filemap.c
> index 1784478270e1..edcb4a8a6121 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -2678,6 +2678,34 @@ const struct vm_operations_struct generic_file_vm_ops = {
>  	.page_mkwrite	= filemap_page_mkwrite,
>  };
>  
> +/**
> + * page_mkwrite_check_truncate - check if page was truncated
> + * @page: the page to check
> + * @inode: the inode to check the page against
> + *
> + * Returns the number of bytes in the page up to EOF,
> + * or -EFAULT if the page was truncated.
> + */
> +int page_mkwrite_check_truncate(struct page *page, struct inode *inode)
> +{
> +	loff_t size = i_size_read(inode);
> +	pgoff_t index = size >> PAGE_SHIFT;
> +	int offset = offset_in_page(size);
> +
> +	if (page->mapping != inode->i_mapping)
> +		return -EFAULT;
> +
> +	/* page is wholly inside EOF */
> +	if (page->index < index)
> +		return PAGE_SIZE;
> +	/* page is wholly past EOF */
> +	if (page->index > index || !offset)
> +		return -EFAULT;
> +	/* page is partially inside EOF */
> +	return offset;
> +}
> +EXPORT_SYMBOL(page_mkwrite_check_truncate);
> +
>  /* This is used for a general mmap of a disk file */
>  
>  int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
> -- 
> 2.24.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

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

* [PATCH v2] fs: Un-inline page_mkwrite_check_truncate
  2020-02-13 20:24 ` [PATCH 1/7] fs: Un-inline page_mkwrite_check_truncate Andreas Gruenbacher
  2020-02-14 15:11   ` Jan Kara
@ 2020-02-14 20:10   ` " Andreas Gruenbacher
  2020-02-17 10:33     ` Jan Kara
  1 sibling, 1 reply; 12+ messages in thread
From: Andreas Gruenbacher @ 2020-02-14 20:10 UTC (permalink / raw)
  To: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger
  Cc: linux-fsdevel, Andreas Gruenbacher, kbuild test robot, Jan Kara

Per review comments from Jan and Ted, un-inline page_mkwrite_check_truncate
and move it to mm/filemap.c.  This function doesn't seem worth inlining.

v2: Define page_mkwrite_check_truncate outside the CONFIG_MMU guard in
mm/filemap.c to allow block_page_mkwrite to use this helper on
ARCH=m68k.

Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Theodore Y. Ts'o <tytso@mit.edu>
---
 include/linux/pagemap.h | 28 +---------------------------
 mm/filemap.c            | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index ccb14b6a16b5..6c9c5b88924d 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -636,32 +636,6 @@ static inline unsigned long dir_pages(struct inode *inode)
 			       PAGE_SHIFT;
 }
 
-/**
- * page_mkwrite_check_truncate - check if page was truncated
- * @page: the page to check
- * @inode: the inode to check the page against
- *
- * Returns the number of bytes in the page up to EOF,
- * or -EFAULT if the page was truncated.
- */
-static inline int page_mkwrite_check_truncate(struct page *page,
-					      struct inode *inode)
-{
-	loff_t size = i_size_read(inode);
-	pgoff_t index = size >> PAGE_SHIFT;
-	int offset = offset_in_page(size);
-
-	if (page->mapping != inode->i_mapping)
-		return -EFAULT;
-
-	/* page is wholly inside EOF */
-	if (page->index < index)
-		return PAGE_SIZE;
-	/* page is wholly past EOF */
-	if (page->index > index || !offset)
-		return -EFAULT;
-	/* page is partially inside EOF */
-	return offset;
-}
+int page_mkwrite_check_truncate(struct page *page, struct inode *inode);
 
 #endif /* _LINUX_PAGEMAP_H */
diff --git a/mm/filemap.c b/mm/filemap.c
index 1784478270e1..eac4f7e84823 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2305,6 +2305,34 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 }
 EXPORT_SYMBOL(generic_file_read_iter);
 
+/**
+ * page_mkwrite_check_truncate - check if page was truncated
+ * @page: the page to check
+ * @inode: the inode to check the page against
+ *
+ * Returns the number of bytes in the page up to EOF,
+ * or -EFAULT if the page was truncated.
+ */
+int page_mkwrite_check_truncate(struct page *page, struct inode *inode)
+{
+	loff_t size = i_size_read(inode);
+	pgoff_t index = size >> PAGE_SHIFT;
+	int offset = offset_in_page(size);
+
+	if (page->mapping != inode->i_mapping)
+		return -EFAULT;
+
+	/* page is wholly inside EOF */
+	if (page->index < index)
+		return PAGE_SIZE;
+	/* page is wholly past EOF */
+	if (page->index > index || !offset)
+		return -EFAULT;
+	/* page is partially inside EOF */
+	return offset;
+}
+EXPORT_SYMBOL(page_mkwrite_check_truncate);
+
 #ifdef CONFIG_MMU
 #define MMAP_LOTSAMISS  (100)
 /*
-- 
2.24.1


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

* Re: [PATCH v2] fs: Un-inline page_mkwrite_check_truncate
  2020-02-14 20:10   ` [PATCH v2] " Andreas Gruenbacher
@ 2020-02-17 10:33     ` Jan Kara
  0 siblings, 0 replies; 12+ messages in thread
From: Jan Kara @ 2020-02-17 10:33 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Alexander Viro, David Sterba, Jeff Layton, Theodore Ts'o,
	Chao Yu, Richard Weinberger, linux-fsdevel, kbuild test robot,
	Jan Kara

On Fri 14-02-20 21:10:20, Andreas Gruenbacher wrote:
> Per review comments from Jan and Ted, un-inline page_mkwrite_check_truncate
> and move it to mm/filemap.c.  This function doesn't seem worth inlining.
> 
> v2: Define page_mkwrite_check_truncate outside the CONFIG_MMU guard in
> mm/filemap.c to allow block_page_mkwrite to use this helper on
> ARCH=m68k.
> 
> Reported-by: kbuild test robot <lkp@intel.com>
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Theodore Y. Ts'o <tytso@mit.edu>

Still looks good to me :). You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  include/linux/pagemap.h | 28 +---------------------------
>  mm/filemap.c            | 28 ++++++++++++++++++++++++++++
>  2 files changed, 29 insertions(+), 27 deletions(-)
> 
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index ccb14b6a16b5..6c9c5b88924d 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -636,32 +636,6 @@ static inline unsigned long dir_pages(struct inode *inode)
>  			       PAGE_SHIFT;
>  }
>  
> -/**
> - * page_mkwrite_check_truncate - check if page was truncated
> - * @page: the page to check
> - * @inode: the inode to check the page against
> - *
> - * Returns the number of bytes in the page up to EOF,
> - * or -EFAULT if the page was truncated.
> - */
> -static inline int page_mkwrite_check_truncate(struct page *page,
> -					      struct inode *inode)
> -{
> -	loff_t size = i_size_read(inode);
> -	pgoff_t index = size >> PAGE_SHIFT;
> -	int offset = offset_in_page(size);
> -
> -	if (page->mapping != inode->i_mapping)
> -		return -EFAULT;
> -
> -	/* page is wholly inside EOF */
> -	if (page->index < index)
> -		return PAGE_SIZE;
> -	/* page is wholly past EOF */
> -	if (page->index > index || !offset)
> -		return -EFAULT;
> -	/* page is partially inside EOF */
> -	return offset;
> -}
> +int page_mkwrite_check_truncate(struct page *page, struct inode *inode);
>  
>  #endif /* _LINUX_PAGEMAP_H */
> diff --git a/mm/filemap.c b/mm/filemap.c
> index 1784478270e1..eac4f7e84823 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -2305,6 +2305,34 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
>  }
>  EXPORT_SYMBOL(generic_file_read_iter);
>  
> +/**
> + * page_mkwrite_check_truncate - check if page was truncated
> + * @page: the page to check
> + * @inode: the inode to check the page against
> + *
> + * Returns the number of bytes in the page up to EOF,
> + * or -EFAULT if the page was truncated.
> + */
> +int page_mkwrite_check_truncate(struct page *page, struct inode *inode)
> +{
> +	loff_t size = i_size_read(inode);
> +	pgoff_t index = size >> PAGE_SHIFT;
> +	int offset = offset_in_page(size);
> +
> +	if (page->mapping != inode->i_mapping)
> +		return -EFAULT;
> +
> +	/* page is wholly inside EOF */
> +	if (page->index < index)
> +		return PAGE_SIZE;
> +	/* page is wholly past EOF */
> +	if (page->index > index || !offset)
> +		return -EFAULT;
> +	/* page is partially inside EOF */
> +	return offset;
> +}
> +EXPORT_SYMBOL(page_mkwrite_check_truncate);
> +
>  #ifdef CONFIG_MMU
>  #define MMAP_LOTSAMISS  (100)
>  /*
> -- 
> 2.24.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

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

end of thread, back to index

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-13 20:24 [PATCH 0/7] Switch to page_mkwrite_check_truncate Andreas Gruenbacher
2020-02-13 20:24 ` [PATCH 1/7] fs: Un-inline page_mkwrite_check_truncate Andreas Gruenbacher
2020-02-14 15:11   ` Jan Kara
2020-02-14 20:10   ` [PATCH v2] " Andreas Gruenbacher
2020-02-17 10:33     ` Jan Kara
2020-02-13 20:24 ` [PATCH 2/7] fs: Switch to page_mkwrite_check_truncate in block_page_mkwrite Andreas Gruenbacher
2020-02-13 20:24 ` [PATCH 3/7] ubifs: Switch to page_mkwrite_check_truncate in ubifs_vm_page_mkwrite Andreas Gruenbacher
2020-02-13 20:24 ` [PATCH 4/7] ext4: Switch to page_mkwrite_check_truncate in ext4_page_mkwrite Andreas Gruenbacher
2020-02-13 20:24 ` [PATCH 5/7] f2fs: Switch to page_mkwrite_check_truncate in f2fs_vm_page_mkwrite Andreas Gruenbacher
2020-02-13 20:24 ` [PATCH 6/7] ceph: Switch to page_mkwrite_check_truncate in ceph_page_mkwrite Andreas Gruenbacher
2020-02-14  0:00   ` Jeff Layton
2020-02-13 20:24 ` [PATCH 7/7] btrfs: Switch to page_mkwrite_check_truncate in btrfs_page_mkwrite Andreas Gruenbacher

Linux-Fsdevel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-fsdevel/0 linux-fsdevel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-fsdevel linux-fsdevel/ https://lore.kernel.org/linux-fsdevel \
		linux-fsdevel@vger.kernel.org
	public-inbox-index linux-fsdevel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-fsdevel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git