Remove the rolling_buffer implementation as it has been replaced with the use of bvecq_pos. Signed-off-by: David Howells Reviewed-by: Paulo Alcantara cc: Matthew Wilcox cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/netfs/rolling_buffer.c | 182 --------------------------------- include/linux/rolling_buffer.h | 47 --------- 2 files changed, 229 deletions(-) delete mode 100644 fs/netfs/rolling_buffer.c delete mode 100644 include/linux/rolling_buffer.h diff --git a/fs/netfs/rolling_buffer.c b/fs/netfs/rolling_buffer.c deleted file mode 100644 index 66ce9add4012..000000000000 --- a/fs/netfs/rolling_buffer.c +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* Rolling buffer helpers - * - * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - */ - -#include -#include -#include -#include -#include -#include "internal.h" - -/* - * Initialise a rolling buffer. We allocate an empty folio queue struct to so - * that the pointers can be independently driven by the producer and the - * consumer. - */ -int rolling_buffer_init(struct rolling_buffer *roll, unsigned int direction, - gfp_t gfp, bool for_writeback) -{ - struct bvecq *bq; - - roll->for_writeback = for_writeback; - - bq = bvecq_alloc_one(BVECQ_POOL_SLOTS, gfp, for_writeback); - if (!bq) - return -ENOMEM; - - roll->head = bq; - roll->tail = bq; - iov_iter_bvec_queue(&roll->iter, direction, bq, 0, 0, 0); - return 0; -} - -/* - * Add another bvecq to a rolling buffer if there's no space left. - */ -int rolling_buffer_make_space(struct rolling_buffer *roll, gfp_t gfp) -{ - struct bvecq *bq, *head = roll->head; - - if (!bvecq_is_full(head)) - return 0; - - bq = bvecq_alloc_one(BVECQ_POOL_SLOTS, gfp, roll->for_writeback); - if (!bq) - return -ENOMEM; - - roll->head = bq; - if (bvecq_is_full(head)) { - /* Make sure we don't leave the master iterator pointing to a - * block that might get immediately consumed. - */ - if (roll->iter.bvecq == head && - roll->iter.bvecq_slot == head->nr_slots) { - roll->iter.bvecq = bq; - roll->iter.bvecq_slot = 0; - } - } - - /* Make sure the initialisation is stored before the next pointer. - * - * [!] NOTE: After we set head->next, the consumer is at liberty to - * immediately delete the old head. - */ - bvecq_append(head, bq); - return 0; -} - -/* - * Decant the entire list of folios to read into a rolling buffer. - */ -ssize_t rolling_buffer_bulk_load_from_ra(struct rolling_buffer *roll, - struct readahead_control *ractl, - gfp_t gfp) -{ - struct bvecq *bq; - size_t loaded = 0; - - while (ractl->_nr_pages - ractl->_batch_count > 0) { - struct page **pages; - unsigned int nr; - - /* Allocate a bvecq to put some folios into and attach it to - * the rolling buffer. - */ - bq = bvecq_alloc_one(BVECQ_POOL_SLOTS, gfp, false); - if (!bq) - goto nomem_unlock; - bq->mem_type = BVECQ_MEM_EXTERNAL; /* Folio cleanup handled separately. */ - - if (!roll->tail) - roll->tail = bq; - else - bvecq_append(roll->head, bq); - roll->head = bq; - - /* Get a bunch of folios and note their sizes. */ - pages = (struct page **)(bq->bv + bq->max_slots); - pages -= bq->max_slots; - nr = __readahead_batch(ractl, pages, bq->max_slots); - if (WARN_ON_ONCE(!nr)) - break; - - for (int slot = 0; slot < nr; slot++) { - struct folio *folio = page_folio(pages[slot]); - size_t len = folio_size(folio); - - bvec_set_folio(&bq->bv[slot], folio, len, 0); - loaded += len; - trace_netfs_folio(folio, netfs_folio_trace_read); - } - - bvecq_filled_to(bq, nr); - } - - WRITE_ONCE(roll->iter.count, loaded); - iov_iter_bvec_queue(&roll->iter, ITER_DEST, roll->tail, 0, 0, loaded); - return loaded; - -nomem_unlock: - for (bq = roll->tail; bq; bq = bq->next) { - for (int slot = 0; slot < bq->nr_slots; slot++) { - struct folio *folio = bvec_folio(&bq->bv[slot]); - - folio_unlock(folio); - folio_put(folio); - } - } - rolling_buffer_clear(roll); - roll->head = NULL; - roll->tail = NULL; - return -ENOMEM; -} - -/* - * Append a folio to the rolling buffer. - */ -ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio, - gfp_t gfp) -{ - ssize_t size = folio_size(folio); - int slot; - - if (rolling_buffer_make_space(roll, gfp) < 0) - return -ENOMEM; - - slot = roll->head->nr_slots; - bvec_set_folio(&roll->head->bv[slot], folio, size, 0); - bvecq_filled_to(roll->head, slot + 1); - - WRITE_ONCE(roll->iter.count, roll->iter.count + size); - return size; -} - -/* - * Delete a spent buffer from a rolling queue and return the next in line. We - * don't return the last buffer to keep the pointers independent, but return - * NULL instead. - */ -struct bvecq *rolling_buffer_delete_spent(struct rolling_buffer *roll) -{ - struct bvecq *spent = roll->tail, *next = bvecq_next(spent); - - if (!next) - return NULL; - next->prev = NULL; - roll->tail = next; - spent->next = NULL; - bvecq_put(spent); - return next; -} - -/* - * Clear out a rolling queue. - */ -void rolling_buffer_clear(struct rolling_buffer *roll) -{ - bvecq_put(roll->tail); -} diff --git a/include/linux/rolling_buffer.h b/include/linux/rolling_buffer.h deleted file mode 100644 index 5c0bc4221f01..000000000000 --- a/include/linux/rolling_buffer.h +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Rolling buffer of folios - * - * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - */ - -#ifndef _ROLLING_BUFFER_H -#define _ROLLING_BUFFER_H - -#include -#include - -/* - * Rolling buffer. Whilst the buffer is live and in use, folios and bvecq - * segments can be added to one end by one thread and removed from the other - * end by another thread. The buffer isn't allowed to be empty; it must always - * have at least one bvecq in it so that neither side has to modify both queue - * pointers. - * - * The iterator in the buffer is extended as buffers are inserted. It can be - * snapshotted to use a segment of the buffer. - */ -struct rolling_buffer { - struct bvecq *head; /* Producer's insertion point */ - struct bvecq *tail; /* Consumer's removal point */ - struct iov_iter iter; /* Iterator tracking what's left in the buffer */ - u8 first_tail_slot; /* First slot in ->tail */ - bool for_writeback; /* T if being used for writeback */ -}; - -int rolling_buffer_init(struct rolling_buffer *roll, unsigned int direction, - gfp_t gfp, bool for_writeback); -int rolling_buffer_make_space(struct rolling_buffer *roll, gfp_t gfp); -ssize_t rolling_buffer_bulk_load_from_ra(struct rolling_buffer *roll, - struct readahead_control *ractl, - gfp_t gfp); -ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio, gfp_t gfp); -struct bvecq *rolling_buffer_delete_spent(struct rolling_buffer *roll); -void rolling_buffer_clear(struct rolling_buffer *roll); - -static inline void rolling_buffer_advance(struct rolling_buffer *roll, size_t amount) -{ - iov_iter_advance(&roll->iter, amount); -} - -#endif /* _ROLLING_BUFFER_H */