Merge tag 'block-6.1-2022-10-20' of git://git.kernel.dk/linux
[linux-block.git] / fs / f2fs / file.c
index 79177050732803eadd5e3d3bb68577b67e743ccc..82cda12582272a0040fe168beb454d787b0e2af1 100644 (file)
@@ -43,8 +43,8 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
 
        ret = filemap_fault(vmf);
        if (!ret)
-               f2fs_update_iostat(F2FS_I_SB(inode), APP_MAPPED_READ_IO,
-                                                       F2FS_BLKSIZE);
+               f2fs_update_iostat(F2FS_I_SB(inode), inode,
+                                       APP_MAPPED_READ_IO, F2FS_BLKSIZE);
 
        trace_f2fs_filemap_fault(inode, vmf->pgoff, (unsigned long)ret);
 
@@ -154,7 +154,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
        if (!PageUptodate(page))
                SetPageUptodate(page);
 
-       f2fs_update_iostat(sbi, APP_MAPPED_IO, F2FS_BLKSIZE);
+       f2fs_update_iostat(sbi, inode, APP_MAPPED_IO, F2FS_BLKSIZE);
        f2fs_update_time(sbi, REQ_TIME);
 
        trace_f2fs_vm_page_mkwrite(page, DATA);
@@ -822,7 +822,12 @@ static bool f2fs_force_buffered_io(struct inode *inode, int rw)
        /* disallow direct IO if any of devices has unaligned blksize */
        if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize)
                return true;
-
+       /*
+        * for blkzoned device, fallback direct IO to buffered IO, so
+        * all IOs can be serialized by log-structured write.
+        */
+       if (f2fs_sb_has_blkzoned(sbi) && (rw == WRITE))
+               return true;
        if (f2fs_lfs_mode(sbi) && rw == WRITE && F2FS_IO_ALIGNED(sbi))
                return true;
        if (is_sbi_flag_set(sbi, SBI_CP_DISABLED))
@@ -912,9 +917,10 @@ static void __setattr_copy(struct user_namespace *mnt_userns,
                inode->i_ctime = attr->ia_ctime;
        if (ia_valid & ATTR_MODE) {
                umode_t mode = attr->ia_mode;
-               kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
+               vfsgid_t vfsgid = i_gid_into_vfsgid(mnt_userns, inode);
 
-               if (!in_group_p(kgid) && !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
+               if (!vfsgid_in_group_p(vfsgid) &&
+                   !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
                        mode &= ~S_ISGID;
                set_acl_inode(inode, mode);
        }
@@ -1196,6 +1202,7 @@ next_dnode:
                        !f2fs_is_valid_blkaddr(sbi, *blkaddr,
                                        DATA_GENERIC_ENHANCE)) {
                        f2fs_put_dnode(&dn);
+                       f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
                        return -EFSCORRUPTED;
                }
 
@@ -1480,6 +1487,7 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start,
                if (!f2fs_is_valid_blkaddr(sbi, dn->data_blkaddr,
                                        DATA_GENERIC_ENHANCE)) {
                        ret = -EFSCORRUPTED;
+                       f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
                        break;
                }
 
@@ -2089,9 +2097,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
        }
        f2fs_i_size_write(fi->cow_inode, i_size_read(inode));
 
-       spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
-       sbi->atomic_files++;
-       spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
+       stat_inc_atomic_inode(inode);
 
        set_inode_flag(inode, FI_ATOMIC_FILE);
        set_inode_flag(fi->cow_inode, FI_COW_FILE);
@@ -2185,7 +2191,8 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
                if (ret) {
                        if (ret == -EROFS) {
                                ret = 0;
-                               f2fs_stop_checkpoint(sbi, false);
+                               f2fs_stop_checkpoint(sbi, false,
+                                               STOP_CP_REASON_SHUTDOWN);
                                set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                                trace_f2fs_shutdown(sbi, in, ret);
                        }
@@ -2198,7 +2205,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
                ret = freeze_bdev(sb->s_bdev);
                if (ret)
                        goto out;
-               f2fs_stop_checkpoint(sbi, false);
+               f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
                set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                thaw_bdev(sb->s_bdev);
                break;
@@ -2207,16 +2214,16 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
                ret = f2fs_sync_fs(sb, 1);
                if (ret)
                        goto out;
-               f2fs_stop_checkpoint(sbi, false);
+               f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
                set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                break;
        case F2FS_GOING_DOWN_NOSYNC:
-               f2fs_stop_checkpoint(sbi, false);
+               f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
                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);
+               f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
                set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                break;
        case F2FS_GOING_DOWN_NEED_FSCK:
@@ -3362,8 +3369,10 @@ static int release_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
                if (!__is_valid_data_blkaddr(blkaddr))
                        continue;
                if (unlikely(!f2fs_is_valid_blkaddr(sbi, blkaddr,
-                                       DATA_GENERIC_ENHANCE)))
+                                       DATA_GENERIC_ENHANCE))) {
+                       f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
                        return -EFSCORRUPTED;
+               }
        }
 
        while (count) {
@@ -3524,8 +3533,10 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
                if (!__is_valid_data_blkaddr(blkaddr))
                        continue;
                if (unlikely(!f2fs_is_valid_blkaddr(sbi, blkaddr,
-                                       DATA_GENERIC_ENHANCE)))
+                                       DATA_GENERIC_ENHANCE))) {
+                       f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
                        return -EFSCORRUPTED;
+               }
        }
 
        while (count) {
@@ -3797,6 +3808,8 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg)
                                                DATA_GENERIC_ENHANCE)) {
                                ret = -EFSCORRUPTED;
                                f2fs_put_dnode(&dn);
+                               f2fs_handle_error(sbi,
+                                               ERROR_INVALID_BLKADDR);
                                goto out;
                        }
 
@@ -4253,7 +4266,7 @@ static int f2fs_dio_read_end_io(struct kiocb *iocb, ssize_t size, int error,
        dec_page_count(sbi, F2FS_DIO_READ);
        if (error)
                return error;
-       f2fs_update_iostat(sbi, APP_DIRECT_READ_IO, size);
+       f2fs_update_iostat(sbi, NULL, APP_DIRECT_READ_IO, size);
        return 0;
 }
 
@@ -4342,7 +4355,8 @@ skip_read_trace:
        } else {
                ret = filemap_read(iocb, to, 0);
                if (ret > 0)
-                       f2fs_update_iostat(F2FS_I_SB(inode), APP_BUFFERED_READ_IO, ret);
+                       f2fs_update_iostat(F2FS_I_SB(inode), inode,
+                                               APP_BUFFERED_READ_IO, ret);
        }
        if (trace_f2fs_dataread_end_enabled())
                trace_f2fs_dataread_end(inode, pos, ret);
@@ -4459,7 +4473,8 @@ static ssize_t f2fs_buffered_write_iter(struct kiocb *iocb,
 
        if (ret > 0) {
                iocb->ki_pos += ret;
-               f2fs_update_iostat(F2FS_I_SB(inode), APP_BUFFERED_IO, ret);
+               f2fs_update_iostat(F2FS_I_SB(inode), inode,
+                                               APP_BUFFERED_IO, ret);
        }
        return ret;
 }
@@ -4472,7 +4487,7 @@ static int f2fs_dio_write_end_io(struct kiocb *iocb, ssize_t size, int error,
        dec_page_count(sbi, F2FS_DIO_WRITE);
        if (error)
                return error;
-       f2fs_update_iostat(sbi, APP_DIRECT_IO, size);
+       f2fs_update_iostat(sbi, NULL, APP_DIRECT_IO, size);
        return 0;
 }
 
@@ -4660,7 +4675,7 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 skip_write_trace:
                /* Do the actual write. */
                ret = dio ?
-                       f2fs_dio_write_iter(iocb, from, &may_need_sync):
+                       f2fs_dio_write_iter(iocb, from, &may_need_sync) :
                        f2fs_buffered_write_iter(iocb, from);
 
                if (trace_f2fs_datawrite_end_enabled())