OSDN Git Service

f2fs: trace f2fs_ioc_shutdown
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / f2fs / file.c
index 1717423..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);
 }
@@ -218,11 +213,15 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,
        };
        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);
@@ -582,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. */
@@ -671,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);
@@ -703,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;
@@ -772,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;
@@ -794,16 +791,31 @@ 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) {
                bool to_smaller = (attr->ia_size <= i_size_read(inode));
 
-               down_write(&F2FS_I(inode)->i_mmap_sem);
                down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+               down_write(&F2FS_I(inode)->i_mmap_sem);
 
                truncate_setsize(inode, attr->ia_size);
 
@@ -813,8 +825,8 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
                 * do not trim all blocks after i_size if target size is
                 * larger than i_size.
                 */
-               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                up_write(&F2FS_I(inode)->i_mmap_sem);
+               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
 
                if (err)
                        return err;
@@ -832,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);
@@ -847,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);
@@ -887,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);
@@ -970,8 +980,8 @@ 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_mmap_sem);
                        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);
@@ -980,8 +990,8 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
                        ret = f2fs_truncate_hole(inode, pg_start, pg_end);
                        f2fs_unlock_op(sbi);
 
-                       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                        up_write(&F2FS_I(inode)->i_mmap_sem);
+                       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                }
        }
 
@@ -1196,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;
 
@@ -1229,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);
 
@@ -1255,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;
 }
 
@@ -1325,10 +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;
+               return ret;
 
        pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
        pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1340,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 {
@@ -1348,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);
@@ -1360,6 +1367,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                        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,
@@ -1371,6 +1379,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                        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;
                        }
@@ -1382,6 +1391,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                        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);
@@ -1410,9 +1420,6 @@ out:
                else
                        f2fs_i_size_write(inode, new_size);
        }
-out_sem:
-       up_write(&F2FS_I(inode)->i_mmap_sem);
-
        return ret;
 }
 
@@ -1441,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)
@@ -1474,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;
 }
 
@@ -1492,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;
@@ -1643,6 +1653,8 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
                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;
 
@@ -1723,8 +1735,6 @@ 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 (is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST))
                        ret = -EINVAL;
@@ -1735,25 +1745,31 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
        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;
@@ -1771,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;
@@ -1799,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;
@@ -1950,6 +1965,13 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
                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;
@@ -1965,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;
 }
 
@@ -1979,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,
@@ -2018,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);
@@ -2028,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);
 }
@@ -2039,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);
@@ -2143,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:
@@ -2163,6 +2188,12 @@ static int f2fs_ioc_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;
@@ -2179,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;
@@ -2395,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;
@@ -2448,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,
@@ -2460,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;
 }
@@ -2529,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,
@@ -2685,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) {
@@ -2796,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);