f2fs: use list_for_each_entry{_safe} for simplyfying code
[cascardo/linux.git] / fs / f2fs / data.c
index 2261ccd..598bfa6 100644 (file)
@@ -45,7 +45,7 @@ static void f2fs_read_end_io(struct bio *bio, int err)
 
 static void f2fs_write_end_io(struct bio *bio, int err)
 {
-       struct f2fs_sb_info *sbi = F2FS_SB(bio->bi_io_vec->bv_page->mapping->host->i_sb);
+       struct f2fs_sb_info *sbi = bio->bi_private;
        struct bio_vec *bvec;
        int i;
 
@@ -55,15 +55,16 @@ static void f2fs_write_end_io(struct bio *bio, int err)
                if (unlikely(err)) {
                        SetPageError(page);
                        set_bit(AS_EIO, &page->mapping->flags);
-                       set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
-                       sbi->sb->s_flags |= MS_RDONLY;
+                       f2fs_stop_checkpoint(sbi);
                }
                end_page_writeback(page);
                dec_page_count(sbi, F2FS_WRITEBACK);
        }
 
-       if (bio->bi_private)
-               complete(bio->bi_private);
+       if (sbi->wait_io) {
+               complete(sbi->wait_io);
+               sbi->wait_io = NULL;
+       }
 
        if (!get_pages(sbi, F2FS_WRITEBACK) &&
                        !list_empty(&sbi->cp_wait.task_list))
@@ -86,6 +87,7 @@ static struct bio *__bio_alloc(struct f2fs_sb_info *sbi, block_t blk_addr,
        bio->bi_bdev = sbi->sb->s_bdev;
        bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr);
        bio->bi_end_io = is_read ? f2fs_read_end_io : f2fs_write_end_io;
+       bio->bi_private = sbi;
 
        return bio;
 }
@@ -113,7 +115,7 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
                 */
                if (fio->type == META_FLUSH) {
                        DECLARE_COMPLETION_ONSTACK(wait);
-                       io->bio->bi_private = &wait;
+                       io->sbi->wait_io = &wait;
                        submit_bio(rw, io->bio);
                        wait_for_completion(&wait);
                } else {
@@ -132,7 +134,7 @@ void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
 
        io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype];
 
-       mutex_lock(&io->io_mutex);
+       down_write(&io->io_rwsem);
 
        /* change META to META_FLUSH in the checkpoint procedure */
        if (type >= META_FLUSH) {
@@ -140,7 +142,7 @@ void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
                io->fio.rw = WRITE_FLUSH_FUA | REQ_META | REQ_PRIO;
        }
        __submit_merged_bio(io);
-       mutex_unlock(&io->io_mutex);
+       up_write(&io->io_rwsem);
 }
 
 /*
@@ -178,7 +180,7 @@ void f2fs_submit_page_mbio(struct f2fs_sb_info *sbi, struct page *page,
 
        verify_block_addr(sbi, blk_addr);
 
-       mutex_lock(&io->io_mutex);
+       down_write(&io->io_rwsem);
 
        if (!is_read)
                inc_page_count(sbi, F2FS_WRITEBACK);
@@ -202,7 +204,7 @@ alloc_new:
 
        io->last_block_in_bio = blk_addr;
 
-       mutex_unlock(&io->io_mutex);
+       up_write(&io->io_rwsem);
        trace_f2fs_submit_page_mbio(page, fio->rw, fio->type, blk_addr);
 }
 
@@ -797,48 +799,36 @@ static int f2fs_write_data_page(struct page *page,
         */
        offset = i_size & (PAGE_CACHE_SIZE - 1);
        if ((page->index >= end_index + 1) || !offset) {
-               if (S_ISDIR(inode->i_mode)) {
-                       dec_page_count(sbi, F2FS_DIRTY_DENTS);
-                       inode_dec_dirty_dents(inode);
-               }
+               inode_dec_dirty_dents(inode);
                goto out;
        }
 
        zero_user_segment(page, offset, PAGE_CACHE_SIZE);
 write:
-       if (unlikely(sbi->por_doing)) {
-               err = AOP_WRITEPAGE_ACTIVATE;
+       if (unlikely(sbi->por_doing))
                goto redirty_out;
-       }
 
        /* Dentry blocks are controlled by checkpoint */
        if (S_ISDIR(inode->i_mode)) {
-               dec_page_count(sbi, F2FS_DIRTY_DENTS);
                inode_dec_dirty_dents(inode);
                err = do_write_data_page(page, &fio);
-       } else {
-               f2fs_lock_op(sbi);
-
-               if (f2fs_has_inline_data(inode) || f2fs_may_inline(inode)) {
-                       err = f2fs_write_inline_data(inode, page, offset);
-                       f2fs_unlock_op(sbi);
-                       goto out;
-               } else {
-                       err = do_write_data_page(page, &fio);
-               }
+               goto done;
+       }
 
-               f2fs_unlock_op(sbi);
+       if (!wbc->for_reclaim)
                need_balance_fs = true;
-       }
-       if (err == -ENOENT)
-               goto out;
-       else if (err)
+       else if (has_not_enough_free_secs(sbi, 0))
                goto redirty_out;
 
-       if (wbc->for_reclaim) {
-               f2fs_submit_merged_bio(sbi, DATA, WRITE);
-               need_balance_fs = false;
-       }
+       f2fs_lock_op(sbi);
+       if (f2fs_has_inline_data(inode) || f2fs_may_inline(inode))
+               err = f2fs_write_inline_data(inode, page, offset);
+       else
+               err = do_write_data_page(page, &fio);
+       f2fs_unlock_op(sbi);
+done:
+       if (err && err != -ENOENT)
+               goto redirty_out;
 
        clear_cold_data(page);
 out:
@@ -849,12 +839,11 @@ out:
 
 redirty_out:
        wbc->pages_skipped++;
+       account_page_redirty(page);
        set_page_dirty(page);
-       return err;
+       return AOP_WRITEPAGE_ACTIVATE;
 }
 
-#define MAX_DESIRED_PAGES_WP   4096
-
 static int __f2fs_writepage(struct page *page, struct writeback_control *wbc,
                        void *data)
 {
@@ -871,17 +860,17 @@ static int f2fs_write_data_pages(struct address_space *mapping,
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        bool locked = false;
        int ret;
-       long excess_nrtw = 0, desired_nrtw;
+       long diff;
 
        /* deal with chardevs and other special file */
        if (!mapping->a_ops->writepage)
                return 0;
 
-       if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) {
-               desired_nrtw = MAX_DESIRED_PAGES_WP;
-               excess_nrtw = desired_nrtw - wbc->nr_to_write;
-               wbc->nr_to_write = desired_nrtw;
-       }
+       if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
+                       get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA))
+               goto skip_write;
+
+       diff = nr_pages_to_write(sbi, DATA, wbc);
 
        if (!S_ISDIR(inode->i_mode)) {
                mutex_lock(&sbi->writepages);
@@ -895,8 +884,12 @@ static int f2fs_write_data_pages(struct address_space *mapping,
 
        remove_dirty_dir_inode(inode);
 
-       wbc->nr_to_write -= excess_nrtw;
+       wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff);
        return ret;
+
+skip_write:
+       wbc->pages_skipped += get_dirty_dents(inode);
+       return 0;
 }
 
 static int f2fs_write_begin(struct file *file, struct address_space *mapping,
@@ -1031,11 +1024,8 @@ static void f2fs_invalidate_data_page(struct page *page, unsigned int offset,
                                      unsigned int length)
 {
        struct inode *inode = page->mapping->host;
-       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-       if (S_ISDIR(inode->i_mode) && PageDirty(page)) {
-               dec_page_count(sbi, F2FS_DIRTY_DENTS);
+       if (PageDirty(page))
                inode_dec_dirty_dents(inode);
-       }
        ClearPagePrivate(page);
 }