]> Git Repo - linux.git/blobdiff - fs/f2fs/data.c
s390: add pte_free_defer() for pgtables sharing page
[linux.git] / fs / f2fs / data.c
index 7165b1202f539c4ebde163c93bbd084748a41714..5882afe71d82bb1b36601f674898e671f08a6294 100644 (file)
@@ -383,6 +383,17 @@ static void f2fs_write_end_io(struct bio *bio)
        bio_put(bio);
 }
 
+#ifdef CONFIG_BLK_DEV_ZONED
+static void f2fs_zone_write_end_io(struct bio *bio)
+{
+       struct f2fs_bio_info *io = (struct f2fs_bio_info *)bio->bi_private;
+
+       bio->bi_private = io->bi_private;
+       complete(&io->zone_wait);
+       f2fs_write_end_io(bio);
+}
+#endif
+
 struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
                block_t blk_addr, sector_t *sector)
 {
@@ -639,6 +650,11 @@ int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi)
                        INIT_LIST_HEAD(&sbi->write_io[i][j].io_list);
                        INIT_LIST_HEAD(&sbi->write_io[i][j].bio_list);
                        init_f2fs_rwsem(&sbi->write_io[i][j].bio_list_lock);
+#ifdef CONFIG_BLK_DEV_ZONED
+                       init_completion(&sbi->write_io[i][j].zone_wait);
+                       sbi->write_io[i][j].zone_pending_bio = NULL;
+                       sbi->write_io[i][j].bi_private = NULL;
+#endif
                }
        }
 
@@ -965,6 +981,26 @@ alloc_new:
        return 0;
 }
 
+#ifdef CONFIG_BLK_DEV_ZONED
+static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
+{
+       int devi = 0;
+
+       if (f2fs_is_multi_device(sbi)) {
+               devi = f2fs_target_device_index(sbi, blkaddr);
+               if (blkaddr < FDEV(devi).start_blk ||
+                   blkaddr > FDEV(devi).end_blk) {
+                       f2fs_err(sbi, "Invalid block %x", blkaddr);
+                       return false;
+               }
+               blkaddr -= FDEV(devi).start_blk;
+       }
+       return bdev_zoned_model(FDEV(devi).bdev) == BLK_ZONED_HM &&
+               f2fs_blkz_is_seq(sbi, devi, blkaddr) &&
+               (blkaddr % sbi->blocks_per_blkz == sbi->blocks_per_blkz - 1);
+}
+#endif
+
 void f2fs_submit_page_write(struct f2fs_io_info *fio)
 {
        struct f2fs_sb_info *sbi = fio->sbi;
@@ -975,6 +1011,16 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
        f2fs_bug_on(sbi, is_read_io(fio->op));
 
        f2fs_down_write(&io->io_rwsem);
+
+#ifdef CONFIG_BLK_DEV_ZONED
+       if (f2fs_sb_has_blkzoned(sbi) && btype < META && io->zone_pending_bio) {
+               wait_for_completion_io(&io->zone_wait);
+               bio_put(io->zone_pending_bio);
+               io->zone_pending_bio = NULL;
+               io->bi_private = NULL;
+       }
+#endif
+
 next:
        if (fio->in_list) {
                spin_lock(&io->io_lock);
@@ -1038,6 +1084,18 @@ skip:
        if (fio->in_list)
                goto next;
 out:
+#ifdef CONFIG_BLK_DEV_ZONED
+       if (f2fs_sb_has_blkzoned(sbi) && btype < META &&
+                       is_end_zone_blkaddr(sbi, fio->new_blkaddr)) {
+               bio_get(io->bio);
+               reinit_completion(&io->zone_wait);
+               io->bi_private = io->bio->bi_private;
+               io->bio->bi_private = io;
+               io->bio->bi_end_io = f2fs_zone_write_end_io;
+               io->zone_pending_bio = io->bio;
+               __submit_merged_bio(io);
+       }
+#endif
        if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) ||
                                !f2fs_is_checkpoint_ready(sbi))
                __submit_merged_bio(io);
@@ -2173,7 +2231,6 @@ submit_and_realloc:
        f2fs_update_iostat(F2FS_I_SB(inode), NULL, FS_DATA_READ_IO,
                                                        F2FS_BLKSIZE);
        *last_block_in_bio = block_nr;
-       goto out;
 out:
        *bio_ret = bio;
        return ret;
@@ -2775,6 +2832,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
        loff_t psize = (loff_t)(page->index + 1) << PAGE_SHIFT;
        unsigned offset = 0;
        bool need_balance_fs = false;
+       bool quota_inode = IS_NOQUOTA(inode);
        int err = 0;
        struct f2fs_io_info fio = {
                .sbi = sbi,
@@ -2807,6 +2865,10 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
                if (S_ISDIR(inode->i_mode) &&
                                !is_sbi_flag_set(sbi, SBI_IS_CLOSE))
                        goto redirty_out;
+
+               /* keep data pages in remount-ro mode */
+               if (F2FS_OPTION(sbi).errors == MOUNT_ERRORS_READONLY)
+                       goto redirty_out;
                goto out;
        }
 
@@ -2832,19 +2894,19 @@ write:
                goto out;
 
        /* Dentry/quota blocks are controlled by checkpoint */
-       if (S_ISDIR(inode->i_mode) || IS_NOQUOTA(inode)) {
+       if (S_ISDIR(inode->i_mode) || quota_inode) {
                /*
                 * We need to wait for node_write to avoid block allocation during
                 * checkpoint. This can only happen to quota writes which can cause
                 * the below discard race condition.
                 */
-               if (IS_NOQUOTA(inode))
+               if (quota_inode)
                        f2fs_down_read(&sbi->node_write);
 
                fio.need_lock = LOCK_DONE;
                err = f2fs_do_write_data_page(&fio);
 
-               if (IS_NOQUOTA(inode))
+               if (quota_inode)
                        f2fs_up_read(&sbi->node_write);
 
                goto done;
@@ -4067,7 +4129,6 @@ const struct address_space_operations f2fs_dblock_aops = {
        .migrate_folio  = filemap_migrate_folio,
        .invalidate_folio = f2fs_invalidate_folio,
        .release_folio  = f2fs_release_folio,
-       .direct_IO      = noop_direct_IO,
        .bmap           = f2fs_bmap,
        .swap_activate  = f2fs_swap_activate,
        .swap_deactivate = f2fs_swap_deactivate,
This page took 0.042365 seconds and 4 git commands to generate.