mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-04-13 09:59:31 +00:00
netfs: Fix a few minor bugs in netfs_page_mkwrite()
We can't return with VM_FAULT_SIGBUS | VM_FAULT_LOCKED; the core code will not unlock the folio in this instance. Introduce a new "unlock" error exit to handle this case. Use it to handle the "folio is truncated" check, and change the "writeback interrupted by a fatal signal" to do a NOPAGE exit instead of letting the core code install the folio currently under writeback before killing the process. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Link: https://lore.kernel.org/r/20241005182307.3190401-3-willy@infradead.org Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
fcd4904e2f
commit
c6a90fe7f0
1 changed files with 13 additions and 14 deletions
|
@ -491,7 +491,9 @@ EXPORT_SYMBOL(netfs_file_write_iter);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notification that a previously read-only page is about to become writable.
|
* Notification that a previously read-only page is about to become writable.
|
||||||
* Note that the caller indicates a single page of a multipage folio.
|
* The caller indicates the precise page that needs to be written to, but
|
||||||
|
* we only track group on a per-folio basis, so we block more often than
|
||||||
|
* we might otherwise.
|
||||||
*/
|
*/
|
||||||
vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group)
|
vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group)
|
||||||
{
|
{
|
||||||
|
@ -501,7 +503,7 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
|
||||||
struct address_space *mapping = file->f_mapping;
|
struct address_space *mapping = file->f_mapping;
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
struct netfs_inode *ictx = netfs_inode(inode);
|
struct netfs_inode *ictx = netfs_inode(inode);
|
||||||
vm_fault_t ret = VM_FAULT_RETRY;
|
vm_fault_t ret = VM_FAULT_NOPAGE;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
_enter("%lx", folio->index);
|
_enter("%lx", folio->index);
|
||||||
|
@ -510,21 +512,15 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
|
||||||
|
|
||||||
if (folio_lock_killable(folio) < 0)
|
if (folio_lock_killable(folio) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
if (folio->mapping != mapping) {
|
if (folio->mapping != mapping)
|
||||||
folio_unlock(folio);
|
goto unlock;
|
||||||
ret = VM_FAULT_NOPAGE;
|
if (folio_wait_writeback_killable(folio) < 0)
|
||||||
goto out;
|
goto unlock;
|
||||||
}
|
|
||||||
|
|
||||||
if (folio_wait_writeback_killable(folio)) {
|
|
||||||
ret = VM_FAULT_LOCKED;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Can we see a streaming write here? */
|
/* Can we see a streaming write here? */
|
||||||
if (WARN_ON(!folio_test_uptodate(folio))) {
|
if (WARN_ON(!folio_test_uptodate(folio))) {
|
||||||
ret = VM_FAULT_SIGBUS | VM_FAULT_LOCKED;
|
ret = VM_FAULT_SIGBUS;
|
||||||
goto out;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
group = netfs_folio_group(folio);
|
group = netfs_folio_group(folio);
|
||||||
|
@ -559,5 +555,8 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
|
||||||
out:
|
out:
|
||||||
sb_end_pagefault(inode->i_sb);
|
sb_end_pagefault(inode->i_sb);
|
||||||
return ret;
|
return ret;
|
||||||
|
unlock:
|
||||||
|
folio_unlock(folio);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(netfs_page_mkwrite);
|
EXPORT_SYMBOL(netfs_page_mkwrite);
|
||||||
|
|
Loading…
Add table
Reference in a new issue