Merge tag 'f2fs-for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
[linux-block.git] / fs / f2fs / file.c
index b906176397436a1fefe4cbaeee6326847039f644..15dabeac4690500f8f6e6d05d64b5cba18729781 100644 (file)
@@ -113,10 +113,8 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
 
        if (need_alloc) {
                /* block allocation */
-               f2fs_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_do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, false);
+               err = f2fs_get_block_locked(&dn, page->index);
        }
 
 #ifdef CONFIG_F2FS_FS_COMPRESSION
@@ -305,7 +303,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,
                 * for OPU case, during fsync(), node can be persisted before
                 * data when lower device doesn't support write barrier, result
                 * in data corruption after SPO.
-                * So for strict fsync mode, force to use atomic write sematics
+                * So for strict fsync mode, force to use atomic write semantics
                 * to keep write order in between data/node and last node to
                 * avoid potential data corruption.
                 */
@@ -619,7 +617,7 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
                fofs = f2fs_start_bidx_of_node(ofs_of_node(dn->node_page),
                                                        dn->inode) + ofs;
                f2fs_update_read_extent_cache_range(dn, fofs, 0, len);
-               f2fs_update_age_extent_cache_range(dn, fofs, nr_free);
+               f2fs_update_age_extent_cache_range(dn, fofs, len);
                dec_valid_block_count(sbi, dn->inode, nr_free);
        }
        dn->ofs_in_node = ofs;
@@ -784,10 +782,8 @@ int f2fs_truncate(struct inode *inode)
 
        trace_f2fs_truncate(inode);
 
-       if (time_to_inject(F2FS_I_SB(inode), FAULT_TRUNCATE)) {
-               f2fs_show_injection_info(F2FS_I_SB(inode), FAULT_TRUNCATE);
+       if (time_to_inject(F2FS_I_SB(inode), FAULT_TRUNCATE))
                return -EIO;
-       }
 
        err = f2fs_dquot_initialize(inode);
        if (err)
@@ -1112,7 +1108,7 @@ int f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end)
        return 0;
 }
 
-static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
+static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
 {
        pgoff_t pg_start, pg_end;
        loff_t off_start, off_end;
@@ -1498,6 +1494,7 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start,
        }
 
        f2fs_update_read_extent_cache_range(dn, start, 0, index - start);
+       f2fs_update_age_extent_cache_range(dn, start, index - start);
 
        return ret;
 }
@@ -1684,7 +1681,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
        return ret;
 }
 
-static int expand_inode_data(struct inode *inode, loff_t offset,
+static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
                                        loff_t len, int mode)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -1697,7 +1694,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
                        .err_gc_skipped = true,
                        .nr_free_secs = 0 };
        pgoff_t pg_start, pg_end;
-       loff_t new_size = i_size_read(inode);
+       loff_t new_size;
        loff_t off_end;
        block_t expanded = 0;
        int err;
@@ -1745,7 +1742,7 @@ next_alloc:
                f2fs_unlock_op(sbi);
 
                map.m_seg_type = CURSEG_COLD_DATA_PINNED;
-               err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
+               err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_PRE_DIO);
                file_dont_truncate(inode);
 
                f2fs_up_write(&sbi->pin_sem);
@@ -1758,7 +1755,7 @@ next_alloc:
 
                map.m_len = expanded;
        } else {
-               err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_AIO);
+               err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_PRE_AIO);
                expanded = map.m_len;
        }
 out_err:
@@ -1809,7 +1806,7 @@ static long f2fs_fallocate(struct file *file, int mode,
                return -EOPNOTSUPP;
 
        /*
-        * Pinned file should not support partial trucation since the block
+        * Pinned file should not support partial truncation since the block
         * can be used by applications.
         */
        if ((f2fs_compressed_file(inode) || f2fs_is_pinned_file(inode)) &&
@@ -1832,7 +1829,7 @@ static long f2fs_fallocate(struct file *file, int mode,
                if (offset >= inode->i_size)
                        goto out;
 
-               ret = punch_hole(inode, offset, len);
+               ret = f2fs_punch_hole(inode, offset, len);
        } else if (mode & FALLOC_FL_COLLAPSE_RANGE) {
                ret = f2fs_collapse_range(inode, offset, len);
        } else if (mode & FALLOC_FL_ZERO_RANGE) {
@@ -1840,7 +1837,7 @@ static long f2fs_fallocate(struct file *file, int mode,
        } else if (mode & FALLOC_FL_INSERT_RANGE) {
                ret = f2fs_insert_range(inode, offset, len);
        } else {
-               ret = expand_inode_data(inode, offset, len, mode);
+               ret = f2fs_expand_inode_data(inode, offset, len, mode);
        }
 
        if (!ret) {
@@ -1859,14 +1856,17 @@ out:
 static int f2fs_release_file(struct inode *inode, struct file *filp)
 {
        /*
-        * f2fs_relase_file is called at every close calls. So we should
+        * f2fs_release_file is called at every close calls. So we should
         * not drop any inmemory pages by close called by other process.
         */
        if (!(filp->f_mode & FMODE_WRITE) ||
                        atomic_read(&inode->i_writecount) != 1)
                return 0;
 
+       inode_lock(inode);
        f2fs_abort_atomic_write(inode, true);
+       inode_unlock(inode);
+
        return 0;
 }
 
@@ -1880,8 +1880,13 @@ 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_I(inode)->atomic_write_task == current)
+       if (F2FS_I(inode)->atomic_write_task == current &&
+                               (current->flags & PF_EXITING)) {
+               inode_lock(inode);
                f2fs_abort_atomic_write(inode, true);
+               inode_unlock(inode);
+       }
+
        return 0;
 }
 
@@ -2087,19 +2092,28 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)
                goto out;
        }
 
-       /* Create a COW inode for atomic write */
-       pinode = f2fs_iget(inode->i_sb, fi->i_pino);
-       if (IS_ERR(pinode)) {
-               f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
-               ret = PTR_ERR(pinode);
-               goto out;
-       }
+       /* Check if the inode already has a COW inode */
+       if (fi->cow_inode == NULL) {
+               /* Create a COW inode for atomic write */
+               pinode = f2fs_iget(inode->i_sb, fi->i_pino);
+               if (IS_ERR(pinode)) {
+                       f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
+                       ret = PTR_ERR(pinode);
+                       goto out;
+               }
 
-       ret = f2fs_get_tmpfile(idmap, pinode, &fi->cow_inode);
-       iput(pinode);
-       if (ret) {
-               f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
-               goto out;
+               ret = f2fs_get_tmpfile(idmap, pinode, &fi->cow_inode);
+               iput(pinode);
+               if (ret) {
+                       f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
+                       goto out;
+               }
+
+               set_inode_flag(fi->cow_inode, FI_COW_FILE);
+               clear_inode_flag(fi->cow_inode, FI_INLINE_DATA);
+       } else {
+               /* Reuse the already created COW inode */
+               f2fs_do_truncate_blocks(fi->cow_inode, 0, true);
        }
 
        f2fs_write_inode(inode, NULL);
@@ -2107,8 +2121,6 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)
        stat_inc_atomic_inode(inode);
 
        set_inode_flag(inode, FI_ATOMIC_FILE);
-       set_inode_flag(fi->cow_inode, FI_COW_FILE);
-       clear_inode_flag(fi->cow_inode, FI_INLINE_DATA);
 
        isize = i_size_read(inode);
        fi->original_i_size = isize;
@@ -2338,6 +2350,7 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       u8 encrypt_pw_salt[16];
        int err;
 
        if (!f2fs_sb_has_encrypt(sbi))
@@ -2362,12 +2375,14 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg)
                goto out_err;
        }
 got_it:
-       if (copy_to_user((__u8 __user *)arg, sbi->raw_super->encrypt_pw_salt,
-                                                                       16))
-               err = -EFAULT;
+       memcpy(encrypt_pw_salt, sbi->raw_super->encrypt_pw_salt, 16);
 out_err:
        f2fs_up_write(&sbi->sb_lock);
        mnt_drop_write_file(filp);
+
+       if (!err && copy_to_user((__u8 __user *)arg, encrypt_pw_salt, 16))
+               err = -EFAULT;
+
        return err;
 }
 
@@ -2524,7 +2539,7 @@ static int f2fs_ioc_gc_range(struct file *filp, unsigned long arg)
        return __f2fs_ioc_gc_range(filp, &range);
 }
 
-static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg)
+static int f2fs_ioc_write_checkpoint(struct file *filp)
 {
        struct inode *inode = file_inode(filp);
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -2606,7 +2621,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
         */
        while (map.m_lblk < pg_end) {
                map.m_len = pg_end - map.m_lblk;
-               err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT);
+               err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_DEFAULT);
                if (err)
                        goto out;
 
@@ -2653,7 +2668,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
 
 do_map:
                map.m_len = pg_end - map.m_lblk;
-               err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT);
+               err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_DEFAULT);
                if (err)
                        goto clear_out;
 
@@ -3227,7 +3242,7 @@ int f2fs_precache_extents(struct inode *inode)
                map.m_len = end - map.m_lblk;
 
                f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
-               err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_PRECACHE);
+               err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_PRECACHE);
                f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
                if (err)
                        return err;
@@ -3238,7 +3253,7 @@ int f2fs_precache_extents(struct inode *inode)
        return 0;
 }
 
-static int f2fs_ioc_precache_extents(struct file *filp, unsigned long arg)
+static int f2fs_ioc_precache_extents(struct file *filp)
 {
        return f2fs_precache_extents(file_inode(filp));
 }
@@ -3942,7 +3957,7 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
                goto out;
        }
 
-       if (inode->i_size != 0) {
+       if (F2FS_HAS_BLOCKS(inode)) {
                ret = -EFBIG;
                goto out;
        }
@@ -3995,7 +4010,7 @@ static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len)
        return ret;
 }
 
-static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg)
+static int f2fs_ioc_decompress_file(struct file *filp)
 {
        struct inode *inode = file_inode(filp);
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -4068,7 +4083,7 @@ out:
        return ret;
 }
 
-static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
+static int f2fs_ioc_compress_file(struct file *filp)
 {
        struct inode *inode = file_inode(filp);
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -4184,7 +4199,7 @@ static 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_write_checkpoint(filp, arg);
+               return f2fs_ioc_write_checkpoint(filp);
        case F2FS_IOC_DEFRAGMENT:
                return f2fs_ioc_defragment(filp, arg);
        case F2FS_IOC_MOVE_RANGE:
@@ -4198,7 +4213,7 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        case F2FS_IOC_SET_PIN_FILE:
                return f2fs_ioc_set_pin_file(filp, arg);
        case F2FS_IOC_PRECACHE_EXTENTS:
-               return f2fs_ioc_precache_extents(filp, arg);
+               return f2fs_ioc_precache_extents(filp);
        case F2FS_IOC_RESIZE_FS:
                return f2fs_ioc_resize_fs(filp, arg);
        case FS_IOC_ENABLE_VERITY:
@@ -4224,9 +4239,9 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        case F2FS_IOC_SET_COMPRESS_OPTION:
                return f2fs_ioc_set_compress_option(filp, arg);
        case F2FS_IOC_DECOMPRESS_FILE:
-               return f2fs_ioc_decompress_file(filp, arg);
+               return f2fs_ioc_decompress_file(filp);
        case F2FS_IOC_COMPRESS_FILE:
-               return f2fs_ioc_compress_file(filp, arg);
+               return f2fs_ioc_compress_file(filp);
        default:
                return -ENOTTY;
        }
@@ -4341,6 +4356,27 @@ out:
        return ret;
 }
 
+static void f2fs_trace_rw_file_path(struct kiocb *iocb, size_t count, int rw)
+{
+       struct inode *inode = file_inode(iocb->ki_filp);
+       char *buf, *path;
+
+       buf = f2fs_kmalloc(F2FS_I_SB(inode), PATH_MAX, GFP_KERNEL);
+       if (!buf)
+               return;
+       path = dentry_path_raw(file_dentry(iocb->ki_filp), buf, PATH_MAX);
+       if (IS_ERR(path))
+               goto free_buf;
+       if (rw == WRITE)
+               trace_f2fs_datawrite_start(inode, iocb->ki_pos, count,
+                               current->pid, path, current->comm);
+       else
+               trace_f2fs_dataread_start(inode, iocb->ki_pos, count,
+                               current->pid, path, current->comm);
+free_buf:
+       kfree(buf);
+}
+
 static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
        struct inode *inode = file_inode(iocb->ki_filp);
@@ -4350,24 +4386,9 @@ static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
        if (!f2fs_is_compress_backend_ready(inode))
                return -EOPNOTSUPP;
 
-       if (trace_f2fs_dataread_start_enabled()) {
-               char *p = f2fs_kmalloc(F2FS_I_SB(inode), PATH_MAX, GFP_KERNEL);
-               char *path;
-
-               if (!p)
-                       goto skip_read_trace;
+       if (trace_f2fs_dataread_start_enabled())
+               f2fs_trace_rw_file_path(iocb, iov_iter_count(to), READ);
 
-               path = dentry_path_raw(file_dentry(iocb->ki_filp), p, PATH_MAX);
-               if (IS_ERR(path)) {
-                       kfree(p);
-                       goto skip_read_trace;
-               }
-
-               trace_f2fs_dataread_start(inode, pos, iov_iter_count(to),
-                                       current->pid, path, current->comm);
-               kfree(p);
-       }
-skip_read_trace:
        if (f2fs_should_use_dio(inode, iocb, to)) {
                ret = f2fs_dio_read_iter(iocb, to);
        } else {
@@ -4466,7 +4487,7 @@ static int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *iter,
                flag = F2FS_GET_BLOCK_PRE_AIO;
        }
 
-       ret = f2fs_map_blocks(inode, &map, 1, flag);
+       ret = f2fs_map_blocks(inode, &map, flag);
        /* -ENOSPC|-EDQUOT are fine to report the number of allocated blocks. */
        if (ret < 0 && !((ret == -ENOSPC || ret == -EDQUOT) && map.m_len > 0))
                return ret;
@@ -4673,24 +4694,9 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (preallocated < 0) {
                ret = preallocated;
        } else {
-               if (trace_f2fs_datawrite_start_enabled()) {
-                       char *p = f2fs_kmalloc(F2FS_I_SB(inode),
-                                               PATH_MAX, GFP_KERNEL);
-                       char *path;
-
-                       if (!p)
-                               goto skip_write_trace;
-                       path = dentry_path_raw(file_dentry(iocb->ki_filp),
-                                                               p, PATH_MAX);
-                       if (IS_ERR(path)) {
-                               kfree(p);
-                               goto skip_write_trace;
-                       }
-                       trace_f2fs_datawrite_start(inode, orig_pos, orig_count,
-                                       current->pid, path, current->comm);
-                       kfree(p);
-               }
-skip_write_trace:
+               if (trace_f2fs_datawrite_start_enabled())
+                       f2fs_trace_rw_file_path(iocb, orig_count, WRITE);
+
                /* Do the actual write. */
                ret = dio ?
                        f2fs_dio_write_iter(iocb, from, &may_need_sync) :
@@ -4823,6 +4829,7 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case F2FS_IOC32_MOVE_RANGE:
                return f2fs_compat_ioc_move_range(file, arg);
        case F2FS_IOC_START_ATOMIC_WRITE:
+       case F2FS_IOC_START_ATOMIC_REPLACE:
        case F2FS_IOC_COMMIT_ATOMIC_WRITE:
        case F2FS_IOC_START_VOLATILE_WRITE:
        case F2FS_IOC_RELEASE_VOLATILE_WRITE: