ceph: Convert ceph_find_incompatible() to take a folio

Both callers already have the folio.  Pass it in and use it throughout.
Removes some hidden calls to compound_head() and a reference to
page->mapping.

Signed-off-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Link: https://lore.kernel.org/r/20250217185119.430193-4-willy@infradead.org
Tested-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Matthew Wilcox (Oracle)
2025-02-17 18:51:11 +00:00
committed by Christian Brauner
parent 88a59bda3f
commit f9707a8b5b
+19 -19
View File
@@ -1771,56 +1771,56 @@ static int context_is_writeable_or_written(struct inode *inode,
/**
* ceph_find_incompatible - find an incompatible context and return it
* @page: page being dirtied
* @folio: folio being dirtied
*
* We are only allowed to write into/dirty a page if the page is
* We are only allowed to write into/dirty a folio if the folio is
* clean, or already dirty within the same snap context. Returns a
* conflicting context if there is one, NULL if there isn't, or a
* negative error code on other errors.
*
* Must be called with page lock held.
* Must be called with folio lock held.
*/
static struct ceph_snap_context *
ceph_find_incompatible(struct page *page)
ceph_find_incompatible(struct folio *folio)
{
struct inode *inode = page->mapping->host;
struct inode *inode = folio->mapping->host;
struct ceph_client *cl = ceph_inode_to_client(inode);
struct ceph_inode_info *ci = ceph_inode(inode);
if (ceph_inode_is_shutdown(inode)) {
doutc(cl, " %llx.%llx page %p is shutdown\n",
ceph_vinop(inode), page);
doutc(cl, " %llx.%llx folio %p is shutdown\n",
ceph_vinop(inode), folio);
return ERR_PTR(-ESTALE);
}
for (;;) {
struct ceph_snap_context *snapc, *oldest;
wait_on_page_writeback(page);
folio_wait_writeback(folio);
snapc = page_snap_context(page);
snapc = page_snap_context(&folio->page);
if (!snapc || snapc == ci->i_head_snapc)
break;
/*
* this page is already dirty in another (older) snap
* this folio is already dirty in another (older) snap
* context! is it writeable now?
*/
oldest = get_oldest_context(inode, NULL, NULL);
if (snapc->seq > oldest->seq) {
/* not writeable -- return it for the caller to deal with */
ceph_put_snap_context(oldest);
doutc(cl, " %llx.%llx page %p snapc %p not current or oldest\n",
ceph_vinop(inode), page, snapc);
doutc(cl, " %llx.%llx folio %p snapc %p not current or oldest\n",
ceph_vinop(inode), folio, snapc);
return ceph_get_snap_context(snapc);
}
ceph_put_snap_context(oldest);
/* yay, writeable, do it now (without dropping page lock) */
doutc(cl, " %llx.%llx page %p snapc %p not current, but oldest\n",
ceph_vinop(inode), page, snapc);
if (clear_page_dirty_for_io(page)) {
int r = writepage_nounlock(page, NULL);
/* yay, writeable, do it now (without dropping folio lock) */
doutc(cl, " %llx.%llx folio %p snapc %p not current, but oldest\n",
ceph_vinop(inode), folio, snapc);
if (folio_clear_dirty_for_io(folio)) {
int r = writepage_nounlock(&folio->page, NULL);
if (r < 0)
return ERR_PTR(r);
}
@@ -1835,7 +1835,7 @@ static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned
struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_snap_context *snapc;
snapc = ceph_find_incompatible(folio_page(*foliop, 0));
snapc = ceph_find_incompatible(*foliop);
if (snapc) {
int r;
@@ -2095,7 +2095,7 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
break;
}
snapc = ceph_find_incompatible(&folio->page);
snapc = ceph_find_incompatible(folio);
if (!snapc) {
/* success. we'll keep the folio locked. */
folio_mark_dirty(folio);