bool truncate_inode_partial_folio(struct folio *folio, loff_t start, loff_t end)
 {
        loff_t pos = folio_pos(folio);
+       size_t size = folio_size(folio);
        unsigned int offset, length;
        struct page *split_at, *split_at2;
 
                offset = start - pos;
        else
                offset = 0;
-       length = folio_size(folio);
-       if (pos + length <= (u64)end)
-               length = length - offset;
+       if (pos + size <= (u64)end)
+               length = size - offset;
        else
                length = end + 1 - pos - offset;
 
        folio_wait_writeback(folio);
-       if (length == folio_size(folio)) {
+       if (length == size) {
                truncate_inode_folio(folio->mapping, folio);
                return true;
        }
                return true;
 
        split_at = folio_page(folio, PAGE_ALIGN_DOWN(offset) / PAGE_SIZE);
-       split_at2 = folio_page(folio,
-                       PAGE_ALIGN_DOWN(offset + length) / PAGE_SIZE);
-
        if (!try_folio_split(folio, split_at, NULL)) {
                /*
                 * try to split at offset + length to make sure folios within
                 * the range can be dropped, especially to avoid memory waste
                 * for shmem truncate
                 */
-               struct folio *folio2 = page_folio(split_at2);
+               struct folio *folio2;
+
+               if (offset + length == size)
+                       goto no_split;
+
+               split_at2 = folio_page(folio,
+                               PAGE_ALIGN_DOWN(offset + length) / PAGE_SIZE);
+               folio2 = page_folio(split_at2);
 
                if (!folio_try_get(folio2))
                        goto no_split;