OSDN Git Service

f2fs: trace f2fs_ioc_shutdown
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / f2fs / file.c
index 2ca53f7..9cc2563 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * fs/f2fs/file.c
  *
  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 #include <linux/fs.h>
 #include <linux/f2fs_fs.h>
@@ -53,7 +50,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
        struct page *page = vmf->page;
        struct inode *inode = file_inode(vma->vm_file);
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-       struct dnode_of_data dn;
+       struct dnode_of_data dn = { .node_changed = false };
        int err;
 
        if (unlikely(f2fs_cp_error(sbi))) {
@@ -65,19 +62,6 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
 
        f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
 
-       /* block allocation */
-       f2fs_lock_op(sbi);
-       set_new_dnode(&dn, inode, NULL, NULL, 0);
-       err = f2fs_reserve_block(&dn, page->index);
-       if (err) {
-               f2fs_unlock_op(sbi);
-               goto out;
-       }
-       f2fs_put_dnode(&dn);
-       f2fs_unlock_op(sbi);
-
-       f2fs_balance_fs(sbi, dn.node_changed);
-
        file_update_time(vma->vm_file);
        down_read(&F2FS_I(inode)->i_mmap_sem);
        lock_page(page);
@@ -89,11 +73,28 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
                goto out_sem;
        }
 
+       /* block allocation */
+       __do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, true);
+       set_new_dnode(&dn, inode, NULL, NULL, 0);
+       err = f2fs_get_block(&dn, page->index);
+       f2fs_put_dnode(&dn);
+       __do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, false);
+       if (err) {
+               unlock_page(page);
+               goto out_sem;
+       }
+
+       /* fill the page */
+       f2fs_wait_on_page_writeback(page, DATA, false, true);
+
+       /* wait for GCed page writeback via META_MAPPING */
+       f2fs_wait_on_block_writeback(inode, dn.data_blkaddr);
+
        /*
         * check to see if the page is mapped already (no holes)
         */
        if (PageMappedToDisk(page))
-               goto mapped;
+               goto out_sem;
 
        /* page is wholly or partially inside EOF */
        if (((loff_t)(page->index + 1) << PAGE_SHIFT) >
@@ -108,21 +109,15 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
                SetPageUptodate(page);
 
        f2fs_update_iostat(sbi, APP_MAPPED_IO, F2FS_BLKSIZE);
+       f2fs_update_time(sbi, REQ_TIME);
 
        trace_f2fs_vm_page_mkwrite(page, DATA);
-mapped:
-       /* fill the page */
-       f2fs_wait_on_page_writeback(page, DATA, false);
-
-       /* wait for GCed page writeback via META_MAPPING */
-       if (f2fs_post_read_required(inode))
-               f2fs_wait_on_block_writeback(sbi, dn.data_blkaddr);
-
 out_sem:
        up_read(&F2FS_I(inode)->i_mmap_sem);
-out:
+
+       f2fs_balance_fs(sbi, dn.node_changed);
+
        sb_end_pagefault(inode->i_sb);
-       f2fs_update_time(sbi, REQ_TIME);
 err:
        return block_page_mkwrite_return(err);
 }
@@ -216,12 +211,17 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,
                .nr_to_write = LONG_MAX,
                .for_reclaim = 0,
        };
+       unsigned int seq_id = 0;
 
-       if (unlikely(f2fs_readonly(inode->i_sb)))
+       if (unlikely(f2fs_readonly(inode->i_sb) ||
+                               is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
                return 0;
 
        trace_f2fs_sync_file_enter(inode);
 
+       if (S_ISDIR(inode->i_mode))
+               goto go_write;
+
        /* if fdatasync is triggered, let's do in-place-update */
        if (datasync || get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks)
                set_inode_flag(inode, FI_NEED_IPU);
@@ -278,7 +278,7 @@ go_write:
        }
 sync_nodes:
        atomic_inc(&sbi->wb_sync_req[NODE]);
-       ret = f2fs_fsync_node_pages(sbi, inode, &wbc, atomic);
+       ret = f2fs_fsync_node_pages(sbi, inode, &wbc, atomic, &seq_id);
        atomic_dec(&sbi->wb_sync_req[NODE]);
        if (ret)
                goto out;
@@ -304,7 +304,7 @@ sync_nodes:
         * given fsync mark.
         */
        if (!atomic) {
-               ret = f2fs_wait_on_node_pages_writeback(sbi, ino);
+               ret = f2fs_wait_on_node_pages_writeback(sbi, seq_id);
                if (ret)
                        goto out;
        }
@@ -353,13 +353,13 @@ static pgoff_t __get_first_dirty_index(struct address_space *mapping,
        return pgofs;
 }
 
-static bool __found_offset(block_t blkaddr, pgoff_t dirty, pgoff_t pgofs,
-                                                       int whence)
+static bool __found_offset(struct f2fs_sb_info *sbi, block_t blkaddr,
+                               pgoff_t dirty, pgoff_t pgofs, int whence)
 {
        switch (whence) {
        case SEEK_DATA:
                if ((blkaddr == NEW_ADDR && dirty == pgofs) ||
-                       is_valid_blkaddr(blkaddr))
+                       is_valid_data_blkaddr(sbi, blkaddr))
                        return true;
                break;
        case SEEK_HOLE:
@@ -423,7 +423,15 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
                        blkaddr = datablock_addr(dn.inode,
                                        dn.node_page, dn.ofs_in_node);
 
-                       if (__found_offset(blkaddr, dirty, pgofs, whence)) {
+                       if (__is_valid_data_blkaddr(blkaddr) &&
+                               !f2fs_is_valid_blkaddr(F2FS_I_SB(inode),
+                                               blkaddr, DATA_GENERIC)) {
+                               f2fs_put_dnode(&dn);
+                               goto fail;
+                       }
+
+                       if (__found_offset(F2FS_I_SB(inode), blkaddr, dirty,
+                                                       pgofs, whence)) {
                                f2fs_put_dnode(&dn);
                                goto found;
                        }
@@ -516,6 +524,11 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
 
                dn->data_blkaddr = NULL_ADDR;
                f2fs_set_data_blkaddr(dn);
+
+               if (__is_valid_data_blkaddr(blkaddr) &&
+                       !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC))
+                       continue;
+
                f2fs_invalidate_blocks(sbi, blkaddr);
                if (dn->ofs_in_node == 0 && IS_INODE(dn->node_page))
                        clear_inode_flag(dn->inode, FI_FIRST_BLOCK_WRITTEN);
@@ -568,7 +581,7 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
        if (IS_ERR(page))
                return PTR_ERR(page) == -ENOENT ? 0 : PTR_ERR(page);
 truncate_out:
-       f2fs_wait_on_page_writeback(page, DATA, true);
+       f2fs_wait_on_page_writeback(page, DATA, true, true);
        zero_user(page, offset, PAGE_SIZE - offset);
 
        /* An encrypted inode should have a key and truncate the last page. */
@@ -657,12 +670,11 @@ int f2fs_truncate(struct inode *inode)
 
        trace_f2fs_truncate(inode);
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(F2FS_I_SB(inode), FAULT_TRUNCATE)) {
                f2fs_show_injection_info(FAULT_TRUNCATE);
                return -EIO;
        }
-#endif
+
        /* we should check inline_data size */
        if (!f2fs_may_inline_data(inode)) {
                err = f2fs_convert_inline_inode(inode);
@@ -689,7 +701,7 @@ int f2fs_getattr(struct vfsmount *mnt,
        unsigned int flags;
 
        if (f2fs_has_extra_attr(inode) &&
-                       f2fs_sb_has_inode_crtime(inode->i_sb) &&
+                       f2fs_sb_has_inode_crtime(F2FS_I_SB(inode)) &&
                        F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_crtime)) {
                stat->result_mask |= STATX_BTIME;
                stat->btime.tv_sec = fi->i_crtime.tv_sec;
@@ -758,7 +770,6 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = d_inode(dentry);
        int err;
-       bool size_changed = false;
 
        if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
                return -EIO;
@@ -780,28 +791,47 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
                !uid_eq(attr->ia_uid, inode->i_uid)) ||
                (attr->ia_valid & ATTR_GID &&
                !gid_eq(attr->ia_gid, inode->i_gid))) {
+               f2fs_lock_op(F2FS_I_SB(inode));
                err = dquot_transfer(inode, attr);
-               if (err)
+               if (err) {
+                       set_sbi_flag(F2FS_I_SB(inode),
+                                       SBI_QUOTA_NEED_REPAIR);
+                       f2fs_unlock_op(F2FS_I_SB(inode));
                        return err;
+               }
+               /*
+                * update uid/gid under lock_op(), so that dquot and inode can
+                * be updated atomically.
+                */
+               if (attr->ia_valid & ATTR_UID)
+                       inode->i_uid = attr->ia_uid;
+               if (attr->ia_valid & ATTR_GID)
+                       inode->i_gid = attr->ia_gid;
+               f2fs_mark_inode_dirty_sync(inode, true);
+               f2fs_unlock_op(F2FS_I_SB(inode));
        }
 
        if (attr->ia_valid & ATTR_SIZE) {
-               if (attr->ia_size <= i_size_read(inode)) {
-                       down_write(&F2FS_I(inode)->i_mmap_sem);
-                       truncate_setsize(inode, attr->ia_size);
+               bool to_smaller = (attr->ia_size <= i_size_read(inode));
+
+               down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+               down_write(&F2FS_I(inode)->i_mmap_sem);
+
+               truncate_setsize(inode, attr->ia_size);
+
+               if (to_smaller)
                        err = f2fs_truncate(inode);
-                       up_write(&F2FS_I(inode)->i_mmap_sem);
-                       if (err)
-                               return err;
-               } else {
-                       /*
-                        * do not trim all blocks after i_size if target size is
-                        * larger than i_size.
-                        */
-                       down_write(&F2FS_I(inode)->i_mmap_sem);
-                       truncate_setsize(inode, attr->ia_size);
-                       up_write(&F2FS_I(inode)->i_mmap_sem);
+               /*
+                * do not trim all blocks after i_size if target size is
+                * larger than i_size.
+                */
+               up_write(&F2FS_I(inode)->i_mmap_sem);
+               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+
+               if (err)
+                       return err;
 
+               if (!to_smaller) {
                        /* should convert inline inode here */
                        if (!f2fs_may_inline_data(inode)) {
                                err = f2fs_convert_inline_inode(inode);
@@ -814,8 +844,6 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
                down_write(&F2FS_I(inode)->i_sem);
                F2FS_I(inode)->last_disk_size = i_size_read(inode);
                up_write(&F2FS_I(inode)->i_sem);
-
-               size_changed = true;
        }
 
        __setattr_copy(inode, attr);
@@ -829,7 +857,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
        /* file size may changed here */
-       f2fs_mark_inode_dirty_sync(inode, size_changed);
+       f2fs_mark_inode_dirty_sync(inode, true);
 
        /* inode change will produce dirty node pages flushed by checkpoint */
        f2fs_balance_fs(F2FS_I_SB(inode), true);
@@ -869,7 +897,7 @@ static int fill_zero(struct inode *inode, pgoff_t index,
        if (IS_ERR(page))
                return PTR_ERR(page);
 
-       f2fs_wait_on_page_writeback(page, DATA, true);
+       f2fs_wait_on_page_writeback(page, DATA, true, true);
        zero_user(page, start, len);
        set_page_dirty(page);
        f2fs_put_page(page, 1);
@@ -951,14 +979,19 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
 
                        blk_start = (loff_t)pg_start << PAGE_SHIFT;
                        blk_end = (loff_t)pg_end << PAGE_SHIFT;
+
+                       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                        down_write(&F2FS_I(inode)->i_mmap_sem);
+
                        truncate_inode_pages_range(mapping, blk_start,
                                        blk_end - 1);
 
                        f2fs_lock_op(sbi);
                        ret = f2fs_truncate_hole(inode, pg_start, pg_end);
                        f2fs_unlock_op(sbi);
+
                        up_write(&F2FS_I(inode)->i_mmap_sem);
+                       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                }
        }
 
@@ -1061,7 +1094,12 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
                        if (ret)
                                return ret;
 
-                       f2fs_get_node_info(sbi, dn.nid, &ni);
+                       ret = f2fs_get_node_info(sbi, dn.nid, &ni);
+                       if (ret) {
+                               f2fs_put_dnode(&dn);
+                               return ret;
+                       }
+
                        ilen = min((pgoff_t)
                                ADDRS_PER_PAGE(dn.node_page, dst_inode) -
                                                dn.ofs_in_node, len - i);
@@ -1129,12 +1167,14 @@ static int __exchange_data_block(struct inode *src_inode,
                olen = min((pgoff_t)4 * ADDRS_PER_BLOCK, len);
 
                src_blkaddr = f2fs_kvzalloc(F2FS_I_SB(src_inode),
-                                       sizeof(block_t) * olen, GFP_KERNEL);
+                                       array_size(olen, sizeof(block_t)),
+                                       GFP_KERNEL);
                if (!src_blkaddr)
                        return -ENOMEM;
 
                do_replace = f2fs_kvzalloc(F2FS_I_SB(src_inode),
-                                       sizeof(int) * olen, GFP_KERNEL);
+                                       array_size(olen, sizeof(int)),
+                                       GFP_KERNEL);
                if (!do_replace) {
                        kvfree(src_blkaddr);
                        return -ENOMEM;
@@ -1166,25 +1206,33 @@ roll_back:
        return ret;
 }
 
-static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end)
+static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
+       pgoff_t start = offset >> PAGE_SHIFT;
+       pgoff_t end = (offset + len) >> PAGE_SHIFT;
        int ret;
 
        f2fs_balance_fs(sbi, true);
-       f2fs_lock_op(sbi);
 
-       f2fs_drop_extent_tree(inode);
+       /* avoid gc operation during block exchange */
+       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+       down_write(&F2FS_I(inode)->i_mmap_sem);
 
+       f2fs_lock_op(sbi);
+       f2fs_drop_extent_tree(inode);
+       truncate_pagecache(inode, offset);
        ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true);
        f2fs_unlock_op(sbi);
+
+       up_write(&F2FS_I(inode)->i_mmap_sem);
+       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        return ret;
 }
 
 static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
 {
-       pgoff_t pg_start, pg_end;
        loff_t new_size;
        int ret;
 
@@ -1199,25 +1247,17 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
        if (ret)
                return ret;
 
-       pg_start = offset >> PAGE_SHIFT;
-       pg_end = (offset + len) >> PAGE_SHIFT;
-
-       /* avoid gc operation during block exchange */
-       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
-
-       down_write(&F2FS_I(inode)->i_mmap_sem);
        /* write out all dirty pages from offset */
        ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
        if (ret)
-               goto out_unlock;
-
-       truncate_pagecache(inode, offset);
+               return ret;
 
-       ret = f2fs_do_collapse(inode, pg_start, pg_end);
+       ret = f2fs_do_collapse(inode, offset, len);
        if (ret)
-               goto out_unlock;
+               return ret;
 
        /* write out all moved pages, if possible */
+       down_write(&F2FS_I(inode)->i_mmap_sem);
        filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
        truncate_pagecache(inode, offset);
 
@@ -1225,11 +1265,9 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
        truncate_pagecache(inode, new_size);
 
        ret = f2fs_truncate_blocks(inode, new_size, true);
+       up_write(&F2FS_I(inode)->i_mmap_sem);
        if (!ret)
                f2fs_i_size_write(inode, new_size);
-out_unlock:
-       up_write(&F2FS_I(inode)->i_mmap_sem);
-       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        return ret;
 }
 
@@ -1295,12 +1333,9 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
        if (ret)
                return ret;
 
-       down_write(&F2FS_I(inode)->i_mmap_sem);
        ret = filemap_write_and_wait_range(mapping, offset, offset + len - 1);
        if (ret)
-               goto out_sem;
-
-       truncate_pagecache_range(inode, offset, offset + len - 1);
+               return ret;
 
        pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
        pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1312,7 +1347,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                ret = fill_zero(inode, pg_start, off_start,
                                                off_end - off_start);
                if (ret)
-                       goto out_sem;
+                       return ret;
 
                new_size = max_t(loff_t, new_size, offset + len);
        } else {
@@ -1320,7 +1355,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                        ret = fill_zero(inode, pg_start++, off_start,
                                                PAGE_SIZE - off_start);
                        if (ret)
-                               goto out_sem;
+                               return ret;
 
                        new_size = max_t(loff_t, new_size,
                                        (loff_t)pg_start << PAGE_SHIFT);
@@ -1331,12 +1366,21 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                        unsigned int end_offset;
                        pgoff_t end;
 
+                       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+                       down_write(&F2FS_I(inode)->i_mmap_sem);
+
+                       truncate_pagecache_range(inode,
+                               (loff_t)index << PAGE_SHIFT,
+                               ((loff_t)pg_end << PAGE_SHIFT) - 1);
+
                        f2fs_lock_op(sbi);
 
                        set_new_dnode(&dn, inode, NULL, NULL, 0);
                        ret = f2fs_get_dnode_of_data(&dn, index, ALLOC_NODE);
                        if (ret) {
                                f2fs_unlock_op(sbi);
+                               up_write(&F2FS_I(inode)->i_mmap_sem);
+                               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                                goto out;
                        }
 
@@ -1345,7 +1389,10 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
 
                        ret = f2fs_do_zero_range(&dn, index, end);
                        f2fs_put_dnode(&dn);
+
                        f2fs_unlock_op(sbi);
+                       up_write(&F2FS_I(inode)->i_mmap_sem);
+                       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
 
                        f2fs_balance_fs(sbi, dn.node_changed);
 
@@ -1373,9 +1420,6 @@ out:
                else
                        f2fs_i_size_write(inode, new_size);
        }
-out_sem:
-       up_write(&F2FS_I(inode)->i_mmap_sem);
-
        return ret;
 }
 
@@ -1404,26 +1448,27 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
 
        f2fs_balance_fs(sbi, true);
 
-       /* avoid gc operation during block exchange */
-       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
-
        down_write(&F2FS_I(inode)->i_mmap_sem);
        ret = f2fs_truncate_blocks(inode, i_size_read(inode), true);
+       up_write(&F2FS_I(inode)->i_mmap_sem);
        if (ret)
-               goto out;
+               return ret;
 
        /* write out all dirty pages from offset */
        ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
        if (ret)
-               goto out;
-
-       truncate_pagecache(inode, offset);
+               return ret;
 
        pg_start = offset >> PAGE_SHIFT;
        pg_end = (offset + len) >> PAGE_SHIFT;
        delta = pg_end - pg_start;
        idx = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
 
+       /* avoid gc operation during block exchange */
+       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+       down_write(&F2FS_I(inode)->i_mmap_sem);
+       truncate_pagecache(inode, offset);
+
        while (!ret && idx > pg_start) {
                nr = idx - pg_start;
                if (nr > delta)
@@ -1437,16 +1482,17 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
                                        idx + delta, nr, false);
                f2fs_unlock_op(sbi);
        }
+       up_write(&F2FS_I(inode)->i_mmap_sem);
+       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
 
        /* write out all moved pages, if possible */
+       down_write(&F2FS_I(inode)->i_mmap_sem);
        filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
        truncate_pagecache(inode, offset);
+       up_write(&F2FS_I(inode)->i_mmap_sem);
 
        if (!ret)
                f2fs_i_size_write(inode, new_size);
-out:
-       up_write(&F2FS_I(inode)->i_mmap_sem);
-       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        return ret;
 }
 
@@ -1455,7 +1501,8 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct f2fs_map_blocks map = { .m_next_pgofs = NULL,
-                       .m_next_extent = NULL, .m_seg_type = NO_CHECK_TYPE };
+                       .m_next_extent = NULL, .m_seg_type = NO_CHECK_TYPE,
+                       .m_may_create = true };
        pgoff_t pg_end;
        loff_t new_size = i_size_read(inode);
        loff_t off_end;
@@ -1602,10 +1649,12 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
        struct f2fs_inode_info *fi = F2FS_I(inode);
        unsigned int flags = fi->i_flags;
 
-       if (file_is_encrypt(inode))
+       if (f2fs_encrypted_inode(inode))
                flags |= F2FS_ENCRYPT_FL;
        if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
                flags |= F2FS_INLINE_DATA_FL;
+       if (is_inode_flag_set(inode, FI_PIN_FILE))
+               flags |= F2FS_NOCOW_FL;
 
        flags &= F2FS_FL_USER_VISIBLE;
 
@@ -1686,34 +1735,41 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
 
        inode_lock(inode);
 
-       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
-
-       if (f2fs_is_atomic_file(inode))
+       if (f2fs_is_atomic_file(inode)) {
+               if (is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST))
+                       ret = -EINVAL;
                goto out;
+       }
 
        ret = f2fs_convert_inline_inode(inode);
        if (ret)
                goto out;
 
-       if (!get_dirty_pages(inode))
-               goto skip_flush;
+       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
 
-       f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING,
+       /*
+        * Should wait end_io to count F2FS_WB_CP_DATA correctly by
+        * f2fs_is_atomic_file.
+        */
+       if (get_dirty_pages(inode))
+               f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING,
                "Unexpected flush for atomic writes: ino=%lu, npages=%u",
                                        inode->i_ino, get_dirty_pages(inode));
        ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
-       if (ret)
+       if (ret) {
+               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                goto out;
-skip_flush:
+       }
+
        set_inode_flag(inode, FI_ATOMIC_FILE);
        clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
-       f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
 
+       f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
        F2FS_I(inode)->inmem_task = current;
        stat_inc_atomic_write(inode);
        stat_update_max_atomic_write(inode);
 out:
-       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        inode_unlock(inode);
        mnt_drop_write_file(filp);
        return ret;
@@ -1731,9 +1787,9 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
        if (ret)
                return ret;
 
-       inode_lock(inode);
+       f2fs_balance_fs(F2FS_I_SB(inode), true);
 
-       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+       inode_lock(inode);
 
        if (f2fs_is_volatile_file(inode)) {
                ret = -EINVAL;
@@ -1759,7 +1815,6 @@ err_out:
                clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
                ret = -EINVAL;
        }
-       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        inode_unlock(inode);
        mnt_drop_write_file(filp);
        return ret;
@@ -1851,6 +1906,8 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp)
                ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
        }
 
+       clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+
        inode_unlock(inode);
 
        mnt_drop_write_file(filp);
@@ -1864,7 +1921,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct super_block *sb = sbi->sb;
        __u32 in;
-       int ret;
+       int ret = 0;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
@@ -1887,6 +1944,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
                }
                if (sb) {
                        f2fs_stop_checkpoint(sbi, false);
+                       set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                        thaw_bdev(sb->s_bdev, sb);
                }
                break;
@@ -1896,14 +1954,24 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
                if (ret)
                        goto out;
                f2fs_stop_checkpoint(sbi, false);
+               set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                break;
        case F2FS_GOING_DOWN_NOSYNC:
                f2fs_stop_checkpoint(sbi, false);
+               set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                break;
        case F2FS_GOING_DOWN_METAFLUSH:
                f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
                f2fs_stop_checkpoint(sbi, false);
+               set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                break;
+       case F2FS_GOING_DOWN_NEED_FSCK:
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               set_sbi_flag(sbi, SBI_CP_DISABLED_QUICK);
+               set_sbi_flag(sbi, SBI_IS_DIRTY);
+               /* do checkpoint only */
+               ret = f2fs_sync_fs(sb, 1);
+               goto out;
        default:
                ret = -EINVAL;
                goto out;
@@ -1919,6 +1987,9 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
 out:
        if (in != F2FS_GOING_DOWN_FULLSYNC)
                mnt_drop_write_file(filp);
+
+       trace_f2fs_shutdown(sbi, in, ret);
+
        return ret;
 }
 
@@ -1933,7 +2004,7 @@ static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (!blk_queue_discard(q))
+       if (!f2fs_hw_support_discard(F2FS_SB(sb)))
                return -EOPNOTSUPP;
 
        if (copy_from_user(&range, (struct fstrim_range __user *)arg,
@@ -1972,7 +2043,7 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
 
-       if (!f2fs_sb_has_encrypt(inode->i_sb))
+       if (!f2fs_sb_has_encrypt(F2FS_I_SB(inode)))
                return -EOPNOTSUPP;
 
        f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
@@ -1982,7 +2053,7 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
 
 static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg)
 {
-       if (!f2fs_sb_has_encrypt(file_inode(filp)->i_sb))
+       if (!f2fs_sb_has_encrypt(F2FS_I_SB(file_inode(filp))))
                return -EOPNOTSUPP;
        return fscrypt_ioctl_get_policy(filp, (void __user *)arg);
 }
@@ -1993,7 +2064,7 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg)
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        int err;
 
-       if (!f2fs_sb_has_encrypt(inode->i_sb))
+       if (!f2fs_sb_has_encrypt(sbi))
                return -EOPNOTSUPP;
 
        err = mnt_want_write_file(filp);
@@ -2097,7 +2168,7 @@ do_more:
        }
 
        ret = f2fs_gc(sbi, range.sync, true, GET_SEGNO(sbi, range.start));
-       range.start += sbi->blocks_per_seg;
+       range.start += BLKS_PER_SEC(sbi);
        if (range.start <= end)
                goto do_more;
 out:
@@ -2105,7 +2176,7 @@ out:
        return ret;
 }
 
-static int f2fs_ioc_f2fs_write_checkpoint(struct file *filp, unsigned long arg)
+static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -2117,6 +2188,12 @@ static int f2fs_ioc_f2fs_write_checkpoint(struct file *filp, unsigned long arg)
        if (f2fs_readonly(sbi->sb))
                return -EROFS;
 
+       if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
+               f2fs_msg(sbi->sb, KERN_INFO,
+                       "Skipping Checkpoint. Checkpoints currently disabled.");
+               return -EINVAL;
+       }
+
        ret = mnt_want_write_file(filp);
        if (ret)
                return ret;
@@ -2133,7 +2210,8 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
 {
        struct inode *inode = file_inode(filp);
        struct f2fs_map_blocks map = { .m_next_extent = NULL,
-                                       .m_seg_type = NO_CHECK_TYPE };
+                                       .m_seg_type = NO_CHECK_TYPE ,
+                                       .m_may_create = false };
        struct extent_info ei = {0, 0, 0};
        pgoff_t pg_start, pg_end, next_pgofs;
        unsigned int blk_per_seg = sbi->blocks_per_seg;
@@ -2349,15 +2427,10 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
        }
 
        inode_lock(src);
-       down_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
        if (src != dst) {
                ret = -EBUSY;
                if (!inode_trylock(dst))
                        goto out;
-               if (!down_write_trylock(&F2FS_I(dst)->i_gc_rwsem[WRITE])) {
-                       inode_unlock(dst);
-                       goto out;
-               }
        }
 
        ret = -EINVAL;
@@ -2402,6 +2475,14 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
                goto out_unlock;
 
        f2fs_balance_fs(sbi, true);
+
+       down_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
+       if (src != dst) {
+               ret = -EBUSY;
+               if (!down_write_trylock(&F2FS_I(dst)->i_gc_rwsem[WRITE]))
+                       goto out_src;
+       }
+
        f2fs_lock_op(sbi);
        ret = __exchange_data_block(src, dst, pos_in >> F2FS_BLKSIZE_BITS,
                                pos_out >> F2FS_BLKSIZE_BITS,
@@ -2414,13 +2495,15 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
                        f2fs_i_size_write(dst, dst_osize);
        }
        f2fs_unlock_op(sbi);
-out_unlock:
-       if (src != dst) {
+
+       if (src != dst)
                up_write(&F2FS_I(dst)->i_gc_rwsem[WRITE]);
+out_src:
+       up_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
+out_unlock:
+       if (src != dst)
                inode_unlock(dst);
-       }
 out:
-       up_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
        inode_unlock(src);
        return ret;
 }
@@ -2483,12 +2566,15 @@ static int f2fs_ioc_flush_device(struct file *filp, unsigned long arg)
        if (f2fs_readonly(sbi->sb))
                return -EROFS;
 
+       if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
+               return -EINVAL;
+
        if (copy_from_user(&range, (struct f2fs_flush_device __user *)arg,
                                                        sizeof(range)))
                return -EFAULT;
 
        if (sbi->s_ndevs <= 1 || sbi->s_ndevs - 1 <= range.dev_num ||
-                       sbi->segs_per_sec != 1) {
+                       __is_large_section(sbi)) {
                f2fs_msg(sbi->sb, KERN_WARNING,
                        "Can't flush %u in %d for segs_per_sec %u != 1\n",
                                range.dev_num, sbi->s_ndevs,
@@ -2592,7 +2678,7 @@ static int f2fs_ioc_set_pin_file(struct file *filp, unsigned long arg)
 
        if (!pin) {
                clear_inode_flag(inode, FI_PIN_FILE);
-               F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] = 1;
+               f2fs_i_gc_failures_write(inode, 0);
                goto done;
        }
 
@@ -2639,6 +2725,7 @@ int f2fs_precache_extents(struct inode *inode)
        map.m_next_pgofs = NULL;
        map.m_next_extent = &m_next_extent;
        map.m_seg_type = NO_CHECK_TYPE;
+       map.m_may_create = false;
        end = F2FS_I_SB(inode)->max_file_blocks;
 
        while (map.m_lblk < end) {
@@ -2698,7 +2785,7 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        case F2FS_IOC_GARBAGE_COLLECT_RANGE:
                return f2fs_ioc_gc_range(filp, arg);
        case F2FS_IOC_WRITE_CHECKPOINT:
-               return f2fs_ioc_f2fs_write_checkpoint(filp, arg);
+               return f2fs_ioc_write_checkpoint(filp, arg);
        case F2FS_IOC_DEFRAGMENT:
                return f2fs_ioc_defragment(filp, arg);
        case F2FS_IOC_MOVE_RANGE:
@@ -2750,7 +2837,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
                                if (!f2fs_overwrite_io(inode, iocb->ki_pos,
                                                iov_iter_count(from)) ||
                                        f2fs_has_inline_data(inode) ||
-                                       f2fs_force_buffered_io(inode, WRITE)) {
+                                       f2fs_force_buffered_io(inode,
+                                                       iocb, from)) {
                                                clear_inode_flag(inode,
                                                                FI_NO_PREALLOC);
                                                inode_unlock(inode);