* [f2fs-dev] [PATCH 1/2] f2fs: correct i_size change for atomic writes @ 2022-09-19 16:06 Daeho Jeong 2022-09-19 16:06 ` [f2fs-dev] [PATCH 2/2] f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE Daeho Jeong 2022-09-29 6:58 ` [f2fs-dev] [PATCH 1/2] f2fs: correct i_size change for atomic writes Chao Yu 0 siblings, 2 replies; 4+ messages in thread From: Daeho Jeong @ 2022-09-19 16:06 UTC (permalink / raw) To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong From: Daeho Jeong <daehojeong@google.com> We need to make sure i_size doesn't change until atomic write commit is successful and restore it when commit is failed. Signed-off-by: Daeho Jeong <daehojeong@google.com> --- fs/f2fs/f2fs.h | 1 + fs/f2fs/file.c | 16 +++++++++------- fs/f2fs/inode.c | 3 +++ fs/f2fs/segment.c | 4 +++- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index dee7b67a17a6..539da7f12cfc 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -821,6 +821,7 @@ struct f2fs_inode_info { unsigned int i_cluster_size; /* cluster size */ unsigned int atomic_write_cnt; + loff_t original_i_size; /* original i_size before atomic write */ }; static inline void get_extent_info(struct extent_info *ext, diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 5efe0e4a725a..4f9b80c41b1e 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1989,6 +1989,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct inode *pinode; + loff_t isize; int ret; if (!inode_owner_or_capable(mnt_userns, inode)) @@ -2047,7 +2048,10 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) f2fs_up_write(&fi->i_gc_rwsem[WRITE]); goto out; } - f2fs_i_size_write(fi->cow_inode, i_size_read(inode)); + + isize = i_size_read(inode); + fi->original_i_size = isize; + f2fs_i_size_write(fi->cow_inode, isize); spin_lock(&sbi->inode_lock[ATOMIC_FILE]); sbi->atomic_files++; @@ -2087,16 +2091,14 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) if (f2fs_is_atomic_file(inode)) { ret = f2fs_commit_atomic_write(inode); - if (ret) - goto unlock_out; - - ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true); if (!ret) - f2fs_abort_atomic_write(inode, false); + ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true); + + f2fs_abort_atomic_write(inode, ret); } else { ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false); } -unlock_out: + inode_unlock(inode); mnt_drop_write_file(filp); return ret; diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index cde0a3dc80c3..64d7772b4cd9 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -30,6 +30,9 @@ void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) if (f2fs_inode_dirtied(inode, sync)) return; + if (f2fs_is_atomic_file(inode)) + return; + mark_inode_dirty_sync(inode); } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 460048f3c850..143b7ea0fb8e 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -193,8 +193,10 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean) if (!f2fs_is_atomic_file(inode)) return; - if (clean) + if (clean) { truncate_inode_pages_final(inode->i_mapping); + f2fs_i_size_write(inode, fi->original_i_size); + } clear_inode_flag(fi->cow_inode, FI_COW_FILE); iput(fi->cow_inode); fi->cow_inode = NULL; -- 2.37.3.968.ga6b4b080e4-goog _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [f2fs-dev] [PATCH 2/2] f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE 2022-09-19 16:06 [f2fs-dev] [PATCH 1/2] f2fs: correct i_size change for atomic writes Daeho Jeong @ 2022-09-19 16:06 ` Daeho Jeong 2022-09-20 1:11 ` kernel test robot 2022-09-29 6:58 ` [f2fs-dev] [PATCH 1/2] f2fs: correct i_size change for atomic writes Chao Yu 1 sibling, 1 reply; 4+ messages in thread From: Daeho Jeong @ 2022-09-19 16:06 UTC (permalink / raw) To: linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong From: Daeho Jeong <daehojeong@google.com> introduce a new ioctl to replace the whole content of a file atomically, which means it induces truncate and content update at the same time. We can start it with F2FS_IOC_START_ATOMIC_REPLACE and complete it with F2FS_IOC_COMMIT_ATOMIC_WRITE. Or abort it with F2FS_IOC_ABORT_ATOMIC_WRITE. Signed-off-by: Daeho Jeong <daehojeong@google.com> --- fs/f2fs/data.c | 3 +++ fs/f2fs/f2fs.h | 1 + fs/f2fs/file.c | 12 ++++++++++-- fs/f2fs/segment.c | 14 +++++++++++++- include/uapi/linux/f2fs.h | 2 ++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 6cd29a575105..eef798b3e941 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3438,6 +3438,9 @@ static int prepare_atomic_write_begin(struct f2fs_sb_info *sbi, else if (*blk_addr != NULL_ADDR) return 0; + if (is_inode_flag_set(inode, FI_ATOMIC_TRUNCATED)) + goto reserve_block; + /* Look for the block in the original inode */ err = __find_data_block(inode, index, &ori_blk_addr); if (err) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 539da7f12cfc..79e7bed009bc 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -764,6 +764,7 @@ enum { FI_COMPRESS_RELEASED, /* compressed blocks were released */ FI_ALIGNED_WRITE, /* enable aligned write */ FI_COW_FILE, /* indicate COW file */ + FI_ATOMIC_TRUNCATED, /* indicate truncated atomic write */ FI_MAX, /* max flag, never be used */ }; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4f9b80c41b1e..905810c62d47 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1982,7 +1982,7 @@ static int f2fs_ioc_getversion(struct file *filp, unsigned long arg) return put_user(inode->i_generation, (int __user *)arg); } -static int f2fs_ioc_start_atomic_write(struct file *filp) +static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate) { struct inode *inode = file_inode(filp); struct user_namespace *mnt_userns = file_mnt_user_ns(filp); @@ -2051,6 +2051,12 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) isize = i_size_read(inode); fi->original_i_size = isize; + if (truncate) { + set_inode_flag(inode, FI_ATOMIC_TRUNCATED); + truncate_inode_pages_final(inode->i_mapping); + f2fs_i_size_write(inode, 0); + isize = 0; + } f2fs_i_size_write(fi->cow_inode, isize); spin_lock(&sbi->inode_lock[ATOMIC_FILE]); @@ -4080,7 +4086,9 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case FS_IOC_GETVERSION: return f2fs_ioc_getversion(filp, arg); case F2FS_IOC_START_ATOMIC_WRITE: - return f2fs_ioc_start_atomic_write(filp); + return f2fs_ioc_start_atomic_write(filp, false); + case F2FS_IOC_START_ATOMIC_REPLACE: + return f2fs_ioc_start_atomic_write(filp, true); case F2FS_IOC_COMMIT_ATOMIC_WRITE: return f2fs_ioc_commit_atomic_write(filp); case F2FS_IOC_ABORT_ATOMIC_WRITE: diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 143b7ea0fb8e..18aeec957ec9 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -263,14 +263,26 @@ static void __complete_revoke_list(struct inode *inode, struct list_head *head, bool revoke) { struct revoke_entry *cur, *tmp; + pgoff_t start_index = 0; + bool truncate = is_inode_flag_set(inode, FI_ATOMIC_TRUNCATED); list_for_each_entry_safe(cur, tmp, head, list) { - if (revoke) + if (revoke) { __replace_atomic_write_block(inode, cur->index, cur->old_addr, NULL, true); + } else if (truncate) { + f2fs_truncate_hole(inode, start_index, cur->index); + start_index = cur->index + 1; + } + list_del(&cur->list); kmem_cache_free(revoke_entry_slab, cur); } + + if (!revoke && truncate) { + f2fs_do_truncate_blocks(inode, start_index * PAGE_SIZE, false); + clear_inode_flag(inode, FI_ATOMIC_TRUNCATED); + } } static int __f2fs_commit_atomic_write(struct inode *inode) diff --git a/include/uapi/linux/f2fs.h b/include/uapi/linux/f2fs.h index 3121d127d5aa..224d98731f22 100644 --- a/include/uapi/linux/f2fs.h +++ b/include/uapi/linux/f2fs.h @@ -42,6 +42,8 @@ struct f2fs_comp_option) #define F2FS_IOC_DECOMPRESS_FILE _IO(F2FS_IOCTL_MAGIC, 23) #define F2FS_IOC_COMPRESS_FILE _IO(F2FS_IOCTL_MAGIC, 24) +#define F2FS_IOC_START_TRUNC_ATOMIC_WRITE \ + _IO(F2FS_IOCTL_MAGIC, 25) /* * should be same as XFS_IOC_GOINGDOWN. -- 2.37.3.968.ga6b4b080e4-goog _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [f2fs-dev] [PATCH 2/2] f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE 2022-09-19 16:06 ` [f2fs-dev] [PATCH 2/2] f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE Daeho Jeong @ 2022-09-20 1:11 ` kernel test robot 0 siblings, 0 replies; 4+ messages in thread From: kernel test robot @ 2022-09-20 1:11 UTC (permalink / raw) To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team Cc: llvm, kbuild-all, Daeho Jeong Hi Daeho, Thank you for the patch! Yet something to improve: [auto build test ERROR on jaegeuk-f2fs/dev-test] [also build test ERROR on linus/master v6.0-rc6 next-20220919] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Daeho-Jeong/f2fs-correct-i_size-change-for-atomic-writes/20220920-000935 base: https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev-test config: i386-randconfig-a006-20220919 (https://download.01.org/0day-ci/archive/20220920/202209200942.RO5JnVfI-lkp@intel.com/config) compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/884660386769b2359529c52ad0afc06684f1ea87 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Daeho-Jeong/f2fs-correct-i_size-change-for-atomic-writes/20220920-000935 git checkout 884660386769b2359529c52ad0afc06684f1ea87 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash fs/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> fs/f2fs/file.c:4090:7: error: use of undeclared identifier 'F2FS_IOC_START_ATOMIC_REPLACE' case F2FS_IOC_START_ATOMIC_REPLACE: ^ 1 error generated. vim +/F2FS_IOC_START_ATOMIC_REPLACE +4090 fs/f2fs/file.c 4082 4083 static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 4084 { 4085 switch (cmd) { 4086 case FS_IOC_GETVERSION: 4087 return f2fs_ioc_getversion(filp, arg); 4088 case F2FS_IOC_START_ATOMIC_WRITE: 4089 return f2fs_ioc_start_atomic_write(filp, false); > 4090 case F2FS_IOC_START_ATOMIC_REPLACE: 4091 return f2fs_ioc_start_atomic_write(filp, true); 4092 case F2FS_IOC_COMMIT_ATOMIC_WRITE: 4093 return f2fs_ioc_commit_atomic_write(filp); 4094 case F2FS_IOC_ABORT_ATOMIC_WRITE: 4095 return f2fs_ioc_abort_atomic_write(filp); 4096 case F2FS_IOC_START_VOLATILE_WRITE: 4097 case F2FS_IOC_RELEASE_VOLATILE_WRITE: 4098 return -EOPNOTSUPP; 4099 case F2FS_IOC_SHUTDOWN: 4100 return f2fs_ioc_shutdown(filp, arg); 4101 case FITRIM: 4102 return f2fs_ioc_fitrim(filp, arg); 4103 case FS_IOC_SET_ENCRYPTION_POLICY: 4104 return f2fs_ioc_set_encryption_policy(filp, arg); 4105 case FS_IOC_GET_ENCRYPTION_POLICY: 4106 return f2fs_ioc_get_encryption_policy(filp, arg); 4107 case FS_IOC_GET_ENCRYPTION_PWSALT: 4108 return f2fs_ioc_get_encryption_pwsalt(filp, arg); 4109 case FS_IOC_GET_ENCRYPTION_POLICY_EX: 4110 return f2fs_ioc_get_encryption_policy_ex(filp, arg); 4111 case FS_IOC_ADD_ENCRYPTION_KEY: 4112 return f2fs_ioc_add_encryption_key(filp, arg); 4113 case FS_IOC_REMOVE_ENCRYPTION_KEY: 4114 return f2fs_ioc_remove_encryption_key(filp, arg); 4115 case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS: 4116 return f2fs_ioc_remove_encryption_key_all_users(filp, arg); 4117 case FS_IOC_GET_ENCRYPTION_KEY_STATUS: 4118 return f2fs_ioc_get_encryption_key_status(filp, arg); 4119 case FS_IOC_GET_ENCRYPTION_NONCE: 4120 return f2fs_ioc_get_encryption_nonce(filp, arg); 4121 case F2FS_IOC_GARBAGE_COLLECT: 4122 return f2fs_ioc_gc(filp, arg); 4123 case F2FS_IOC_GARBAGE_COLLECT_RANGE: 4124 return f2fs_ioc_gc_range(filp, arg); 4125 case F2FS_IOC_WRITE_CHECKPOINT: 4126 return f2fs_ioc_write_checkpoint(filp, arg); 4127 case F2FS_IOC_DEFRAGMENT: 4128 return f2fs_ioc_defragment(filp, arg); 4129 case F2FS_IOC_MOVE_RANGE: 4130 return f2fs_ioc_move_range(filp, arg); 4131 case F2FS_IOC_FLUSH_DEVICE: 4132 return f2fs_ioc_flush_device(filp, arg); 4133 case F2FS_IOC_GET_FEATURES: 4134 return f2fs_ioc_get_features(filp, arg); 4135 case F2FS_IOC_GET_PIN_FILE: 4136 return f2fs_ioc_get_pin_file(filp, arg); 4137 case F2FS_IOC_SET_PIN_FILE: 4138 return f2fs_ioc_set_pin_file(filp, arg); 4139 case F2FS_IOC_PRECACHE_EXTENTS: 4140 return f2fs_ioc_precache_extents(filp, arg); 4141 case F2FS_IOC_RESIZE_FS: 4142 return f2fs_ioc_resize_fs(filp, arg); 4143 case FS_IOC_ENABLE_VERITY: 4144 return f2fs_ioc_enable_verity(filp, arg); 4145 case FS_IOC_MEASURE_VERITY: 4146 return f2fs_ioc_measure_verity(filp, arg); 4147 case FS_IOC_READ_VERITY_METADATA: 4148 return f2fs_ioc_read_verity_metadata(filp, arg); 4149 case FS_IOC_GETFSLABEL: 4150 return f2fs_ioc_getfslabel(filp, arg); 4151 case FS_IOC_SETFSLABEL: 4152 return f2fs_ioc_setfslabel(filp, arg); 4153 case F2FS_IOC_GET_COMPRESS_BLOCKS: 4154 return f2fs_get_compress_blocks(filp, arg); 4155 case F2FS_IOC_RELEASE_COMPRESS_BLOCKS: 4156 return f2fs_release_compress_blocks(filp, arg); 4157 case F2FS_IOC_RESERVE_COMPRESS_BLOCKS: 4158 return f2fs_reserve_compress_blocks(filp, arg); 4159 case F2FS_IOC_SEC_TRIM_FILE: 4160 return f2fs_sec_trim_file(filp, arg); 4161 case F2FS_IOC_GET_COMPRESS_OPTION: 4162 return f2fs_ioc_get_compress_option(filp, arg); 4163 case F2FS_IOC_SET_COMPRESS_OPTION: 4164 return f2fs_ioc_set_compress_option(filp, arg); 4165 case F2FS_IOC_DECOMPRESS_FILE: 4166 return f2fs_ioc_decompress_file(filp, arg); 4167 case F2FS_IOC_COMPRESS_FILE: 4168 return f2fs_ioc_compress_file(filp, arg); 4169 default: 4170 return -ENOTTY; 4171 } 4172 } 4173 -- 0-DAY CI Kernel Test Service https://01.org/lkp _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [f2fs-dev] [PATCH 1/2] f2fs: correct i_size change for atomic writes 2022-09-19 16:06 [f2fs-dev] [PATCH 1/2] f2fs: correct i_size change for atomic writes Daeho Jeong 2022-09-19 16:06 ` [f2fs-dev] [PATCH 2/2] f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE Daeho Jeong @ 2022-09-29 6:58 ` Chao Yu 1 sibling, 0 replies; 4+ messages in thread From: Chao Yu @ 2022-09-29 6:58 UTC (permalink / raw) To: Daeho Jeong, linux-kernel, linux-f2fs-devel, kernel-team; +Cc: Daeho Jeong On 2022/9/20 0:06, Daeho Jeong wrote: > From: Daeho Jeong <daehojeong@google.com> > > We need to make sure i_size doesn't change until atomic write commit is > successful and restore it when commit is failed. > > Signed-off-by: Daeho Jeong <daehojeong@google.com> Reviewed-by: Chao Yu <chao@kernel.org> Thanks, _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-09-29 6:58 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-09-19 16:06 [f2fs-dev] [PATCH 1/2] f2fs: correct i_size change for atomic writes Daeho Jeong 2022-09-19 16:06 ` [f2fs-dev] [PATCH 2/2] f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE Daeho Jeong 2022-09-20 1:11 ` kernel test robot 2022-09-29 6:58 ` [f2fs-dev] [PATCH 1/2] f2fs: correct i_size change for atomic writes Chao Yu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).