diff --git a/mm/filemap.c b/mm/filemap.c
index 43700480d897d48eb5dbdb879d9d1c5efddb8d0d..bcf64e92ffb05ba38c047e5d407bc0866b1ef1e2 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1969,8 +1969,14 @@ unsigned find_lock_entries(struct address_space *mapping, pgoff_t start,
 put:
 		put_page(page);
 next:
-		if (!xa_is_value(page) && PageTransHuge(page))
-			xas_set(&xas, page->index + thp_nr_pages(page));
+		if (!xa_is_value(page) && PageTransHuge(page)) {
+			unsigned int nr_pages = thp_nr_pages(page);
+
+			/* Final THP may cross MAX_LFS_FILESIZE on 32-bit */
+			xas_set(&xas, page->index + nr_pages);
+			if (xas.xa_index < nr_pages)
+				break;
+		}
 	}
 	rcu_read_unlock();