Merge tag 'f2fs-for-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
[muen/linux.git] / fs / f2fs / data.c
index 568e1d0..9727944 100644 (file)
@@ -301,9 +301,10 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi,
                for (; start < F2FS_IO_SIZE(sbi); start++) {
                        struct page *page =
                                mempool_alloc(sbi->write_io_dummy,
-                                       GFP_NOIO | __GFP_ZERO | __GFP_NOFAIL);
+                                             GFP_NOIO | __GFP_NOFAIL);
                        f2fs_bug_on(sbi, !page);
 
+                       zero_user_segment(page, 0, PAGE_SIZE);
                        SetPagePrivate(page);
                        set_page_private(page, (unsigned long)DUMMY_WRITTEN_PAGE);
                        lock_page(page);
@@ -1553,6 +1554,9 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
                if (last_block > last_block_in_file)
                        last_block = last_block_in_file;
 
+               /* just zeroing out page which is beyond EOF */
+               if (block_in_file >= last_block)
+                       goto zero_out;
                /*
                 * Map blocks using the previous result first.
                 */
@@ -1565,16 +1569,11 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
                 * Then do more f2fs_map_blocks() calls until we are
                 * done with this page.
                 */
-               map.m_flags = 0;
-
-               if (block_in_file < last_block) {
-                       map.m_lblk = block_in_file;
-                       map.m_len = last_block - block_in_file;
+               map.m_lblk = block_in_file;
+               map.m_len = last_block - block_in_file;
 
-                       if (f2fs_map_blocks(inode, &map, 0,
-                                               F2FS_GET_BLOCK_DEFAULT))
-                               goto set_error_page;
-               }
+               if (f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT))
+                       goto set_error_page;
 got_it:
                if ((map.m_flags & F2FS_MAP_MAPPED)) {
                        block_nr = map.m_pblk + block_in_file - map.m_lblk;
@@ -1589,6 +1588,7 @@ got_it:
                                                                DATA_GENERIC))
                                goto set_error_page;
                } else {
+zero_out:
                        zero_user_segment(page, 0, PAGE_SIZE);
                        if (!PageUptodate(page))
                                SetPageUptodate(page);
@@ -1863,8 +1863,13 @@ got_it:
                if (fio->need_lock == LOCK_REQ)
                        f2fs_unlock_op(fio->sbi);
                err = f2fs_inplace_write_data(fio);
-               if (err && PageWriteback(page))
-                       end_page_writeback(page);
+               if (err) {
+                       if (f2fs_encrypted_file(inode))
+                               fscrypt_pullback_bio_page(&fio->encrypted_page,
+                                                                       true);
+                       if (PageWriteback(page))
+                               end_page_writeback(page);
+               }
                trace_f2fs_do_write_data_page(fio->page, IPU);
                set_inode_flag(inode, FI_UPDATE_WRITE);
                return err;
@@ -2315,7 +2320,8 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to)
                down_write(&F2FS_I(inode)->i_mmap_sem);
 
                truncate_pagecache(inode, i_size);
-               f2fs_truncate_blocks(inode, i_size, true, true);
+               if (!IS_NOQUOTA(inode))
+                       f2fs_truncate_blocks(inode, i_size, true);
 
                up_write(&F2FS_I(inode)->i_mmap_sem);
                up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
@@ -2585,14 +2591,11 @@ static void f2fs_dio_submit_bio(struct bio *bio, struct inode *inode,
 {
        struct f2fs_private_dio *dio;
        bool write = (bio_op(bio) == REQ_OP_WRITE);
-       int err;
 
        dio = f2fs_kzalloc(F2FS_I_SB(inode),
                        sizeof(struct f2fs_private_dio), GFP_NOFS);
-       if (!dio) {
-               err = -ENOMEM;
+       if (!dio)
                goto out;
-       }
 
        dio->inode = inode;
        dio->orig_end_io = bio->bi_end_io;
@@ -2710,12 +2713,10 @@ void f2fs_invalidate_page(struct page *page, unsigned int offset,
 
        clear_cold_data(page);
 
-       /* This is atomic written page, keep Private */
        if (IS_ATOMIC_WRITTEN_PAGE(page))
                return f2fs_drop_inmem_page(inode, page);
 
-       set_page_private(page, 0);
-       ClearPagePrivate(page);
+       f2fs_clear_page_private(page);
 }
 
 int f2fs_release_page(struct page *page, gfp_t wait)
@@ -2729,8 +2730,7 @@ int f2fs_release_page(struct page *page, gfp_t wait)
                return 0;
 
        clear_cold_data(page);
-       set_page_private(page, 0);
-       ClearPagePrivate(page);
+       f2fs_clear_page_private(page);
        return 1;
 }
 
@@ -2798,12 +2798,8 @@ int f2fs_migrate_page(struct address_space *mapping,
                        return -EAGAIN;
        }
 
-       /*
-        * A reference is expected if PagePrivate set when move mapping,
-        * however F2FS breaks this for maintaining dirty page counts when
-        * truncating pages. So here adjusting the 'extra_count' make it work.
-        */
-       extra_count = (atomic_written ? 1 : 0) - page_has_private(page);
+       /* one extra reference was held for atomic_write page */
+       extra_count = atomic_written ? 1 : 0;
        rc = migrate_page_move_mapping(mapping, newpage,
                                page, mode, extra_count);
        if (rc != MIGRATEPAGE_SUCCESS) {
@@ -2824,9 +2820,10 @@ int f2fs_migrate_page(struct address_space *mapping,
                get_page(newpage);
        }
 
-       if (PagePrivate(page))
-               SetPagePrivate(newpage);
-       set_page_private(newpage, page_private(page));
+       if (PagePrivate(page)) {
+               f2fs_set_page_private(newpage, page_private(page));
+               f2fs_clear_page_private(page);
+       }
 
        if (mode != MIGRATE_SYNC_NO_COPY)
                migrate_page_copy(newpage, page);