Merge tag 'f2fs-for-6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
[linux-2.6-microblaze.git] / fs / f2fs / file.c
index d66e37d..ce4905a 100644 (file)
@@ -1272,7 +1272,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
                                f2fs_put_page(psrc, 1);
                                return PTR_ERR(pdst);
                        }
-                       f2fs_copy_page(psrc, pdst);
+                       memcpy_page(pdst, 0, psrc, 0, PAGE_SIZE);
                        set_page_dirty(pdst);
                        f2fs_put_page(pdst, 1);
                        f2fs_put_page(psrc, 1);
@@ -1675,7 +1675,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
                return 0;
 
        if (f2fs_is_pinned_file(inode)) {
-               block_t sec_blks = BLKS_PER_SEC(sbi);
+               block_t sec_blks = CAP_BLKS_PER_SEC(sbi);
                block_t sec_len = roundup(map.m_len, sec_blks);
 
                map.m_len = sec_blks;
@@ -1816,8 +1816,7 @@ static int f2fs_release_file(struct inode *inode, struct file *filp)
                        atomic_read(&inode->i_writecount) != 1)
                return 0;
 
-       if (f2fs_is_atomic_file(inode))
-               f2fs_abort_atomic_write(inode, true);
+       f2fs_abort_atomic_write(inode, true);
        return 0;
 }
 
@@ -1831,8 +1830,7 @@ static int f2fs_file_flush(struct file *file, fl_owner_t id)
         * until all the writers close its file. Since this should be done
         * before dropping file lock, it needs to do in ->flush.
         */
-       if (f2fs_is_atomic_file(inode) &&
-                       F2FS_I(inode)->atomic_write_task == current)
+       if (F2FS_I(inode)->atomic_write_task == current)
                f2fs_abort_atomic_write(inode, true);
        return 0;
 }
@@ -1867,22 +1865,15 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
                if (masked_flags & F2FS_COMPR_FL) {
                        if (!f2fs_disable_compressed_file(inode))
                                return -EINVAL;
-               }
-               if (iflags & F2FS_NOCOMP_FL)
-                       return -EINVAL;
-               if (iflags & F2FS_COMPR_FL) {
+               } else {
                        if (!f2fs_may_compress(inode))
                                return -EINVAL;
-                       if (S_ISREG(inode->i_mode) && inode->i_size)
+                       if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))
                                return -EINVAL;
-
-                       set_compress_context(inode);
+                       if (set_compress_context(inode))
+                               return -EOPNOTSUPP;
                }
        }
-       if ((iflags ^ masked_flags) & F2FS_NOCOMP_FL) {
-               if (masked_flags & F2FS_COMPR_FL)
-                       return -EINVAL;
-       }
 
        fi->i_flags = iflags | (fi->i_flags & ~mask);
        f2fs_bug_on(F2FS_I_SB(inode), (fi->i_flags & F2FS_COMPR_FL) &&
@@ -2062,13 +2053,14 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
        spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
 
        set_inode_flag(inode, FI_ATOMIC_FILE);
-       set_inode_flag(fi->cow_inode, FI_ATOMIC_FILE);
+       set_inode_flag(fi->cow_inode, FI_COW_FILE);
        clear_inode_flag(fi->cow_inode, FI_INLINE_DATA);
        f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
 
        f2fs_update_time(sbi, REQ_TIME);
        fi->atomic_write_task = current;
        stat_update_max_atomic_write(inode);
+       fi->atomic_write_cnt = 0;
 out:
        inode_unlock(inode);
        mnt_drop_write_file(filp);
@@ -2109,6 +2101,30 @@ unlock_out:
        return ret;
 }
 
+static int f2fs_ioc_abort_atomic_write(struct file *filp)
+{
+       struct inode *inode = file_inode(filp);
+       struct user_namespace *mnt_userns = file_mnt_user_ns(filp);
+       int ret;
+
+       if (!inode_owner_or_capable(mnt_userns, inode))
+               return -EACCES;
+
+       ret = mnt_want_write_file(filp);
+       if (ret)
+               return ret;
+
+       inode_lock(inode);
+
+       f2fs_abort_atomic_write(inode, true);
+
+       inode_unlock(inode);
+
+       mnt_drop_write_file(filp);
+       f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+       return ret;
+}
+
 static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
@@ -2426,7 +2442,7 @@ do_more:
                        ret = -EAGAIN;
                goto out;
        }
-       range->start += BLKS_PER_SEC(sbi);
+       range->start += CAP_BLKS_PER_SEC(sbi);
        if (range->start <= end)
                goto do_more;
 out:
@@ -2551,7 +2567,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
                goto out;
        }
 
-       sec_num = DIV_ROUND_UP(total, BLKS_PER_SEC(sbi));
+       sec_num = DIV_ROUND_UP(total, CAP_BLKS_PER_SEC(sbi));
 
        /*
         * make sure there are enough free section for LFS allocation, this can
@@ -3897,10 +3913,10 @@ static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len)
 
        for (i = 0; i < page_len; i++, redirty_idx++) {
                page = find_lock_page(mapping, redirty_idx);
-               if (!page) {
-                       ret = -ENOMEM;
-                       break;
-               }
+
+               /* It will never fail, when page has pinned above */
+               f2fs_bug_on(F2FS_I_SB(inode), !page);
+
                set_page_dirty(page);
                f2fs_put_page(page, 1);
                f2fs_put_page(page, 0);
@@ -3939,6 +3955,11 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg)
                goto out;
        }
 
+       if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
        if (ret)
                goto out;
@@ -4006,6 +4027,11 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
                goto out;
        }
 
+       if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
        if (ret)
                goto out;
@@ -4054,9 +4080,10 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                return f2fs_ioc_start_atomic_write(filp);
        case F2FS_IOC_COMMIT_ATOMIC_WRITE:
                return f2fs_ioc_commit_atomic_write(filp);
+       case F2FS_IOC_ABORT_ATOMIC_WRITE:
+               return f2fs_ioc_abort_atomic_write(filp);
        case F2FS_IOC_START_VOLATILE_WRITE:
        case F2FS_IOC_RELEASE_VOLATILE_WRITE:
-       case F2FS_IOC_ABORT_VOLATILE_WRITE:
                return -EOPNOTSUPP;
        case F2FS_IOC_SHUTDOWN:
                return f2fs_ioc_shutdown(filp, arg);
@@ -4725,7 +4752,7 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case F2FS_IOC_COMMIT_ATOMIC_WRITE:
        case F2FS_IOC_START_VOLATILE_WRITE:
        case F2FS_IOC_RELEASE_VOLATILE_WRITE:
-       case F2FS_IOC_ABORT_VOLATILE_WRITE:
+       case F2FS_IOC_ABORT_ATOMIC_WRITE:
        case F2FS_IOC_SHUTDOWN:
        case FITRIM:
        case FS_IOC_SET_ENCRYPTION_POLICY: