History

mm: add new readahead_control API

Filesystems which implement the upcoming ->readahead method will get their pages by calling readahead_page() or readahead_page_batch(). These functions support large pages, even though none of the filesystems to be converted do yet.

Matthew Wilcox (Oracle) committed 6 years ago

Commit 042124c1 parent ad4ae1c1 file · +140 −0Browse files

Showing the changes to include/linux (1 of 1 file). Show all

Unified · Split

include/linux/pagemap.h+140−0
@@ -642,6 +642,146 @@ static inline int add_to_page_cache(struct page *page, · 641 unmodified lines
642642 return error;
643643 }
644644
645+/**
646+ * struct readahead_control - Describes a readahead request.
647+ *
648+ * A readahead request is for consecutive pages. Filesystems which
649+ * implement the ->readahead method should call readahead_page() or
650+ * readahead_page_batch() in a loop and attempt to start I/O against
651+ * each page in the request.
652+ *
653+ * Most of the fields in this struct are private and should be accessed
654+ * by the functions below.
655+ *
656+ * @file: The file, used primarily by network filesystems for authentication.
657+ * May be NULL if invoked internally by the filesystem.
658+ * @mapping: Readahead this filesystem object.
659+ */
660+struct readahead_control {
661+ struct file *file;
662+ struct address_space *mapping;
663+/* private: use the readahead_* accessors instead */
664+ pgoff_t _index;
665+ unsigned int _nr_pages;
666+ unsigned int _batch_count;
667+};
668+
669+/**
670+ * readahead_page - Get the next page to read.
671+ * @rac: The current readahead request.
672+ *
673+ * Context: The page is locked and has an elevated refcount. The caller
674+ * should decreases the refcount once the page has been submitted for I/O
675+ * and unlock the page once all I/O to that page has completed.
676+ * Return: A pointer to the next page, or %NULL if we are done.
677+ */
678+static inline struct page *readahead_page(struct readahead_control *rac)
679+{
680+ struct page *page;
681+
682+ BUG_ON(rac->_batch_count > rac->_nr_pages);
683+ rac->_nr_pages -= rac->_batch_count;
684+ rac->_index += rac->_batch_count;
685+
686+ if (!rac->_nr_pages) {
687+ rac->_batch_count = 0;
688+ return NULL;
689+ }
690+
691+ page = xa_load(&rac->mapping->i_pages, rac->_index);
692+ VM_BUG_ON_PAGE(!PageLocked(page), page);
693+ rac->_batch_count = hpage_nr_pages(page);
694+
695+ return page;
696+}
697+
698+static inline unsigned int __readahead_batch(struct readahead_control *rac,
699+ struct page **array, unsigned int array_sz)
700+{
701+ unsigned int i = 0;
702+ XA_STATE(xas, &rac->mapping->i_pages, 0);
703+ struct page *page;
704+
705+ BUG_ON(rac->_batch_count > rac->_nr_pages);
706+ rac->_nr_pages -= rac->_batch_count;
707+ rac->_index += rac->_batch_count;
708+ rac->_batch_count = 0;
709+
710+ xas_set(&xas, rac->_index);
711+ rcu_read_lock();
712+ xas_for_each(&xas, page, rac->_index + rac->_nr_pages - 1) {
713+ VM_BUG_ON_PAGE(!PageLocked(page), page);
714+ VM_BUG_ON_PAGE(PageTail(page), page);
715+ array[i++] = page;
716+ rac->_batch_count += hpage_nr_pages(page);
717+
718+ /*
719+ * The page cache isn't using multi-index entries yet,
720+ * so the xas cursor needs to be manually moved to the
721+ * next index. This can be removed once the page cache
722+ * is converted.
723+ */
724+ if (PageHead(page))
725+ xas_set(&xas, rac->_index + rac->_batch_count);
726+
727+ if (i == array_sz)
728+ break;
729+ }
730+ rcu_read_unlock();
731+
732+ return i;
733+}
734+
735+/**
736+ * readahead_page_batch - Get a batch of pages to read.
737+ * @rac: The current readahead request.
738+ * @array: An array of pointers to struct page.
739+ *
740+ * Context: The pages are locked and have an elevated refcount. The caller
741+ * should decreases the refcount once the page has been submitted for I/O
742+ * and unlock the page once all I/O to that page has completed.
743+ * Return: The number of pages placed in the array. 0 indicates the request
744+ * is complete.
745+ */
746+#define readahead_page_batch(rac, array) \
747+ __readahead_batch(rac, array, ARRAY_SIZE(array))
748+
749+/**
750+ * readahead_pos - The byte offset into the file of this readahead request.
751+ * @rac: The readahead request.
752+ */
753+static inline loff_t readahead_pos(struct readahead_control *rac)
754+{
755+ return (loff_t)rac->_index * PAGE_SIZE;
756+}
757+
758+/**
759+ * readahead_length - The number of bytes in this readahead request.
760+ * @rac: The readahead request.
761+ */
762+static inline loff_t readahead_length(struct readahead_control *rac)
763+{
764+ return (loff_t)rac->_nr_pages * PAGE_SIZE;
765+}
766+
767+/**
768+ * readahead_index - The index of the first page in this readahead request.
769+ * @rac: The readahead request.
770+ */
771+static inline pgoff_t readahead_index(struct readahead_control *rac)
772+{
773+ return rac->_index;
774+}
775+
776+/**
777+ * readahead_count - The number of pages in this readahead request.
778+ * @rac: The readahead request.
779+ */
780+static inline unsigned int readahead_count(struct readahead_control *rac)
781+{
782+ return rac->_nr_pages;
783+}
784+
645785 static inline unsigned long dir_pages(struct inode *inode)
646786 {
647787 return (unsigned long)(inode->i_size + PAGE_SIZE - 1) >>