Merge tag 'for_v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[linux-2.6-microblaze.git] / fs / f2fs / data.c
index 73683e5..be4da52 100644 (file)
@@ -202,7 +202,7 @@ static void f2fs_verify_bio(struct bio *bio)
                dic = (struct decompress_io_ctx *)page_private(page);
 
                if (dic) {
-                       if (refcount_dec_not_one(&dic->ref))
+                       if (atomic_dec_return(&dic->pending_pages))
                                continue;
                        f2fs_verify_pages(dic->rpages,
                                                dic->cluster_size);
@@ -517,7 +517,7 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi,
 
                        zero_user_segment(page, 0, PAGE_SIZE);
                        SetPagePrivate(page);
-                       set_page_private(page, (unsigned long)DUMMY_WRITTEN_PAGE);
+                       set_page_private(page, DUMMY_WRITTEN_PAGE);
                        lock_page(page);
                        if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE)
                                f2fs_bug_on(sbi, 1);
@@ -1416,7 +1416,7 @@ alloc:
        set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
        old_blkaddr = dn->data_blkaddr;
        f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr,
-                                       &sum, seg_type, NULL);
+                               &sum, seg_type, NULL);
        if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
                invalidate_mapping_pages(META_MAPPING(sbi),
                                        old_blkaddr, old_blkaddr);
@@ -1803,10 +1803,6 @@ static int get_data_block_dio(struct inode *inode, sector_t iblock,
 static int get_data_block_bmap(struct inode *inode, sector_t iblock,
                        struct buffer_head *bh_result, int create)
 {
-       /* Block number less than F2FS MAX BLOCKS */
-       if (unlikely(iblock >= F2FS_I_SB(inode)->max_file_blocks))
-               return -EFBIG;
-
        return __get_data_block(inode, iblock, bh_result, create,
                                                F2FS_GET_BLOCK_BMAP, NULL,
                                                NO_CHECK_TYPE, create);
@@ -2272,8 +2268,8 @@ submit_and_realloc:
                        if (IS_ERR(bio)) {
                                ret = PTR_ERR(bio);
                                dic->failed = true;
-                               if (refcount_sub_and_test(dic->nr_cpages - i,
-                                                       &dic->ref)) {
+                               if (!atomic_sub_return(dic->nr_cpages - i,
+                                                       &dic->pending_pages)) {
                                        f2fs_decompress_end_io(dic->rpages,
                                                        cc->cluster_size, true,
                                                        false);
@@ -3133,6 +3129,8 @@ next:
                        retry = 0;
                }
        }
+       if (f2fs_compressed_file(inode))
+               f2fs_destroy_compress_ctx(&cc);
 #endif
        if (retry) {
                index = 0;
@@ -3574,7 +3572,7 @@ static void f2fs_dio_end_io(struct bio *bio)
        bio->bi_private = dio->orig_private;
        bio->bi_end_io = dio->orig_end_io;
 
-       kvfree(dio);
+       kfree(dio);
 
        bio_endio(bio);
 }
@@ -3673,12 +3671,18 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
                                                                        err);
                        if (!do_opu)
                                set_inode_flag(inode, FI_UPDATE_WRITE);
+               } else if (err == -EIOCBQUEUED) {
+                       f2fs_update_iostat(F2FS_I_SB(inode), APP_DIRECT_IO,
+                                               count - iov_iter_count(iter));
                } else if (err < 0) {
                        f2fs_write_failed(mapping, offset + count);
                }
        } else {
                if (err > 0)
                        f2fs_update_iostat(sbi, APP_DIRECT_READ_IO, err);
+               else if (err == -EIOCBQUEUED)
+                       f2fs_update_iostat(F2FS_I_SB(inode), APP_DIRECT_READ_IO,
+                                               count - iov_iter_count(iter));
        }
 
 out:
@@ -3807,11 +3811,16 @@ static sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
        if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
                filemap_write_and_wait(mapping);
 
-       if (f2fs_compressed_file(inode))
-               blknr = f2fs_bmap_compress(inode, block);
+       /* Block number less than F2FS MAX BLOCKS */
+       if (unlikely(block >= F2FS_I_SB(inode)->max_file_blocks))
+               goto out;
 
-       if (!get_data_block_bmap(inode, block, &tmp, 0))
-               blknr = tmp.b_blocknr;
+       if (f2fs_compressed_file(inode)) {
+               blknr = f2fs_bmap_compress(inode, block);
+       } else {
+               if (!get_data_block_bmap(inode, block, &tmp, 0))
+                       blknr = tmp.b_blocknr;
+       }
 out:
        trace_f2fs_bmap(inode, block, blknr);
        return blknr;
@@ -3874,6 +3883,83 @@ int f2fs_migrate_page(struct address_space *mapping,
 #endif
 
 #ifdef CONFIG_SWAP
+static int check_swap_activate_fast(struct swap_info_struct *sis,
+                               struct file *swap_file, sector_t *span)
+{
+       struct address_space *mapping = swap_file->f_mapping;
+       struct inode *inode = mapping->host;
+       sector_t cur_lblock;
+       sector_t last_lblock;
+       sector_t pblock;
+       sector_t lowest_pblock = -1;
+       sector_t highest_pblock = 0;
+       int nr_extents = 0;
+       unsigned long nr_pblocks;
+       unsigned long len;
+       int ret;
+
+       /*
+        * Map all the blocks into the extent list.  This code doesn't try
+        * to be very smart.
+        */
+       cur_lblock = 0;
+       last_lblock = logical_to_blk(inode, i_size_read(inode));
+       len = i_size_read(inode);
+
+       while (cur_lblock <= last_lblock && cur_lblock < sis->max) {
+               struct buffer_head map_bh;
+               pgoff_t next_pgofs;
+
+               cond_resched();
+
+               memset(&map_bh, 0, sizeof(struct buffer_head));
+               map_bh.b_size = len - cur_lblock;
+
+               ret = get_data_block(inode, cur_lblock, &map_bh, 0,
+                                       F2FS_GET_BLOCK_FIEMAP, &next_pgofs);
+               if (ret)
+                       goto err_out;
+
+               /* hole */
+               if (!buffer_mapped(&map_bh))
+                       goto err_out;
+
+               pblock = map_bh.b_blocknr;
+               nr_pblocks = logical_to_blk(inode, map_bh.b_size);
+
+               if (cur_lblock + nr_pblocks >= sis->max)
+                       nr_pblocks = sis->max - cur_lblock;
+
+               if (cur_lblock) {       /* exclude the header page */
+                       if (pblock < lowest_pblock)
+                               lowest_pblock = pblock;
+                       if (pblock + nr_pblocks - 1 > highest_pblock)
+                               highest_pblock = pblock + nr_pblocks - 1;
+               }
+
+               /*
+                * We found a PAGE_SIZE-length, PAGE_SIZE-aligned run of blocks
+                */
+               ret = add_swap_extent(sis, cur_lblock, nr_pblocks, pblock);
+               if (ret < 0)
+                       goto out;
+               nr_extents += ret;
+               cur_lblock += nr_pblocks;
+       }
+       ret = nr_extents;
+       *span = 1 + highest_pblock - lowest_pblock;
+       if (cur_lblock == 0)
+               cur_lblock = 1; /* force Empty message */
+       sis->max = cur_lblock;
+       sis->pages = cur_lblock - 1;
+       sis->highest_bit = cur_lblock - 1;
+out:
+       return ret;
+err_out:
+       pr_err("swapon: swapfile has holes\n");
+       return -EINVAL;
+}
+
 /* Copied from generic_swapfile_activate() to check any holes */
 static int check_swap_activate(struct swap_info_struct *sis,
                                struct file *swap_file, sector_t *span)
@@ -3890,6 +3976,9 @@ static int check_swap_activate(struct swap_info_struct *sis,
        int nr_extents = 0;
        int ret;
 
+       if (PAGE_SIZE == F2FS_BLKSIZE)
+               return check_swap_activate_fast(sis, swap_file, span);
+
        blkbits = inode->i_blkbits;
        blocks_per_page = PAGE_SIZE >> blkbits;
 
@@ -3989,7 +4078,7 @@ static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file,
        if (ret)
                return ret;
 
-       if (f2fs_disable_compressed_file(inode))
+       if (!f2fs_disable_compressed_file(inode))
                return -EINVAL;
 
        ret = check_swap_activate(sis, file, span);