Unverified Commit b85054be authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!15645 nilfs2: do not force clear folio if buffer is referenced

parents 94d50bef 7bad9d8e
Loading
Loading
Loading
Loading
+29 −5
Original line number Diff line number Diff line
@@ -391,6 +391,11 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
 * nilfs_clear_dirty_page - discard dirty page
 * @page: dirty page that will be discarded
 * @silent: suppress [true] or print [false] warning messages
 *
 * nilfs_clear_dirty_page() clears working states including dirty state for
 * the page and its buffers.  If the page has buffers, clear only if it is
 * confirmed that none of the buffer heads are busy (none have valid
 * references and none are locked).
 */
void nilfs_clear_dirty_page(struct page *page, bool silent)
{
@@ -403,10 +408,6 @@ void nilfs_clear_dirty_page(struct page *page, bool silent)
		nilfs_warn(sb, "discard dirty page: offset=%lld, ino=%lu",
			   page_offset(page), inode->i_ino);

	ClearPageUptodate(page);
	ClearPageMappedToDisk(page);
	ClearPageChecked(page);

	if (page_has_buffers(page)) {
		struct buffer_head *bh, *head;
		const unsigned long clear_bits =
@@ -414,8 +415,28 @@ void nilfs_clear_dirty_page(struct page *page, bool silent)
			 BIT(BH_Async_Write) | BIT(BH_NILFS_Volatile) |
			 BIT(BH_NILFS_Checked) | BIT(BH_NILFS_Redirected) |
			 BIT(BH_Delay));
		bool busy, invalidated = false;

		bh = head = page_buffers(page);
		head = page_buffers(page);
recheck_buffers:
		busy = false;
		bh = head;
		do {
			if (atomic_read(&bh->b_count) | buffer_locked(bh)) {
				busy = true;
				break;
			}
		} while (bh = bh->b_this_page, bh != head);

		if (busy) {
			if (invalidated)
				return;
			invalidate_bh_lrus();
			invalidated = true;
			goto recheck_buffers;
		}

		bh = head;
		do {
			lock_buffer(bh);
			if (!silent)
@@ -428,6 +449,9 @@ void nilfs_clear_dirty_page(struct page *page, bool silent)
		} while (bh = bh->b_this_page, bh != head);
	}

	ClearPageUptodate(page);
	ClearPageMappedToDisk(page);
	ClearPageChecked(page);
	__nilfs_clear_page_dirty(page);
}