Linux drops pipe page stealing for FUSE and virtio console
Splice into those consumers will always copy, clearing a path for folio work that page theft kept breaking.
Kiryl Shutsemau of Meta has posted patches that stop the kernel from handing a pipe's pages to another owner instead of copying them. Linus Torvalds, who suggested the removal with David Hildenbrand, replied that he was considering taking the series as-is rather than delaying it. "Ack. Lovely," Torvalds wrote.
Two consumers used the steal path. A FUSE server that splices a read reply into /dev/fuse with SPLICE_F_MOVE could have the kernel drop those pages straight into the FUSE file's page cache. virtio_console could pass the same page to the host. The page might have come from another file's page cache, from a write into the pipe, or from a vmsplice that gifted user memory.
That shortcut has been a recurring source of breakage. Stealing pulls page-cache folios out of their files and turns ordinary pages into folios and back, which gets in the way of reading the page cache without folio references and of marking folios with a dedicated flag. It only worked when nothing else held the page, and for FUSE only on clean, unmapped, order-0 pages. Shutsemau pointed to a string of FUSE fixes that had to keep repairing the steal path.
Both consumers already copied when a steal failed. After the change they always copy. The data a FUSE server or a virtio host sees does not change; the move was a hint splice never promised to honour. The in-tree virtio-trace user already always copied, because ftrace ring-buffer pages cannot be stolen.
vmsplice and splice still accept SPLICE_F_GIFT and SPLICE_F_MOVE, and FUSE still advertises FUSE_SPLICE_MOVE. libfuse refuses to mount a filesystem that asks for a capability the kernel does not offer, so dropping the advertisement would break existing servers even though nothing acts on the flag anymore.
Shutsemau tested a FUSE server that answers reads by splicing a backing file's page-cache pages into /dev/fuse. On a current release candidate, one 16MB read of a FUSE file backed by order-0 folios pulled 3968 of the backing file's 4096 pages out of its page cache. With the series, nothing moves, and the bytes read through FUSE are the same, including when the server itself reads requests with splice.
He asked FUSE and virtio maintainers whether any user depends on avoiding that copy. Zi Yan acked the FUSE and virtio_console changes. The last patch deletes the steal operation entirely, along with the pipe-buffer flags that existed only to support it.