Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2216371/?format=api
{ "id": 2216371, "url": "http://patchwork.ozlabs.org/api/patches/2216371/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260326104544.509518-24-dhowells@redhat.com/", "project": { "id": 12, "url": "http://patchwork.ozlabs.org/api/projects/12/?format=api", "name": "Linux CIFS Client", "link_name": "linux-cifs-client", "list_id": "linux-cifs.vger.kernel.org", "list_email": "linux-cifs@vger.kernel.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260326104544.509518-24-dhowells@redhat.com>", "list_archive_url": null, "date": "2026-03-26T10:45:38", "name": "[23/26] netfs: Remove folio_queue and rolling_buffer", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "96cc32a6ada6f19d92b84c453130aeee052f8a68", "submitter": { "id": 59, "url": "http://patchwork.ozlabs.org/api/people/59/?format=api", "name": "David Howells", "email": "dhowells@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260326104544.509518-24-dhowells@redhat.com/mbox/", "series": [ { "id": 497565, "url": "http://patchwork.ozlabs.org/api/series/497565/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/list/?series=497565", "date": "2026-03-26T10:45:15", "name": "netfs: Keep track of folios in a segmented bio_vec[] chain", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/497565/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2216371/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2216371/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-cifs+bounces-10546-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-cifs@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=YNHh64gE;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-cifs+bounces-10546-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com\n header.b=\"YNHh64gE\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=170.10.133.124", "smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=redhat.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=redhat.com" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fhLhJ2qgMz1y1G\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 26 Mar 2026 22:12:00 +1100 (AEDT)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id E5B5531CBB1D\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 26 Mar 2026 10:55:03 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id DABF93F7E94;\n\tThu, 26 Mar 2026 10:49:37 +0000 (UTC)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B6E83E8C66\n\tfor <linux-cifs@vger.kernel.org>; Thu, 26 Mar 2026 10:49:33 +0000 (UTC)", "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-616-riWMjUXYPcu13w47f_QtQw-1; Thu,\n 26 Mar 2026 06:49:29 -0400", "from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 3BC7D1800372;\n\tThu, 26 Mar 2026 10:49:26 +0000 (UTC)", "from warthog.procyon.org.com (unknown [10.44.33.121])\n\tby mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id A10C33000223;\n\tThu, 26 Mar 2026 10:49:19 +0000 (UTC)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1774522177; cv=none;\n b=Or+8W7MvhsiJk+2pybQVXlP3a7Uv1WPoMZlDhrpjlp3Ut2rkSU0fkt1dSxocbwKPlzizZg1cPA3di9j7oLFlOWn0ysHx3C18u8YgQXkeE4JiC7ZKc5ql3JpsXQWWOHdd6mdC7oGG/1YrLttHRw+BiRGg6t1TKRqQ12GLLUfIB2I=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1774522177; c=relaxed/simple;\n\tbh=ckxwwirhW7gaqeFfrfFah+zpSvFqxBbGBtNeHLtwQ/c=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=fKnNPuCM9rBctjo0ZjrBqo9o+9wr174F32alo70x0UEXvCLqep/HzfkiYXatRYFJy1SVoFMg3BTzJu1yJi2ILXjJdKqDMT73R+Z311EbVj5xbArIdnrgIOsvPLhmvhcwY1SIWsmxEvABH+g6sfY73ksgzdT4O3ImIsDVFh3po2s=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=redhat.com;\n spf=pass smtp.mailfrom=redhat.com;\n dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com\n header.b=YNHh64gE; arc=none smtp.client-ip=170.10.133.124", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1774522172;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\t to:to:cc:cc:mime-version:mime-version:\n\t content-transfer-encoding:content-transfer-encoding:\n\t in-reply-to:in-reply-to:references:references;\n\tbh=j4uigjP0QA24vMb19T4wDbEFmU/7M8ptBU67QVBfdeQ=;\n\tb=YNHh64gECjU1F5CoG404Qkhh3yE5MK963ReqAVyOgJd4GYRsEtcC+yIyPjUZpNVd7K4AkW\n\tmS3Euiw8NLYJTMFbvAQsiYWUY0JFNBb9Yzqemk+I4wijyd93ivn1TjsVxFtm0b/CvAbjJl\n\tozhBKZq8KbAd+BGfnSv6NIaD8xORVrk=", "X-MC-Unique": "riWMjUXYPcu13w47f_QtQw-1", "X-Mimecast-MFC-AGG-ID": "riWMjUXYPcu13w47f_QtQw_1774522166", "From": "David Howells <dhowells@redhat.com>", "To": "Christian Brauner <christian@brauner.io>,\n\tMatthew Wilcox <willy@infradead.org>,\n\tChristoph Hellwig <hch@infradead.org>", "Cc": "David Howells <dhowells@redhat.com>,\n\tPaulo Alcantara <pc@manguebit.com>,\n\tJens Axboe <axboe@kernel.dk>,\n\tLeon Romanovsky <leon@kernel.org>,\n\tSteve French <sfrench@samba.org>,\n\tChenXiaoSong <chenxiaosong@chenxiaosong.com>,\n\tMarc Dionne <marc.dionne@auristor.com>,\n\tEric Van Hensbergen <ericvh@kernel.org>,\n\tDominique Martinet <asmadeus@codewreck.org>,\n\tIlya Dryomov <idryomov@gmail.com>,\n\tTrond Myklebust <trondmy@kernel.org>,\n\tnetfs@lists.linux.dev,\n\tlinux-afs@lists.infradead.org,\n\tlinux-cifs@vger.kernel.org,\n\tlinux-nfs@vger.kernel.org,\n\tceph-devel@vger.kernel.org,\n\tv9fs@lists.linux.dev,\n\tlinux-erofs@lists.ozlabs.org,\n\tlinux-fsdevel@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org,\n\tPaulo Alcantara <pc@manguebit.org>", "Subject": "[PATCH 23/26] netfs: Remove folio_queue and rolling_buffer", "Date": "Thu, 26 Mar 2026 10:45:38 +0000", "Message-ID": "<20260326104544.509518-24-dhowells@redhat.com>", "In-Reply-To": "<20260326104544.509518-1-dhowells@redhat.com>", "References": "<20260326104544.509518-1-dhowells@redhat.com>", "Precedence": "bulk", "X-Mailing-List": "linux-cifs@vger.kernel.org", "List-Id": "<linux-cifs.vger.kernel.org>", "List-Subscribe": "<mailto:linux-cifs+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-cifs+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.4" }, "content": "Remove folio_queue and rolling_buffer as they're no longer used.\n\nSigned-off-by: David Howells <dhowells@redhat.com>\ncc: Paulo Alcantara <pc@manguebit.org>\ncc: Matthew Wilcox <willy@infradead.org>\ncc: Christoph Hellwig <hch@infradead.org>\ncc: Steve French <sfrench@samba.org>\ncc: linux-cifs@vger.kernel.org\ncc: netfs@lists.linux.dev\ncc: linux-fsdevel@vger.kernel.org\n---\n Documentation/core-api/folio_queue.rst | 209 -----------------\n Documentation/core-api/index.rst | 1 -\n fs/netfs/iterator.c | 192 ----------------\n fs/netfs/rolling_buffer.c | 297 -------------------------\n include/linux/folio_queue.h | 282 -----------------------\n include/linux/rolling_buffer.h | 64 ------\n 6 files changed, 1045 deletions(-)\n delete mode 100644 Documentation/core-api/folio_queue.rst\n delete mode 100644 fs/netfs/rolling_buffer.c\n delete mode 100644 include/linux/folio_queue.h\n delete mode 100644 include/linux/rolling_buffer.h", "diff": "diff --git a/Documentation/core-api/folio_queue.rst b/Documentation/core-api/folio_queue.rst\ndeleted file mode 100644\nindex b7628896d2b6..000000000000\n--- a/Documentation/core-api/folio_queue.rst\n+++ /dev/null\n@@ -1,209 +0,0 @@\n-.. SPDX-License-Identifier: GPL-2.0+\n-\n-===========\n-Folio Queue\n-===========\n-\n-:Author: David Howells <dhowells@redhat.com>\n-\n-.. Contents:\n-\n- * Overview\n- * Initialisation\n- * Adding and removing folios\n- * Querying information about a folio\n- * Querying information about a folio_queue\n- * Folio queue iteration\n- * Folio marks\n- * Lockless simultaneous production/consumption issues\n-\n-\n-Overview\n-========\n-\n-The folio_queue struct forms a single segment in a segmented list of folios\n-that can be used to form an I/O buffer. As such, the list can be iterated over\n-using the ITER_FOLIOQ iov_iter type.\n-\n-The publicly accessible members of the structure are::\n-\n-\tstruct folio_queue {\n-\t\tstruct folio_queue *next;\n-\t\tstruct folio_queue *prev;\n-\t\t...\n-\t};\n-\n-A pair of pointers are provided, ``next`` and ``prev``, that point to the\n-segments on either side of the segment being accessed. Whilst this is a\n-doubly-linked list, it is intentionally not a circular list; the outward\n-sibling pointers in terminal segments should be NULL.\n-\n-Each segment in the list also stores:\n-\n- * an ordered sequence of folio pointers,\n- * the size of each folio and\n- * three 1-bit marks per folio,\n-\n-but these should not be accessed directly as the underlying data structure may\n-change, but rather the access functions outlined below should be used.\n-\n-The facility can be made accessible by::\n-\n-\t#include <linux/folio_queue.h>\n-\n-and to use the iterator::\n-\n-\t#include <linux/uio.h>\n-\n-\n-Initialisation\n-==============\n-\n-A segment should be initialised by calling::\n-\n-\tvoid folioq_init(struct folio_queue *folioq);\n-\n-with a pointer to the segment to be initialised. Note that this will not\n-necessarily initialise all the folio pointers, so care must be taken to check\n-the number of folios added.\n-\n-\n-Adding and removing folios\n-==========================\n-\n-Folios can be set in the next unused slot in a segment struct by calling one\n-of::\n-\n-\tunsigned int folioq_append(struct folio_queue *folioq,\n-\t\t\t\t struct folio *folio);\n-\n-\tunsigned int folioq_append_mark(struct folio_queue *folioq,\n-\t\t\t\t\tstruct folio *folio);\n-\n-Both functions update the stored folio count, store the folio and note its\n-size. The second function also sets the first mark for the folio added. Both\n-functions return the number of the slot used. [!] Note that no attempt is made\n-to check that the capacity wasn't overrun and the list will not be extended\n-automatically.\n-\n-A folio can be excised by calling::\n-\n-\tvoid folioq_clear(struct folio_queue *folioq, unsigned int slot);\n-\n-This clears the slot in the array and also clears all the marks for that folio,\n-but doesn't change the folio count - so future accesses of that slot must check\n-if the slot is occupied.\n-\n-\n-Querying information about a folio\n-==================================\n-\n-Information about the folio in a particular slot may be queried by the\n-following function::\n-\n-\tstruct folio *folioq_folio(const struct folio_queue *folioq,\n-\t\t\t\t unsigned int slot);\n-\n-If a folio has not yet been set in that slot, this may yield an undefined\n-pointer. The size of the folio in a slot may be queried with either of::\n-\n-\tunsigned int folioq_folio_order(const struct folio_queue *folioq,\n-\t\t\t\t\tunsigned int slot);\n-\n-\tsize_t folioq_folio_size(const struct folio_queue *folioq,\n-\t\t\t\t unsigned int slot);\n-\n-The first function returns the size as an order and the second as a number of\n-bytes.\n-\n-\n-Querying information about a folio_queue\n-========================================\n-\n-Information may be retrieved about a particular segment with the following\n-functions::\n-\n-\tunsigned int folioq_nr_slots(const struct folio_queue *folioq);\n-\n-\tunsigned int folioq_count(struct folio_queue *folioq);\n-\n-\tbool folioq_full(struct folio_queue *folioq);\n-\n-The first function returns the maximum capacity of a segment. It must not be\n-assumed that this won't vary between segments. The second returns the number\n-of folios added to a segments and the third is a shorthand to indicate if the\n-segment has been filled to capacity.\n-\n-Not that the count and fullness are not affected by clearing folios from the\n-segment. These are more about indicating how many slots in the array have been\n-initialised, and it assumed that slots won't get reused, but rather the segment\n-will get discarded as the queue is consumed.\n-\n-\n-Folio marks\n-===========\n-\n-Folios within a queue can also have marks assigned to them. These marks can be\n-used to note information such as if a folio needs folio_put() calling upon it.\n-There are three marks available to be set for each folio.\n-\n-The marks can be set by::\n-\n-\tvoid folioq_mark(struct folio_queue *folioq, unsigned int slot);\n-\tvoid folioq_mark2(struct folio_queue *folioq, unsigned int slot);\n-\n-Cleared by::\n-\n-\tvoid folioq_unmark(struct folio_queue *folioq, unsigned int slot);\n-\tvoid folioq_unmark2(struct folio_queue *folioq, unsigned int slot);\n-\n-And the marks can be queried by::\n-\n-\tbool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot);\n-\tbool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot);\n-\n-The marks can be used for any purpose and are not interpreted by this API.\n-\n-\n-Folio queue iteration\n-=====================\n-\n-A list of segments may be iterated over using the I/O iterator facility using\n-an ``iov_iter`` iterator of ``ITER_FOLIOQ`` type. The iterator may be\n-initialised with::\n-\n-\tvoid iov_iter_folio_queue(struct iov_iter *i, unsigned int direction,\n-\t\t\t\t const struct folio_queue *folioq,\n-\t\t\t\t unsigned int first_slot, unsigned int offset,\n-\t\t\t\t size_t count);\n-\n-This may be told to start at a particular segment, slot and offset within a\n-queue. The iov iterator functions will follow the next pointers when advancing\n-and prev pointers when reverting when needed.\n-\n-\n-Lockless simultaneous production/consumption issues\n-===================================================\n-\n-If properly managed, the list can be extended by the producer at the head end\n-and shortened by the consumer at the tail end simultaneously without the need\n-to take locks. The ITER_FOLIOQ iterator inserts appropriate barriers to aid\n-with this.\n-\n-Care must be taken when simultaneously producing and consuming a list. If the\n-last segment is reached and the folios it refers to are entirely consumed by\n-the IOV iterators, an iov_iter struct will be left pointing to the last segment\n-with a slot number equal to the capacity of that segment. The iterator will\n-try to continue on from this if there's another segment available when it is\n-used again, but care must be taken lest the segment got removed and freed by\n-the consumer before the iterator was advanced.\n-\n-It is recommended that the queue always contain at least one segment, even if\n-that segment has never been filled or is entirely spent. This prevents the\n-head and tail pointers from collapsing.\n-\n-\n-API Function Reference\n-======================\n-\n-.. kernel-doc:: include/linux/folio_queue.h\ndiff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst\nindex 13769d5c40bf..16c529a33ac4 100644\n--- a/Documentation/core-api/index.rst\n+++ b/Documentation/core-api/index.rst\n@@ -39,7 +39,6 @@ Library functionality that is used throughout the kernel.\n kref\n cleanup\n assoc_array\n- folio_queue\n xarray\n maple_tree\n idr\ndiff --git a/fs/netfs/iterator.c b/fs/netfs/iterator.c\nindex 442f893a0d65..7969c0b1f9a9 100644\n--- a/fs/netfs/iterator.c\n+++ b/fs/netfs/iterator.c\n@@ -135,195 +135,3 @@ ssize_t netfs_extract_iter(struct iov_iter *orig, size_t orig_len, size_t max_se\n \treturn extracted ?: ret;\n }\n EXPORT_SYMBOL_GPL(netfs_extract_iter);\n-\n-#if 0\n-/*\n- * Select the span of a bvec iterator we're going to use. Limit it by both maximum\n- * size and maximum number of segments. Returns the size of the span in bytes.\n- */\n-static size_t netfs_limit_bvec(const struct iov_iter *iter, size_t start_offset,\n-\t\t\t size_t max_size, size_t max_segs)\n-{\n-\tconst struct bio_vec *bvecs = iter->bvec;\n-\tunsigned int nbv = iter->nr_segs, ix = 0, nsegs = 0;\n-\tsize_t len, span = 0, n = iter->count;\n-\tsize_t skip = iter->iov_offset + start_offset;\n-\n-\tif (WARN_ON(!iov_iter_is_bvec(iter)) ||\n-\t WARN_ON(start_offset > n) ||\n-\t n == 0)\n-\t\treturn 0;\n-\n-\twhile (n && ix < nbv && skip) {\n-\t\tlen = bvecs[ix].bv_len;\n-\t\tif (skip < len)\n-\t\t\tbreak;\n-\t\tskip -= len;\n-\t\tn -= len;\n-\t\tix++;\n-\t}\n-\n-\twhile (n && ix < nbv) {\n-\t\tlen = min3(n, bvecs[ix].bv_len - skip, max_size);\n-\t\tspan += len;\n-\t\tnsegs++;\n-\t\tix++;\n-\t\tif (span >= max_size || nsegs >= max_segs)\n-\t\t\tbreak;\n-\t\tskip = 0;\n-\t\tn -= len;\n-\t}\n-\n-\treturn min(span, max_size);\n-}\n-\n-/*\n- * Select the span of a kvec iterator we're going to use. Limit it by both\n- * maximum size and maximum number of segments. Returns the size of the span\n- * in bytes.\n- */\n-static size_t netfs_limit_kvec(const struct iov_iter *iter, size_t start_offset,\n-\t\t\t size_t max_size, size_t max_segs)\n-{\n-\tconst struct kvec *kvecs = iter->kvec;\n-\tunsigned int nkv = iter->nr_segs, ix = 0, nsegs = 0;\n-\tsize_t len, span = 0, n = iter->count;\n-\tsize_t skip = iter->iov_offset + start_offset;\n-\n-\tif (WARN_ON(!iov_iter_is_kvec(iter)) ||\n-\t WARN_ON(start_offset > n) ||\n-\t n == 0)\n-\t\treturn 0;\n-\n-\twhile (n && ix < nkv && skip) {\n-\t\tlen = kvecs[ix].iov_len;\n-\t\tif (skip < len)\n-\t\t\tbreak;\n-\t\tskip -= len;\n-\t\tn -= len;\n-\t\tix++;\n-\t}\n-\n-\twhile (n && ix < nkv) {\n-\t\tlen = min3(n, kvecs[ix].iov_len - skip, max_size);\n-\t\tspan += len;\n-\t\tnsegs++;\n-\t\tix++;\n-\t\tif (span >= max_size || nsegs >= max_segs)\n-\t\t\tbreak;\n-\t\tskip = 0;\n-\t\tn -= len;\n-\t}\n-\n-\treturn min(span, max_size);\n-}\n-\n-/*\n- * Select the span of an xarray iterator we're going to use. Limit it by both\n- * maximum size and maximum number of segments. It is assumed that segments\n- * can be larger than a page in size, provided they're physically contiguous.\n- * Returns the size of the span in bytes.\n- */\n-static size_t netfs_limit_xarray(const struct iov_iter *iter, size_t start_offset,\n-\t\t\t\t size_t max_size, size_t max_segs)\n-{\n-\tstruct folio *folio;\n-\tunsigned int nsegs = 0;\n-\tloff_t pos = iter->xarray_start + iter->iov_offset;\n-\tpgoff_t index = pos / PAGE_SIZE;\n-\tsize_t span = 0, n = iter->count;\n-\n-\tXA_STATE(xas, iter->xarray, index);\n-\n-\tif (WARN_ON(!iov_iter_is_xarray(iter)) ||\n-\t WARN_ON(start_offset > n) ||\n-\t n == 0)\n-\t\treturn 0;\n-\tmax_size = min(max_size, n - start_offset);\n-\n-\trcu_read_lock();\n-\txas_for_each(&xas, folio, ULONG_MAX) {\n-\t\tsize_t offset, flen, len;\n-\t\tif (xas_retry(&xas, folio))\n-\t\t\tcontinue;\n-\t\tif (WARN_ON(xa_is_value(folio)))\n-\t\t\tbreak;\n-\t\tif (WARN_ON(folio_test_hugetlb(folio)))\n-\t\t\tbreak;\n-\n-\t\tflen = folio_size(folio);\n-\t\toffset = offset_in_folio(folio, pos);\n-\t\tlen = min(max_size, flen - offset);\n-\t\tspan += len;\n-\t\tnsegs++;\n-\t\tif (span >= max_size || nsegs >= max_segs)\n-\t\t\tbreak;\n-\t}\n-\n-\trcu_read_unlock();\n-\treturn min(span, max_size);\n-}\n-\n-/*\n- * Select the span of a folio queue iterator we're going to use. Limit it by\n- * both maximum size and maximum number of segments. Returns the size of the\n- * span in bytes.\n- */\n-static size_t netfs_limit_folioq(const struct iov_iter *iter, size_t start_offset,\n-\t\t\t\t size_t max_size, size_t max_segs)\n-{\n-\tconst struct folio_queue *folioq = iter->folioq;\n-\tunsigned int nsegs = 0;\n-\tunsigned int slot = iter->folioq_slot;\n-\tsize_t span = 0, n = iter->count;\n-\n-\tif (WARN_ON(!iov_iter_is_folioq(iter)) ||\n-\t WARN_ON(start_offset > n) ||\n-\t n == 0)\n-\t\treturn 0;\n-\tmax_size = umin(max_size, n - start_offset);\n-\n-\tif (slot >= folioq_nr_slots(folioq)) {\n-\t\tfolioq = folioq->next;\n-\t\tslot = 0;\n-\t}\n-\n-\tstart_offset += iter->iov_offset;\n-\tdo {\n-\t\tsize_t flen = folioq_folio_size(folioq, slot);\n-\n-\t\tif (start_offset < flen) {\n-\t\t\tspan += flen - start_offset;\n-\t\t\tnsegs++;\n-\t\t\tstart_offset = 0;\n-\t\t} else {\n-\t\t\tstart_offset -= flen;\n-\t\t}\n-\t\tif (span >= max_size || nsegs >= max_segs)\n-\t\t\tbreak;\n-\n-\t\tslot++;\n-\t\tif (slot >= folioq_nr_slots(folioq)) {\n-\t\t\tfolioq = folioq->next;\n-\t\t\tslot = 0;\n-\t\t}\n-\t} while (folioq);\n-\n-\treturn umin(span, max_size);\n-}\n-\n-size_t netfs_limit_iter(const struct iov_iter *iter, size_t start_offset,\n-\t\t\tsize_t max_size, size_t max_segs)\n-{\n-\tif (iov_iter_is_folioq(iter))\n-\t\treturn netfs_limit_folioq(iter, start_offset, max_size, max_segs);\n-\tif (iov_iter_is_bvec(iter))\n-\t\treturn netfs_limit_bvec(iter, start_offset, max_size, max_segs);\n-\tif (iov_iter_is_xarray(iter))\n-\t\treturn netfs_limit_xarray(iter, start_offset, max_size, max_segs);\n-\tif (iov_iter_is_kvec(iter))\n-\t\treturn netfs_limit_kvec(iter, start_offset, max_size, max_segs);\n-\tBUG();\n-}\n-EXPORT_SYMBOL(netfs_limit_iter);\n-#endif\ndiff --git a/fs/netfs/rolling_buffer.c b/fs/netfs/rolling_buffer.c\ndeleted file mode 100644\nindex 292011c1cacb..000000000000\n--- a/fs/netfs/rolling_buffer.c\n+++ /dev/null\n@@ -1,297 +0,0 @@\n-// SPDX-License-Identifier: GPL-2.0-or-later\n-/* Rolling buffer helpers\n- *\n- * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved.\n- * Written by David Howells (dhowells@redhat.com)\n- */\n-\n-#include <linux/bitops.h>\n-#include <linux/pagemap.h>\n-#include <linux/rolling_buffer.h>\n-#include <linux/slab.h>\n-#include \"internal.h\"\n-\n-static atomic_t debug_ids;\n-\n-/**\n- * netfs_folioq_alloc - Allocate a folio_queue struct\n- * @rreq_id: Associated debugging ID for tracing purposes\n- * @gfp: Allocation constraints\n- * @trace: Trace tag to indicate the purpose of the allocation\n- *\n- * Allocate, initialise and account the folio_queue struct and log a trace line\n- * to mark the allocation.\n- */\n-struct folio_queue *netfs_folioq_alloc(unsigned int rreq_id, gfp_t gfp,\n-\t\t\t\t unsigned int /*enum netfs_folioq_trace*/ trace)\n-{\n-\tstruct folio_queue *fq;\n-\n-\tfq = kmalloc_obj(*fq, gfp);\n-\tif (fq) {\n-\t\tnetfs_stat(&netfs_n_folioq);\n-\t\tfolioq_init(fq, rreq_id);\n-\t\tfq->debug_id = atomic_inc_return(&debug_ids);\n-\t\ttrace_netfs_folioq(fq, trace);\n-\t}\n-\treturn fq;\n-}\n-EXPORT_SYMBOL(netfs_folioq_alloc);\n-\n-/**\n- * netfs_folioq_free - Free a folio_queue struct\n- * @folioq: The object to free\n- * @trace: Trace tag to indicate which free\n- *\n- * Free and unaccount the folio_queue struct.\n- */\n-void netfs_folioq_free(struct folio_queue *folioq,\n-\t\t unsigned int /*enum netfs_trace_folioq*/ trace)\n-{\n-\ttrace_netfs_folioq(folioq, trace);\n-\tnetfs_stat_d(&netfs_n_folioq);\n-\tkfree(folioq);\n-}\n-EXPORT_SYMBOL(netfs_folioq_free);\n-\n-/*\n- * Initialise a rolling buffer. We allocate an empty folio queue struct to so\n- * that the pointers can be independently driven by the producer and the\n- * consumer.\n- */\n-int rolling_buffer_init(struct rolling_buffer *roll, unsigned int rreq_id,\n-\t\t\tunsigned int direction)\n-{\n-\tstruct folio_queue *fq;\n-\n-\tfq = netfs_folioq_alloc(rreq_id, GFP_NOFS, netfs_trace_folioq_rollbuf_init);\n-\tif (!fq)\n-\t\treturn -ENOMEM;\n-\n-\troll->head = fq;\n-\troll->tail = fq;\n-\tiov_iter_folio_queue(&roll->iter, direction, fq, 0, 0, 0);\n-\treturn 0;\n-}\n-\n-/*\n- * Add another folio_queue to a rolling buffer if there's no space left.\n- */\n-int rolling_buffer_make_space(struct rolling_buffer *roll)\n-{\n-\tstruct folio_queue *fq, *head = roll->head;\n-\n-\tif (!folioq_full(head))\n-\t\treturn 0;\n-\n-\tfq = netfs_folioq_alloc(head->rreq_id, GFP_NOFS, netfs_trace_folioq_make_space);\n-\tif (!fq)\n-\t\treturn -ENOMEM;\n-\tfq->prev = head;\n-\n-\troll->head = fq;\n-\tif (folioq_full(head)) {\n-\t\t/* Make sure we don't leave the master iterator pointing to a\n-\t\t * block that might get immediately consumed.\n-\t\t */\n-\t\tif (roll->iter.folioq == head &&\n-\t\t roll->iter.folioq_slot == folioq_nr_slots(head)) {\n-\t\t\troll->iter.folioq = fq;\n-\t\t\troll->iter.folioq_slot = 0;\n-\t\t}\n-\t}\n-\n-\t/* Make sure the initialisation is stored before the next pointer.\n-\t *\n-\t * [!] NOTE: After we set head->next, the consumer is at liberty to\n-\t * immediately delete the old head.\n-\t */\n-\tsmp_store_release(&head->next, fq);\n-\treturn 0;\n-}\n-\n-/*\n- * Decant the list of folios to read into a rolling buffer.\n- */\n-ssize_t rolling_buffer_load_from_ra(struct rolling_buffer *roll,\n-\t\t\t\t struct readahead_control *ractl,\n-\t\t\t\t struct folio_batch *put_batch)\n-{\n-\tstruct folio_queue *fq;\n-\tstruct page **vec;\n-\tint nr, ix, to;\n-\tssize_t size = 0;\n-\n-\tif (rolling_buffer_make_space(roll) < 0)\n-\t\treturn -ENOMEM;\n-\n-\tfq = roll->head;\n-\tvec = (struct page **)fq->vec.folios;\n-\tnr = __readahead_batch(ractl, vec + folio_batch_count(&fq->vec),\n-\t\t\t folio_batch_space(&fq->vec));\n-\tix = fq->vec.nr;\n-\tto = ix + nr;\n-\tfq->vec.nr = to;\n-\tfor (; ix < to; ix++) {\n-\t\tstruct folio *folio = folioq_folio(fq, ix);\n-\t\tunsigned int order = folio_order(folio);\n-\n-\t\tfq->orders[ix] = order;\n-\t\tsize += PAGE_SIZE << order;\n-\t\ttrace_netfs_folio(folio, netfs_folio_trace_read);\n-\t\tif (!folio_batch_add(put_batch, folio))\n-\t\t\tfolio_batch_release(put_batch);\n-\t}\n-\tWRITE_ONCE(roll->iter.count, roll->iter.count + size);\n-\n-\t/* Store the counter after setting the slot. */\n-\tsmp_store_release(&roll->next_head_slot, to);\n-\treturn size;\n-}\n-\n-/*\n- * Decant the entire list of folios to read into a rolling buffer.\n- */\n-ssize_t rolling_buffer_bulk_load_from_ra(struct rolling_buffer *roll,\n-\t\t\t\t\t struct readahead_control *ractl,\n-\t\t\t\t\t unsigned int rreq_id)\n-{\n-\tXA_STATE(xas, &ractl->mapping->i_pages, ractl->_index);\n-\tstruct folio_queue *fq;\n-\tstruct folio *folio;\n-\tssize_t loaded = 0;\n-\tint nr, slot = 0, npages = 0;\n-\n-\t/* First allocate all the folioqs we're going to need to avoid having\n-\t * to deal with ENOMEM later.\n-\t */\n-\tnr = ractl->_nr_folios;\n-\tdo {\n-\t\tfq = netfs_folioq_alloc(rreq_id, GFP_KERNEL,\n-\t\t\t\t\tnetfs_trace_folioq_make_space);\n-\t\tif (!fq) {\n-\t\t\trolling_buffer_clear(roll);\n-\t\t\treturn -ENOMEM;\n-\t\t}\n-\t\tfq->prev = roll->head;\n-\t\tif (!roll->tail)\n-\t\t\troll->tail = fq;\n-\t\telse\n-\t\t\troll->head->next = fq;\n-\t\troll->head = fq;\n-\t\t\t\n-\t\tnr -= folioq_nr_slots(fq);\n-\t} while (nr > 0);\n-\n-\trcu_read_lock();\n-\n-\tfq = roll->tail;\n-\txas_for_each(&xas, folio, ractl->_index + ractl->_nr_pages - 1) {\n-\t\tunsigned int order;\n-\n-\t\tif (xas_retry(&xas, folio))\n-\t\t\tcontinue;\n-\t\tVM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);\n-\n-\t\torder = folio_order(folio);\n-\t\tfq->orders[slot] = order;\n-\t\tfq->vec.folios[slot] = folio;\n-\t\tloaded += PAGE_SIZE << order;\n-\t\tnpages += 1 << order;\n-\t\ttrace_netfs_folio(folio, netfs_folio_trace_read);\n-\n-\t\tslot++;\n-\t\tif (slot >= folioq_nr_slots(fq)) {\n-\t\t\tfq->vec.nr = slot;\n-\t\t\tfq = fq->next;\n-\t\t\tif (!fq) {\n-\t\t\t\tWARN_ON_ONCE(npages < readahead_count(ractl));\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tslot = 0;\n-\t\t}\n-\t}\n-\n-\trcu_read_unlock();\n-\n-\tif (fq)\n-\t\tfq->vec.nr = slot;\n-\n-\tWRITE_ONCE(roll->iter.count, loaded);\n-\tiov_iter_folio_queue(&roll->iter, ITER_DEST, roll->tail, 0, 0, loaded);\n-\tractl->_index += npages;\n-\tractl->_nr_pages -= npages;\n-\treturn loaded;\n-}\n-\n-/*\n- * Append a folio to the rolling buffer.\n- */\n-ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio,\n-\t\t\t unsigned int flags)\n-{\n-\tssize_t size = folio_size(folio);\n-\tint slot;\n-\n-\tif (rolling_buffer_make_space(roll) < 0)\n-\t\treturn -ENOMEM;\n-\n-\tslot = folioq_append(roll->head, folio);\n-\tif (flags & ROLLBUF_MARK_1)\n-\t\tfolioq_mark(roll->head, slot);\n-\tif (flags & ROLLBUF_MARK_2)\n-\t\tfolioq_mark2(roll->head, slot);\n-\n-\tWRITE_ONCE(roll->iter.count, roll->iter.count + size);\n-\n-\t/* Store the counter after setting the slot. */\n-\tsmp_store_release(&roll->next_head_slot, slot);\n-\treturn size;\n-}\n-\n-/*\n- * Delete a spent buffer from a rolling queue and return the next in line. We\n- * don't return the last buffer to keep the pointers independent, but return\n- * NULL instead.\n- */\n-struct folio_queue *rolling_buffer_delete_spent(struct rolling_buffer *roll)\n-{\n-\tstruct folio_queue *spent = roll->tail, *next = READ_ONCE(spent->next);\n-\n-\tif (!next)\n-\t\treturn NULL;\n-\tnext->prev = NULL;\n-\tnetfs_folioq_free(spent, netfs_trace_folioq_delete);\n-\troll->tail = next;\n-\treturn next;\n-}\n-\n-/*\n- * Clear out a rolling queue. Folios that have mark 1 set are put.\n- */\n-void rolling_buffer_clear(struct rolling_buffer *roll)\n-{\n-\tstruct folio_batch fbatch;\n-\tstruct folio_queue *p;\n-\n-\tfolio_batch_init(&fbatch);\n-\n-\twhile ((p = roll->tail)) {\n-\t\troll->tail = p->next;\n-\t\tfor (int slot = 0; slot < folioq_count(p); slot++) {\n-\t\t\tstruct folio *folio = folioq_folio(p, slot);\n-\n-\t\t\tif (!folio)\n-\t\t\t\tcontinue;\n-\t\t\tif (folioq_is_marked(p, slot)) {\n-\t\t\t\ttrace_netfs_folio(folio, netfs_folio_trace_put);\n-\t\t\t\tif (!folio_batch_add(&fbatch, folio))\n-\t\t\t\t\tfolio_batch_release(&fbatch);\n-\t\t\t}\n-\t\t}\n-\n-\t\tnetfs_folioq_free(p, netfs_trace_folioq_clear);\n-\t}\n-\n-\tfolio_batch_release(&fbatch);\n-}\ndiff --git a/include/linux/folio_queue.h b/include/linux/folio_queue.h\ndeleted file mode 100644\nindex adab609c972e..000000000000\n--- a/include/linux/folio_queue.h\n+++ /dev/null\n@@ -1,282 +0,0 @@\n-/* SPDX-License-Identifier: GPL-2.0-or-later */\n-/* Queue of folios definitions\n- *\n- * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved.\n- * Written by David Howells (dhowells@redhat.com)\n- *\n- * See:\n- *\n- *\tDocumentation/core-api/folio_queue.rst\n- *\n- * for a description of the API.\n- */\n-\n-#ifndef _LINUX_FOLIO_QUEUE_H\n-#define _LINUX_FOLIO_QUEUE_H\n-\n-#include <linux/pagevec.h>\n-#include <linux/mm.h>\n-\n-/*\n- * Segment in a queue of running buffers. Each segment can hold a number of\n- * folios and a portion of the queue can be referenced with the ITER_FOLIOQ\n- * iterator. The possibility exists of inserting non-folio elements into the\n- * queue (such as gaps).\n- *\n- * Explicit prev and next pointers are used instead of a list_head to make it\n- * easier to add segments to tail and remove them from the head without the\n- * need for a lock.\n- */\n-struct folio_queue {\n-\tstruct folio_batch\tvec;\t\t/* Folios in the queue segment */\n-\tu8\t\t\torders[PAGEVEC_SIZE]; /* Order of each folio */\n-\tstruct folio_queue\t*next;\t\t/* Next queue segment or NULL */\n-\tstruct folio_queue\t*prev;\t\t/* Previous queue segment of NULL */\n-\tunsigned long\t\tmarks;\t\t/* 1-bit mark per folio */\n-\tunsigned long\t\tmarks2;\t\t/* Second 1-bit mark per folio */\n-#if PAGEVEC_SIZE > BITS_PER_LONG\n-#error marks is not big enough\n-#endif\n-\tunsigned int\t\trreq_id;\n-\tunsigned int\t\tdebug_id;\n-};\n-\n-/**\n- * folioq_init - Initialise a folio queue segment\n- * @folioq: The segment to initialise\n- * @rreq_id: The request identifier to use in tracelines.\n- *\n- * Initialise a folio queue segment and set an identifier to be used in traces.\n- *\n- * Note that the folio pointers are left uninitialised.\n- */\n-static inline void folioq_init(struct folio_queue *folioq, unsigned int rreq_id)\n-{\n-\tfolio_batch_init(&folioq->vec);\n-\tfolioq->next = NULL;\n-\tfolioq->prev = NULL;\n-\tfolioq->marks = 0;\n-\tfolioq->marks2 = 0;\n-\tfolioq->rreq_id = rreq_id;\n-\tfolioq->debug_id = 0;\n-}\n-\n-/**\n- * folioq_nr_slots: Query the capacity of a folio queue segment\n- * @folioq: The segment to query\n- *\n- * Query the number of folios that a particular folio queue segment might hold.\n- * [!] NOTE: This must not be assumed to be the same for every segment!\n- */\n-static inline unsigned int folioq_nr_slots(const struct folio_queue *folioq)\n-{\n-\treturn PAGEVEC_SIZE;\n-}\n-\n-/**\n- * folioq_count: Query the occupancy of a folio queue segment\n- * @folioq: The segment to query\n- *\n- * Query the number of folios that have been added to a folio queue segment.\n- * Note that this is not decreased as folios are removed from a segment.\n- */\n-static inline unsigned int folioq_count(struct folio_queue *folioq)\n-{\n-\treturn folio_batch_count(&folioq->vec);\n-}\n-\n-/**\n- * folioq_full: Query if a folio queue segment is full\n- * @folioq: The segment to query\n- *\n- * Query if a folio queue segment is fully occupied. Note that this does not\n- * change if folios are removed from a segment.\n- */\n-static inline bool folioq_full(struct folio_queue *folioq)\n-{\n-\t//return !folio_batch_space(&folioq->vec);\n-\treturn folioq_count(folioq) >= folioq_nr_slots(folioq);\n-}\n-\n-/**\n- * folioq_is_marked: Check first folio mark in a folio queue segment\n- * @folioq: The segment to query\n- * @slot: The slot number of the folio to query\n- *\n- * Determine if the first mark is set for the folio in the specified slot in a\n- * folio queue segment.\n- */\n-static inline bool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot)\n-{\n-\treturn test_bit(slot, &folioq->marks);\n-}\n-\n-/**\n- * folioq_mark: Set the first mark on a folio in a folio queue segment\n- * @folioq: The segment to modify\n- * @slot: The slot number of the folio to modify\n- *\n- * Set the first mark for the folio in the specified slot in a folio queue\n- * segment.\n- */\n-static inline void folioq_mark(struct folio_queue *folioq, unsigned int slot)\n-{\n-\tset_bit(slot, &folioq->marks);\n-}\n-\n-/**\n- * folioq_unmark: Clear the first mark on a folio in a folio queue segment\n- * @folioq: The segment to modify\n- * @slot: The slot number of the folio to modify\n- *\n- * Clear the first mark for the folio in the specified slot in a folio queue\n- * segment.\n- */\n-static inline void folioq_unmark(struct folio_queue *folioq, unsigned int slot)\n-{\n-\tclear_bit(slot, &folioq->marks);\n-}\n-\n-/**\n- * folioq_is_marked2: Check second folio mark in a folio queue segment\n- * @folioq: The segment to query\n- * @slot: The slot number of the folio to query\n- *\n- * Determine if the second mark is set for the folio in the specified slot in a\n- * folio queue segment.\n- */\n-static inline bool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot)\n-{\n-\treturn test_bit(slot, &folioq->marks2);\n-}\n-\n-/**\n- * folioq_mark2: Set the second mark on a folio in a folio queue segment\n- * @folioq: The segment to modify\n- * @slot: The slot number of the folio to modify\n- *\n- * Set the second mark for the folio in the specified slot in a folio queue\n- * segment.\n- */\n-static inline void folioq_mark2(struct folio_queue *folioq, unsigned int slot)\n-{\n-\tset_bit(slot, &folioq->marks2);\n-}\n-\n-/**\n- * folioq_unmark2: Clear the second mark on a folio in a folio queue segment\n- * @folioq: The segment to modify\n- * @slot: The slot number of the folio to modify\n- *\n- * Clear the second mark for the folio in the specified slot in a folio queue\n- * segment.\n- */\n-static inline void folioq_unmark2(struct folio_queue *folioq, unsigned int slot)\n-{\n-\tclear_bit(slot, &folioq->marks2);\n-}\n-\n-/**\n- * folioq_append: Add a folio to a folio queue segment\n- * @folioq: The segment to add to\n- * @folio: The folio to add\n- *\n- * Add a folio to the tail of the sequence in a folio queue segment, increasing\n- * the occupancy count and returning the slot number for the folio just added.\n- * The folio size is extracted and stored in the queue and the marks are left\n- * unmodified.\n- *\n- * Note that it's left up to the caller to check that the segment capacity will\n- * not be exceeded and to extend the queue.\n- */\n-static inline unsigned int folioq_append(struct folio_queue *folioq, struct folio *folio)\n-{\n-\tunsigned int slot = folioq->vec.nr++;\n-\n-\tfolioq->vec.folios[slot] = folio;\n-\tfolioq->orders[slot] = folio_order(folio);\n-\treturn slot;\n-}\n-\n-/**\n- * folioq_append_mark: Add a folio to a folio queue segment\n- * @folioq: The segment to add to\n- * @folio: The folio to add\n- *\n- * Add a folio to the tail of the sequence in a folio queue segment, increasing\n- * the occupancy count and returning the slot number for the folio just added.\n- * The folio size is extracted and stored in the queue, the first mark is set\n- * and and the second and third marks are left unmodified.\n- *\n- * Note that it's left up to the caller to check that the segment capacity will\n- * not be exceeded and to extend the queue.\n- */\n-static inline unsigned int folioq_append_mark(struct folio_queue *folioq, struct folio *folio)\n-{\n-\tunsigned int slot = folioq->vec.nr++;\n-\n-\tfolioq->vec.folios[slot] = folio;\n-\tfolioq->orders[slot] = folio_order(folio);\n-\tfolioq_mark(folioq, slot);\n-\treturn slot;\n-}\n-\n-/**\n- * folioq_folio: Get a folio from a folio queue segment\n- * @folioq: The segment to access\n- * @slot: The folio slot to access\n- *\n- * Retrieve the folio in the specified slot from a folio queue segment. Note\n- * that no bounds check is made and if the slot hasn't been added into yet, the\n- * pointer will be undefined. If the slot has been cleared, NULL will be\n- * returned.\n- */\n-static inline struct folio *folioq_folio(const struct folio_queue *folioq, unsigned int slot)\n-{\n-\treturn folioq->vec.folios[slot];\n-}\n-\n-/**\n- * folioq_folio_order: Get the order of a folio from a folio queue segment\n- * @folioq: The segment to access\n- * @slot: The folio slot to access\n- *\n- * Retrieve the order of the folio in the specified slot from a folio queue\n- * segment. Note that no bounds check is made and if the slot hasn't been\n- * added into yet, the order returned will be 0.\n- */\n-static inline unsigned int folioq_folio_order(const struct folio_queue *folioq, unsigned int slot)\n-{\n-\treturn folioq->orders[slot];\n-}\n-\n-/**\n- * folioq_folio_size: Get the size of a folio from a folio queue segment\n- * @folioq: The segment to access\n- * @slot: The folio slot to access\n- *\n- * Retrieve the size of the folio in the specified slot from a folio queue\n- * segment. Note that no bounds check is made and if the slot hasn't been\n- * added into yet, the size returned will be PAGE_SIZE.\n- */\n-static inline size_t folioq_folio_size(const struct folio_queue *folioq, unsigned int slot)\n-{\n-\treturn PAGE_SIZE << folioq_folio_order(folioq, slot);\n-}\n-\n-/**\n- * folioq_clear: Clear a folio from a folio queue segment\n- * @folioq: The segment to clear\n- * @slot: The folio slot to clear\n- *\n- * Clear a folio from a sequence in a folio queue segment and clear its marks.\n- * The occupancy count is left unchanged.\n- */\n-static inline void folioq_clear(struct folio_queue *folioq, unsigned int slot)\n-{\n-\tfolioq->vec.folios[slot] = NULL;\n-\tfolioq_unmark(folioq, slot);\n-\tfolioq_unmark2(folioq, slot);\n-}\n-\n-#endif /* _LINUX_FOLIO_QUEUE_H */\ndiff --git a/include/linux/rolling_buffer.h b/include/linux/rolling_buffer.h\ndeleted file mode 100644\nindex b35ef43f325f..000000000000\n--- a/include/linux/rolling_buffer.h\n+++ /dev/null\n@@ -1,64 +0,0 @@\n-/* SPDX-License-Identifier: GPL-2.0-or-later */\n-/* Rolling buffer of folios\n- *\n- * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved.\n- * Written by David Howells (dhowells@redhat.com)\n- */\n-\n-#ifndef _ROLLING_BUFFER_H\n-#define _ROLLING_BUFFER_H\n-\n-#include <linux/folio_queue.h>\n-#include <linux/uio.h>\n-\n-/*\n- * Rolling buffer. Whilst the buffer is live and in use, folios and folio\n- * queue segments can be added to one end by one thread and removed from the\n- * other end by another thread. The buffer isn't allowed to be empty; it must\n- * always have at least one folio_queue in it so that neither side has to\n- * modify both queue pointers.\n- *\n- * The iterator in the buffer is extended as buffers are inserted. It can be\n- * snapshotted to use a segment of the buffer.\n- */\n-struct rolling_buffer {\n-\tstruct folio_queue\t*head;\t\t/* Producer's insertion point */\n-\tstruct folio_queue\t*tail;\t\t/* Consumer's removal point */\n-\tstruct iov_iter\t\titer;\t\t/* Iterator tracking what's left in the buffer */\n-\tu8\t\t\tnext_head_slot;\t/* Next slot in ->head */\n-\tu8\t\t\tfirst_tail_slot; /* First slot in ->tail */\n-};\n-\n-/*\n- * Snapshot of a rolling buffer.\n- */\n-struct rolling_buffer_snapshot {\n-\tstruct folio_queue\t*curr_folioq;\t/* Queue segment in which current folio resides */\n-\tunsigned char\t\tcurr_slot;\t/* Folio currently being read */\n-\tunsigned char\t\tcurr_order;\t/* Order of folio */\n-};\n-\n-/* Marks to store per-folio in the internal folio_queue structs. */\n-#define ROLLBUF_MARK_1\tBIT(0)\n-#define ROLLBUF_MARK_2\tBIT(1)\n-\n-int rolling_buffer_init(struct rolling_buffer *roll, unsigned int rreq_id,\n-\t\t\tunsigned int direction);\n-int rolling_buffer_make_space(struct rolling_buffer *roll);\n-ssize_t rolling_buffer_load_from_ra(struct rolling_buffer *roll,\n-\t\t\t\t struct readahead_control *ractl,\n-\t\t\t\t struct folio_batch *put_batch);\n-ssize_t rolling_buffer_bulk_load_from_ra(struct rolling_buffer *roll,\n-\t\t\t\t\t struct readahead_control *ractl,\n-\t\t\t\t\t unsigned int rreq_id);\n-ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio,\n-\t\t\t unsigned int flags);\n-struct folio_queue *rolling_buffer_delete_spent(struct rolling_buffer *roll);\n-void rolling_buffer_clear(struct rolling_buffer *roll);\n-\n-static inline void rolling_buffer_advance(struct rolling_buffer *roll, size_t amount)\n-{\n-\tiov_iter_advance(&roll->iter, amount);\n-}\n-\n-#endif /* _ROLLING_BUFFER_H */\n", "prefixes": [ "23/26" ] }