Merge tag 'mm-stable-2023-11-01-14-33' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / fs / ntfs / aops.c
index 4e158bc..71e31e7 100644 (file)
@@ -145,13 +145,12 @@ still_busy:
 }
 
 /**
- * ntfs_read_block - fill a @page of an address space with data
- * @page:      page cache page to fill with data
+ * ntfs_read_block - fill a @folio of an address space with data
+ * @folio:     page cache folio to fill with data
  *
- * Fill the page @page of the address space belonging to the @page->host inode.
  * We read each buffer asynchronously and when all buffers are read in, our io
  * completion handler ntfs_end_buffer_read_async(), if required, automatically
- * applies the mst fixups to the page before finally marking it uptodate and
+ * applies the mst fixups to the folio before finally marking it uptodate and
  * unlocking it.
  *
  * We only enforce allocated_size limit because i_size is checked for in
@@ -161,7 +160,7 @@ still_busy:
  *
  * Contains an adapted version of fs/buffer.c::block_read_full_folio().
  */
-static int ntfs_read_block(struct page *page)
+static int ntfs_read_block(struct folio *folio)
 {
        loff_t i_size;
        VCN vcn;
@@ -178,7 +177,7 @@ static int ntfs_read_block(struct page *page)
        int i, nr;
        unsigned char blocksize_bits;
 
-       vi = page->mapping->host;
+       vi = folio->mapping->host;
        ni = NTFS_I(vi);
        vol = ni->vol;
 
@@ -188,15 +187,10 @@ static int ntfs_read_block(struct page *page)
        blocksize = vol->sb->s_blocksize;
        blocksize_bits = vol->sb->s_blocksize_bits;
 
-       if (!page_has_buffers(page)) {
-               create_empty_buffers(page, blocksize, 0);
-               if (unlikely(!page_has_buffers(page))) {
-                       unlock_page(page);
-                       return -ENOMEM;
-               }
-       }
-       bh = head = page_buffers(page);
-       BUG_ON(!bh);
+       head = folio_buffers(folio);
+       if (!head)
+               head = create_empty_buffers(folio, blocksize, 0);
+       bh = head;
 
        /*
         * We may be racing with truncate.  To avoid some of the problems we
@@ -205,11 +199,11 @@ static int ntfs_read_block(struct page *page)
         * may leave some buffers unmapped which are now allocated.  This is
         * not a problem since these buffers will just get mapped when a write
         * occurs.  In case of a shrinking truncate, we will detect this later
-        * on due to the runlist being incomplete and if the page is being
+        * on due to the runlist being incomplete and if the folio is being
         * fully truncated, truncate will throw it away as soon as we unlock
         * it so no need to worry what we do with it.
         */
-       iblock = (s64)page->index << (PAGE_SHIFT - blocksize_bits);
+       iblock = (s64)folio->index << (PAGE_SHIFT - blocksize_bits);
        read_lock_irqsave(&ni->size_lock, flags);
        lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits;
        init_size = ni->initialized_size;
@@ -221,7 +215,7 @@ static int ntfs_read_block(struct page *page)
        }
        zblock = (init_size + blocksize - 1) >> blocksize_bits;
 
-       /* Loop through all the buffers in the page. */
+       /* Loop through all the buffers in the folio. */
        rl = NULL;
        nr = i = 0;
        do {
@@ -299,7 +293,7 @@ lock_retry_remap:
                        if (!err)
                                err = -EIO;
                        bh->b_blocknr = -1;
-                       SetPageError(page);
+                       folio_set_error(folio);
                        ntfs_error(vol->sb, "Failed to read from inode 0x%lx, "
                                        "attribute type 0x%x, vcn 0x%llx, "
                                        "offset 0x%x because its location on "
@@ -312,13 +306,13 @@ lock_retry_remap:
                /*
                 * Either iblock was outside lblock limits or
                 * ntfs_rl_vcn_to_lcn() returned error.  Just zero that portion
-                * of the page and set the buffer uptodate.
+                * of the folio and set the buffer uptodate.
                 */
 handle_hole:
                bh->b_blocknr = -1UL;
                clear_buffer_mapped(bh);
 handle_zblock:
-               zero_user(page, i * blocksize, blocksize);
+               folio_zero_range(folio, i * blocksize, blocksize);
                if (likely(!err))
                        set_buffer_uptodate(bh);
        } while (i++, iblock++, (bh = bh->b_this_page) != head);
@@ -349,11 +343,11 @@ handle_zblock:
                return 0;
        }
        /* No i/o was scheduled on any of the buffers. */
-       if (likely(!PageError(page)))
-               SetPageUptodate(page);
+       if (likely(!folio_test_error(folio)))
+               folio_mark_uptodate(folio);
        else /* Signal synchronous i/o error. */
                nr = -EIO;
-       unlock_page(page);
+       folio_unlock(folio);
        return nr;
 }
 
@@ -433,7 +427,7 @@ retry_readpage:
        /* NInoNonResident() == NInoIndexAllocPresent() */
        if (NInoNonResident(ni)) {
                /* Normal, non-resident data stream. */
-               return ntfs_read_block(page);
+               return ntfs_read_block(folio);
        }
        /*
         * Attribute is resident, implying it is not compressed or encrypted.
@@ -507,28 +501,29 @@ err_out:
 #ifdef NTFS_RW
 
 /**
- * ntfs_write_block - write a @page to the backing store
- * @page:      page cache page to write out
+ * ntfs_write_block - write a @folio to the backing store
+ * @folio:     page cache folio to write out
  * @wbc:       writeback control structure
  *
- * This function is for writing pages belonging to non-resident, non-mst
+ * This function is for writing folios belonging to non-resident, non-mst
  * protected attributes to their backing store.
  *
- * For a page with buffers, map and write the dirty buffers asynchronously
- * under page writeback. For a page without buffers, create buffers for the
- * page, then proceed as above.
+ * For a folio with buffers, map and write the dirty buffers asynchronously
+ * under folio writeback. For a folio without buffers, create buffers for the
+ * folio, then proceed as above.
  *
- * If a page doesn't have buffers the page dirty state is definitive. If a page
- * does have buffers, the page dirty state is just a hint, and the buffer dirty
- * state is definitive. (A hint which has rules: dirty buffers against a clean
- * page is illegal. Other combinations are legal and need to be handled. In
- * particular a dirty page containing clean buffers for example.)
+ * If a folio doesn't have buffers the folio dirty state is definitive. If
+ * a folio does have buffers, the folio dirty state is just a hint,
+ * and the buffer dirty state is definitive. (A hint which has rules:
+ * dirty buffers against a clean folio is illegal. Other combinations are
+ * legal and need to be handled. In particular a dirty folio containing
+ * clean buffers for example.)
  *
  * Return 0 on success and -errno on error.
  *
  * Based on ntfs_read_block() and __block_write_full_folio().
  */
-static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
+static int ntfs_write_block(struct folio *folio, struct writeback_control *wbc)
 {
        VCN vcn;
        LCN lcn;
@@ -546,41 +541,29 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
        bool need_end_writeback;
        unsigned char blocksize_bits;
 
-       vi = page->mapping->host;
+       vi = folio->mapping->host;
        ni = NTFS_I(vi);
        vol = ni->vol;
 
        ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
-                       "0x%lx.", ni->mft_no, ni->type, page->index);
+                       "0x%lx.", ni->mft_no, ni->type, folio->index);
 
        BUG_ON(!NInoNonResident(ni));
        BUG_ON(NInoMstProtected(ni));
        blocksize = vol->sb->s_blocksize;
        blocksize_bits = vol->sb->s_blocksize_bits;
-       if (!page_has_buffers(page)) {
-               BUG_ON(!PageUptodate(page));
-               create_empty_buffers(page, blocksize,
+       head = folio_buffers(folio);
+       if (!head) {
+               BUG_ON(!folio_test_uptodate(folio));
+               head = create_empty_buffers(folio, blocksize,
                                (1 << BH_Uptodate) | (1 << BH_Dirty));
-               if (unlikely(!page_has_buffers(page))) {
-                       ntfs_warning(vol->sb, "Error allocating page "
-                                       "buffers.  Redirtying page so we try "
-                                       "again later.");
-                       /*
-                        * Put the page back on mapping->dirty_pages, but leave
-                        * its buffers' dirty state as-is.
-                        */
-                       redirty_page_for_writepage(wbc, page);
-                       unlock_page(page);
-                       return 0;
-               }
        }
-       bh = head = page_buffers(page);
-       BUG_ON(!bh);
+       bh = head;
 
        /* NOTE: Different naming scheme to ntfs_read_block()! */
 
-       /* The first block in the page. */
-       block = (s64)page->index << (PAGE_SHIFT - blocksize_bits);
+       /* The first block in the folio. */
+       block = (s64)folio->index << (PAGE_SHIFT - blocksize_bits);
 
        read_lock_irqsave(&ni->size_lock, flags);
        i_size = i_size_read(vi);
@@ -597,14 +580,14 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
         * Be very careful.  We have no exclusion from block_dirty_folio
         * here, and the (potentially unmapped) buffers may become dirty at
         * any time.  If a buffer becomes dirty here after we've inspected it
-        * then we just miss that fact, and the page stays dirty.
+        * then we just miss that fact, and the folio stays dirty.
         *
         * Buffers outside i_size may be dirtied by block_dirty_folio;
         * handle that here by just cleaning them.
         */
 
        /*
-        * Loop through all the buffers in the page, mapping all the dirty
+        * Loop through all the buffers in the folio, mapping all the dirty
         * buffers to disk addresses and handling any aliases from the
         * underlying block device's mapping.
         */
@@ -616,13 +599,13 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
                if (unlikely(block >= dblock)) {
                        /*
                         * Mapped buffers outside i_size will occur, because
-                        * this page can be outside i_size when there is a
+                        * this folio can be outside i_size when there is a
                         * truncate in progress. The contents of such buffers
                         * were zeroed by ntfs_writepage().
                         *
                         * FIXME: What about the small race window where
                         * ntfs_writepage() has not done any clearing because
-                        * the page was within i_size but before we get here,
+                        * the folio was within i_size but before we get here,
                         * vmtruncate() modifies i_size?
                         */
                        clear_buffer_dirty(bh);
@@ -638,38 +621,38 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
                if (unlikely((block >= iblock) &&
                                (initialized_size < i_size))) {
                        /*
-                        * If this page is fully outside initialized
-                        * size, zero out all pages between the current
-                        * initialized size and the current page. Just
+                        * If this folio is fully outside initialized
+                        * size, zero out all folios between the current
+                        * initialized size and the current folio. Just
                         * use ntfs_read_folio() to do the zeroing
                         * transparently.
                         */
                        if (block > iblock) {
                                // TODO:
-                               // For each page do:
-                               // - read_cache_page()
-                               // Again for each page do:
-                               // - wait_on_page_locked()
-                               // - Check (PageUptodate(page) &&
-                               //                      !PageError(page))
+                               // For each folio do:
+                               // - read_cache_folio()
+                               // Again for each folio do:
+                               // - wait_on_folio_locked()
+                               // - Check (folio_test_uptodate(folio) &&
+                               //              !folio_test_error(folio))
                                // Update initialized size in the attribute and
                                // in the inode.
-                               // Again, for each page do:
+                               // Again, for each folio do:
                                //      block_dirty_folio();
-                               // put_page()
+                               // folio_put()
                                // We don't need to wait on the writes.
                                // Update iblock.
                        }
                        /*
-                        * The current page straddles initialized size. Zero
+                        * The current folio straddles initialized size. Zero
                         * all non-uptodate buffers and set them uptodate (and
                         * dirty?). Note, there aren't any non-uptodate buffers
-                        * if the page is uptodate.
-                        * FIXME: For an uptodate page, the buffers may need to
+                        * if the folio is uptodate.
+                        * FIXME: For an uptodate folio, the buffers may need to
                         * be written out because they were not initialized on
                         * disk before.
                         */
-                       if (!PageUptodate(page)) {
+                       if (!folio_test_uptodate(folio)) {
                                // TODO:
                                // Zero any non-uptodate buffers up to i_size.
                                // Set them uptodate and dirty.
@@ -727,14 +710,14 @@ lock_retry_remap:
                        unsigned long *bpos, *bend;
 
                        /* Check if the buffer is zero. */
-                       kaddr = kmap_atomic(page);
-                       bpos = (unsigned long *)(kaddr + bh_offset(bh));
-                       bend = (unsigned long *)((u8*)bpos + blocksize);
+                       kaddr = kmap_local_folio(folio, bh_offset(bh));
+                       bpos = (unsigned long *)kaddr;
+                       bend = (unsigned long *)(kaddr + blocksize);
                        do {
                                if (unlikely(*bpos))
                                        break;
                        } while (likely(++bpos < bend));
-                       kunmap_atomic(kaddr);
+                       kunmap_local(kaddr);
                        if (bpos == bend) {
                                /*
                                 * Buffer is zero and sparse, no need to write
@@ -774,7 +757,7 @@ lock_retry_remap:
                if (err == -ENOENT || lcn == LCN_ENOENT) {
                        bh->b_blocknr = -1;
                        clear_buffer_dirty(bh);
-                       zero_user(page, bh_offset(bh), blocksize);
+                       folio_zero_range(folio, bh_offset(bh), blocksize);
                        set_buffer_uptodate(bh);
                        err = 0;
                        continue;
@@ -801,7 +784,7 @@ lock_retry_remap:
        bh = head;
 
        /* Just an optimization, so ->read_folio() is not called later. */
-       if (unlikely(!PageUptodate(page))) {
+       if (unlikely(!folio_test_uptodate(folio))) {
                int uptodate = 1;
                do {
                        if (!buffer_uptodate(bh)) {
@@ -811,7 +794,7 @@ lock_retry_remap:
                        }
                } while ((bh = bh->b_this_page) != head);
                if (uptodate)
-                       SetPageUptodate(page);
+                       folio_mark_uptodate(folio);
        }
 
        /* Setup all mapped, dirty buffers for async write i/o. */
@@ -826,7 +809,7 @@ lock_retry_remap:
                } else if (unlikely(err)) {
                        /*
                         * For the error case. The buffer may have been set
-                        * dirty during attachment to a dirty page.
+                        * dirty during attachment to a dirty folio.
                         */
                        if (err != -ENOMEM)
                                clear_buffer_dirty(bh);
@@ -839,20 +822,20 @@ lock_retry_remap:
                        err = 0;
                else if (err == -ENOMEM) {
                        ntfs_warning(vol->sb, "Error allocating memory. "
-                                       "Redirtying page so we try again "
+                                       "Redirtying folio so we try again "
                                        "later.");
                        /*
-                        * Put the page back on mapping->dirty_pages, but
+                        * Put the folio back on mapping->dirty_pages, but
                         * leave its buffer's dirty state as-is.
                         */
-                       redirty_page_for_writepage(wbc, page);
+                       folio_redirty_for_writepage(wbc, folio);
                        err = 0;
                } else
-                       SetPageError(page);
+                       folio_set_error(folio);
        }
 
-       BUG_ON(PageWriteback(page));
-       set_page_writeback(page);       /* Keeps try_to_free_buffers() away. */
+       BUG_ON(folio_test_writeback(folio));
+       folio_start_writeback(folio);   /* Keeps try_to_free_buffers() away. */
 
        /* Submit the prepared buffers for i/o. */
        need_end_writeback = true;
@@ -864,11 +847,11 @@ lock_retry_remap:
                }
                bh = next;
        } while (bh != head);
-       unlock_page(page);
+       folio_unlock(folio);
 
-       /* If no i/o was started, need to end_page_writeback(). */
+       /* If no i/o was started, need to end writeback here. */
        if (unlikely(need_end_writeback))
-               end_page_writeback(page);
+               folio_end_writeback(folio);
 
        ntfs_debug("Done.");
        return err;
@@ -1337,8 +1320,9 @@ done:
  */
 static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
 {
+       struct folio *folio = page_folio(page);
        loff_t i_size;
-       struct inode *vi = page->mapping->host;
+       struct inode *vi = folio->mapping->host;
        ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
        char *addr;
        ntfs_attr_search_ctx *ctx = NULL;
@@ -1347,14 +1331,13 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
        int err;
 
 retry_writepage:
-       BUG_ON(!PageLocked(page));
+       BUG_ON(!folio_test_locked(folio));
        i_size = i_size_read(vi);
-       /* Is the page fully outside i_size? (truncate in progress) */
-       if (unlikely(page->index >= (i_size + PAGE_SIZE - 1) >>
+       /* Is the folio fully outside i_size? (truncate in progress) */
+       if (unlikely(folio->index >= (i_size + PAGE_SIZE - 1) >>
                        PAGE_SHIFT)) {
-               struct folio *folio = page_folio(page);
                /*
-                * The page may have dirty, unmapped buffers.  Make them
+                * The folio may have dirty, unmapped buffers.  Make them
                 * freeable here, so the page does not leak.
                 */
                block_invalidate_folio(folio, 0, folio_size(folio));
@@ -1373,7 +1356,7 @@ retry_writepage:
        if (ni->type != AT_INDEX_ALLOCATION) {
                /* If file is encrypted, deny access, just like NT4. */
                if (NInoEncrypted(ni)) {
-                       unlock_page(page);
+                       folio_unlock(folio);
                        BUG_ON(ni->type != AT_DATA);
                        ntfs_debug("Denying write access to encrypted file.");
                        return -EACCES;
@@ -1384,14 +1367,14 @@ retry_writepage:
                        BUG_ON(ni->name_len);
                        // TODO: Implement and replace this with
                        // return ntfs_write_compressed_block(page);
-                       unlock_page(page);
+                       folio_unlock(folio);
                        ntfs_error(vi->i_sb, "Writing to compressed files is "
                                        "not supported yet.  Sorry.");
                        return -EOPNOTSUPP;
                }
                // TODO: Implement and remove this check.
                if (NInoNonResident(ni) && NInoSparse(ni)) {
-                       unlock_page(page);
+                       folio_unlock(folio);
                        ntfs_error(vi->i_sb, "Writing to sparse files is not "
                                        "supported yet.  Sorry.");
                        return -EOPNOTSUPP;
@@ -1400,34 +1383,34 @@ retry_writepage:
        /* NInoNonResident() == NInoIndexAllocPresent() */
        if (NInoNonResident(ni)) {
                /* We have to zero every time due to mmap-at-end-of-file. */
-               if (page->index >= (i_size >> PAGE_SHIFT)) {
-                       /* The page straddles i_size. */
-                       unsigned int ofs = i_size & ~PAGE_MASK;
-                       zero_user_segment(page, ofs, PAGE_SIZE);
+               if (folio->index >= (i_size >> PAGE_SHIFT)) {
+                       /* The folio straddles i_size. */
+                       unsigned int ofs = i_size & (folio_size(folio) - 1);
+                       folio_zero_segment(folio, ofs, folio_size(folio));
                }
                /* Handle mst protected attributes. */
                if (NInoMstProtected(ni))
                        return ntfs_write_mst_block(page, wbc);
                /* Normal, non-resident data stream. */
-               return ntfs_write_block(page, wbc);
+               return ntfs_write_block(folio, wbc);
        }
        /*
         * Attribute is resident, implying it is not compressed, encrypted, or
         * mst protected.  This also means the attribute is smaller than an mft
-        * record and hence smaller than a page, so can simply return error on
-        * any pages with index above 0.  Note the attribute can actually be
+        * record and hence smaller than a folio, so can simply return error on
+        * any folios with index above 0.  Note the attribute can actually be
         * marked compressed but if it is resident the actual data is not
         * compressed so we are ok to ignore the compressed flag here.
         */
-       BUG_ON(page_has_buffers(page));
-       BUG_ON(!PageUptodate(page));
-       if (unlikely(page->index > 0)) {
-               ntfs_error(vi->i_sb, "BUG()! page->index (0x%lx) > 0.  "
-                               "Aborting write.", page->index);
-               BUG_ON(PageWriteback(page));
-               set_page_writeback(page);
-               unlock_page(page);
-               end_page_writeback(page);
+       BUG_ON(folio_buffers(folio));
+       BUG_ON(!folio_test_uptodate(folio));
+       if (unlikely(folio->index > 0)) {
+               ntfs_error(vi->i_sb, "BUG()! folio->index (0x%lx) > 0.  "
+                               "Aborting write.", folio->index);
+               BUG_ON(folio_test_writeback(folio));
+               folio_start_writeback(folio);
+               folio_unlock(folio);
+               folio_end_writeback(folio);
                return -EIO;
        }
        if (!NInoAttr(ni))
@@ -1460,12 +1443,12 @@ retry_writepage:
        if (unlikely(err))
                goto err_out;
        /*
-        * Keep the VM happy.  This must be done otherwise the radix-tree tag
-        * PAGECACHE_TAG_DIRTY remains set even though the page is clean.
+        * Keep the VM happy.  This must be done otherwise
+        * PAGECACHE_TAG_DIRTY remains set even though the folio is clean.
         */
-       BUG_ON(PageWriteback(page));
-       set_page_writeback(page);
-       unlock_page(page);
+       BUG_ON(folio_test_writeback(folio));
+       folio_start_writeback(folio);
+       folio_unlock(folio);
        attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
        i_size = i_size_read(vi);
        if (unlikely(attr_len > i_size)) {
@@ -1480,18 +1463,18 @@ retry_writepage:
                /* Shrinking cannot fail. */
                BUG_ON(err);
        }
-       addr = kmap_atomic(page);
-       /* Copy the data from the page to the mft record. */
+       addr = kmap_local_folio(folio, 0);
+       /* Copy the data from the folio to the mft record. */
        memcpy((u8*)ctx->attr +
                        le16_to_cpu(ctx->attr->data.resident.value_offset),
                        addr, attr_len);
-       /* Zero out of bounds area in the page cache page. */
-       memset(addr + attr_len, 0, PAGE_SIZE - attr_len);
-       kunmap_atomic(addr);
-       flush_dcache_page(page);
+       /* Zero out of bounds area in the page cache folio. */
+       memset(addr + attr_len, 0, folio_size(folio) - attr_len);
+       kunmap_local(addr);
+       flush_dcache_folio(folio);
        flush_dcache_mft_record_page(ctx->ntfs_ino);
-       /* We are done with the page. */
-       end_page_writeback(page);
+       /* We are done with the folio. */
+       folio_end_writeback(folio);
        /* Finally, mark the mft record dirty, so it gets written back. */
        mark_mft_record_dirty(ctx->ntfs_ino);
        ntfs_attr_put_search_ctx(ctx);
@@ -1502,18 +1485,18 @@ err_out:
                ntfs_warning(vi->i_sb, "Error allocating memory. Redirtying "
                                "page so we try again later.");
                /*
-                * Put the page back on mapping->dirty_pages, but leave its
+                * Put the folio back on mapping->dirty_pages, but leave its
                 * buffers' dirty state as-is.
                 */
-               redirty_page_for_writepage(wbc, page);
+               folio_redirty_for_writepage(wbc, folio);
                err = 0;
        } else {
                ntfs_error(vi->i_sb, "Resident attribute write failed with "
                                "error %i.", err);
-               SetPageError(page);
+               folio_set_error(folio);
                NVolSetErrors(ni->vol);
        }
-       unlock_page(page);
+       folio_unlock(folio);
        if (ctx)
                ntfs_attr_put_search_ctx(ctx);
        if (m)