libfs: Convert simple_write_begin and simple_write_end to use a folio
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Mon, 21 Aug 2023 14:13:22 +0000 (15:13 +0100)
committerChristian Brauner <brauner@kernel.org>
Mon, 21 Aug 2023 15:23:57 +0000 (17:23 +0200)
Remove a number of implicit calls to compound_head() and various calls
to compatibility functions.  This is not sufficient to enable support
for large folios; generic_perform_write() must be converted first.

Signed-off-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Message-Id: <20230821141322.2535459-1-willy@infradead.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/libfs.c

index 0ea7fedb0b7a17b187bbb5ba46e716b9e6cec70c..d80374ede638cb8db226dd49ed370c3df5897553 100644 (file)
@@ -548,21 +548,20 @@ int simple_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len,
                        struct page **pagep, void **fsdata)
 {
-       struct page *page;
-       pgoff_t index;
+       struct folio *folio;
 
-       index = pos >> PAGE_SHIFT;
+       folio = __filemap_get_folio(mapping, pos / PAGE_SIZE, FGP_WRITEBEGIN,
+                       mapping_gfp_mask(mapping));
+       if (IS_ERR(folio))
+               return PTR_ERR(folio);
 
-       page = grab_cache_page_write_begin(mapping, index);
-       if (!page)
-               return -ENOMEM;
-
-       *pagep = page;
+       *pagep = &folio->page;
 
-       if (!PageUptodate(page) && (len != PAGE_SIZE)) {
-               unsigned from = pos & (PAGE_SIZE - 1);
+       if (!folio_test_uptodate(folio) && (len != folio_size(folio))) {
+               size_t from = offset_in_folio(folio, pos);
 
-               zero_user_segments(page, 0, from, from + len, PAGE_SIZE);
+               folio_zero_segments(folio, 0, from,
+                               from + len, folio_size(folio));
        }
        return 0;
 }
@@ -594,17 +593,18 @@ static int simple_write_end(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned copied,
                        struct page *page, void *fsdata)
 {
-       struct inode *inode = page->mapping->host;
+       struct folio *folio = page_folio(page);
+       struct inode *inode = folio->mapping->host;
        loff_t last_pos = pos + copied;
 
-       /* zero the stale part of the page if we did a short copy */
-       if (!PageUptodate(page)) {
+       /* zero the stale part of the folio if we did a short copy */
+       if (!folio_test_uptodate(folio)) {
                if (copied < len) {
-                       unsigned from = pos & (PAGE_SIZE - 1);
+                       size_t from = offset_in_folio(folio, pos);
 
-                       zero_user(page, from + copied, len - copied);
+                       folio_zero_range(folio, from + copied, len - copied);
                }
-               SetPageUptodate(page);
+               folio_mark_uptodate(folio);
        }
        /*
         * No need to use i_size_read() here, the i_size
@@ -613,9 +613,9 @@ static int simple_write_end(struct file *file, struct address_space *mapping,
        if (last_pos > inode->i_size)
                i_size_write(inode, last_pos);
 
-       set_page_dirty(page);
-       unlock_page(page);
-       put_page(page);
+       folio_mark_dirty(folio);
+       folio_unlock(folio);
+       folio_put(folio);
 
        return copied;
 }