diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index e6d62f711db8..69a4be12b674 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -1502,28 +1502,32 @@ new_request: BUG_ON(len < ceph_fscrypt_page_offset(page) + thp_size(page) - offset); if (!ceph_inc_osd_stopping_blocker(fsc->mdsc)) { - for (i = 0; i < folio_batch_count(&ceph_wbc->fbatch); i++) { - struct folio *folio = ceph_wbc->fbatch.folios[i]; - - if (!folio) - continue; - - page = &folio->page; - redirty_page_for_writepage(wbc, page); - unlock_page(page); - } - for (i = 0; i < ceph_wbc->locked_pages; i++) { - page = ceph_fscrypt_pagecache_page(ceph_wbc->pages[i]); + page = ceph_wbc->pages[i]; + if (fscrypt_is_bounce_page(page)) { + page = fscrypt_pagecache_page(page); + fscrypt_free_bounce_page(ceph_wbc->pages[i]); + } - if (!page) - continue; + if (atomic_long_dec_return(&fsc->writeback_count) < + CONGESTION_OFF_THRESH(fsc->mount_options->congestion_kb)) + fsc->write_congested = false; ceph_undo_wrbuffer_claim(inode, page_folio(page)); redirty_page_for_writepage(wbc, page); unlock_page(page); + put_page(page); } + if (ceph_wbc->from_pool) { + mempool_free(ceph_wbc->pages, ceph_wb_pagevec_pool); + ceph_wbc->from_pool = false; + } else { + kfree(ceph_wbc->pages); + } + ceph_wbc->pages = NULL; + ceph_wbc->locked_pages = 0; + ceph_osdc_put_request(req); return -EIO; } @@ -1756,8 +1760,11 @@ process_folio_batch: } rc = ceph_submit_write(mapping, wbc, &ceph_wbc); - if (rc) - goto release_folios; + if (rc) { + /* the OSD client is being torn down, don't retry */ + folio_batch_release(&ceph_wbc.fbatch); + goto dec_osd_stopping_blocker; + } ceph_wbc.locked_pages = 0; ceph_wbc.strip_unit_end = 0;