// SPDX-License-Identifier: GPL-2.0
/*
 *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
 *
 *  Swap reorganised 29.12.95, Stephen Tweedie.
 *  kswapd added: 7.1.96  sct
 *  Removed kswapd_ctl limits, and swap out as many pages as needed
 *  to bring the system back to freepages.high: 2.4.97, Rik van Riel.
 *  Zone aware kswapd started 02/00, Kanoj Sarcar (kanoj@sgi.com).
 *  Multiqueue VM started 5.8.00, Rik van Riel.
 */

/* Extracted unchanged from Linux v6.18, mm/vmscan.c:683-722.
 * Complete function definition; surrounding kernel context is required.
 * Source: https://github.com/torvalds/linux/blob/v6.18/mm/vmscan.c#L683
 * License text: GPL-2.0.txt (in this directory).
 */
static pageout_t pageout(struct folio *folio, struct address_space *mapping,
			 struct swap_iocb **plug, struct list_head *folio_list)
{
	/*
	 * We no longer attempt to writeback filesystem folios here, other
	 * than tmpfs/shmem.  That's taken care of in page-writeback.
	 * If we find a dirty filesystem folio at the end of the LRU list,
	 * typically that means the filesystem is saturating the storage
	 * with contiguous writes and telling it to write a folio here
	 * would only make the situation worse by injecting an element
	 * of random access.
	 *
	 * If the folio is swapcache, write it back even if that would
	 * block, for some throttling. This happens by accident, because
	 * swap_backing_dev_info is bust: it doesn't reflect the
	 * congestion state of the swapdevs.  Easy to fix, if needed.
	 */
	if (!is_page_cache_freeable(folio))
		return PAGE_KEEP;
	if (!mapping) {
		/*
		 * Some data journaling orphaned folios can have
		 * folio->mapping == NULL while being dirty with clean buffers.
		 */
		if (folio_test_private(folio)) {
			if (try_to_free_buffers(folio)) {
				folio_clear_dirty(folio);
				pr_info("%s: orphaned folio\n", __func__);
				return PAGE_CLEAN;
			}
		}
		return PAGE_KEEP;
	}

	if (!shmem_mapping(mapping) && !folio_test_anon(folio))
		return PAGE_ACTIVATE;
	if (!folio_clear_dirty_for_io(folio))
		return PAGE_CLEAN;
	return writeout(folio, mapping, plug, folio_list);
}

