Messages in this thread Patch in this message |  | | Date | Sat, 18 Aug 2018 08:35:18 -0700 | From | Jaegeuk Kim <> | Subject | Re: [PATCH 2/2] f2fs: guarantee journalled quota data by checkpoint |
| |
On 08/17, Chao Yu wrote: > For journalled quota mode, let checkpoint to flush dquot dirty data > and quota file data to keep all file quota info are consisting in > last checkpoint, so that we can avoid quota file being corrupted > after SPO.
This breaks fault injection + shutdown loop like below.
[736914.430526] WARNING: CPU: 1 PID: 22233 at fs/quota/dquot.c:626 dquot_writeback_dquots+0x27d/0x290 [736914.434605] Modules linked in: f2fs(OE) quota_v2 quota_tree brd sb_edac crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel aes_x86_64 crypto_simd cryptd glue_helper vmw_balloon intel_rapl_perf joydev input_leds serio_raw i2c_piix4 mac_hid vmw_vsock_vmci_transport vsock vmw_vmci ip_tables x_tables autofs4 vmwgfx ttm drm_kms_helper syscopyarea mptspi sysfillrect mptscsih sysimgblt mptbase fb_sys_fops psmouse pata_acpi scsi_transport_spi ahci drm e1000 libahci [last unloaded: f2fs] [736914.450269] CPU: 1 PID: 22233 Comm: fsstress Tainted: G W OE 4.18.0-rc3+ #5 [736914.453262] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017 [736914.457537] RIP: 0010:dquot_writeback_dquots+0x27d/0x290 [736914.459664] Code: 4d 89 7f 08 4c 89 f7 e8 51 17 70 00 8b 54 24 0c e9 e2 fe ff ff 0f 0b e9 7d fe ff ff 0f 0b e9 67 fe ff ff 0f 0b e9 51 fe ff ff <0f> 0b e9 a2 fd ff ff 66 90 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 [736914.467064] RSP: 0018:ffffb1f20111bb40 EFLAGS: 00010246 [736914.469132] RAX: 0000000000000000 RBX: ffff8e93f284a000 RCX: 0000000000000000 [736914.471581] RDX: ffffb1f20111bbf0 RSI: 00000000ffffffff RDI: ffff8e93f0674000 [736914.474043] RBP: ffff8e93f0674000 R08: ffffffffc06a9aa0 R09: 0000000000000000 [736914.476470] R10: ffffb1f20111bcc0 R11: 0000000000000000 R12: 00000000ffffffff [736914.479092] R13: ffff8e93f0674000 R14: 0000000000000001 R15: ffff8e93f0674000 [736914.481765] FS: 00007f2b98aa3b80(0000) GS:ffff8e93f9640000(0000) knlGS:0000000000000000 [736914.484568] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [736914.486713] CR2: 00007f2b98aa2000 CR3: 0000000131c3c001 CR4: 00000000003606e0 [736914.489213] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [736914.491660] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [736914.494085] Call Trace: [736914.495365] f2fs_quota_sync+0x1a/0xd0 [f2fs] [736914.497054] block_operations+0x94/0x2c0 [f2fs] [736914.499032] ? f2fs_write_checkpoint+0x50/0x11e0 [f2fs] [736914.500897] ? f2fs_write_checkpoint+0xbb/0x11e0 [f2fs] [736914.502770] f2fs_write_checkpoint+0xbb/0x11e0 [f2fs] [736914.504580] ? f2fs_sync_fs+0xb0/0x1f0 [f2fs] [736914.506252] ? __mutex_lock+0x7f/0xa10 [736914.507710] ? f2fs_sync_fs+0xb0/0x1f0 [f2fs] [736914.509333] ? pagevec_lookup_range_tag+0x24/0x30 [736914.510989] ? __filemap_fdatawait_range+0x7d/0x150 [736914.512724] f2fs_sync_fs+0xbd/0x1f0 [f2fs] [736914.514344] f2fs_do_sync_file+0x196/0xa30 [f2fs] [736914.515995] do_fsync+0x38/0x60 [736914.517289] __x64_sys_fdatasync+0x13/0x20 [736914.518912] do_syscall_64+0x60/0x1b0 [736914.520398] entry_SYSCALL_64_after_hwframe+0x49/0xbe ... [736920.063443] BUG: unable to handle kernel paging request at ffffffffd9c019eb [736920.066262] PGD 78414067 P4D 78414067 PUD 78416067 PMD 0 [736920.068403] Oops: 0000 [#1] SMP PTI [736920.070055] CPU: 2 PID: 22236 Comm: fsstress Tainted: G W OE 4.18.0-rc3+ #5 [736920.072792] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017 [736920.076756] RIP: 0010:do_raw_spin_lock+0x6/0xc0 [736920.078644] Code: 49 89 f9 48 c7 c7 c8 8b ee b3 65 8b 15 13 c0 30 4d e8 2c 00 01 00 e9 5e 50 92 00 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 53 <81> 7f 04 ad 4e ad de 48 89 fb 75 43 65 48 8b 04 25 c0 5d 01 00 48 [736920.085417] RSP: 0018:ffffb1f20128fbc8 EFLAGS: 00010286 [736920.087505] RAX: ffffffffb2f4a1d3 RBX: ffffffffd9c01927 RCX: 0000000000000000 [736920.090068] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffffffffd9c019e7 [736920.092589] RBP: 0000000000000001 R08: ffffffffb2f4a1d3 R09: 0000000000000000 [736920.095009] R10: ffffb1f20128fb58 R11: 0000000000000000 R12: ffffb1f20128fc58 [736920.097437] R13: ffffffffd9c019e7 R14: 0000000000000000 R15: ffff8e934fe29788 [736920.099823] FS: 00007f2b98aa3b80(0000) GS:ffff8e93f9680000(0000) knlGS:0000000000000000 [736920.102469] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [736920.104569] CR2: ffffffffd9c019eb CR3: 00000001282dc002 CR4: 00000000003606e0 [736920.107140] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [736920.109517] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [736920.111845] Call Trace: [736920.113111] dquot_add_inodes+0x23/0x1a0 [736920.114665] __dquot_transfer+0x3d6/0x5f0 [736920.116233] ? lock_acquire+0xb4/0x220 [736920.117718] ? dqput.part.14+0x35/0x200 [736920.119212] ? online_pages+0x1a0/0x2d0 [736920.120699] ? dqget+0x424/0x490 [736920.122038] dquot_transfer+0xce/0x150 [736920.123500] f2fs_setattr+0xba/0x420 [f2fs] [736920.125138] ? current_time+0x4d/0x90 [736920.126676] notify_change+0x2eb/0x440 [736920.128117] chown_common+0x1ac/0x1d0 [736920.129670] do_fchownat+0xc7/0xe0 [736920.131070] __x64_sys_lchown+0x21/0x30 [736920.132559] do_syscall_64+0x60/0x1b0 [736920.134011] entry_SYSCALL_64_after_hwframe+0x49/0xbe [736920.135699] RIP: 0033:0x7f2b97f893a7
> > Signed-off-by: Weichao Guo <guoweichao@huawei.com> > Signed-off-by: Chao Yu <yuchao0@huawei.com> > --- > fs/f2fs/checkpoint.c | 12 ++++++++ > fs/f2fs/data.c | 4 ++- > fs/f2fs/f2fs.h | 2 ++ > fs/f2fs/super.c | 67 ++++++++++++++++++++++++++++++++++++++++---- > 4 files changed, 78 insertions(+), 7 deletions(-) > > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c > index 0274446f585e..cf8d1bb8ec3e 100644 > --- a/fs/f2fs/checkpoint.c > +++ b/fs/f2fs/checkpoint.c > @@ -1100,7 +1100,19 @@ static int block_operations(struct f2fs_sb_info *sbi) > blk_start_plug(&plug); > > retry_flush_dents: > + if (is_sbi_flag_set(sbi, SBI_NEED_FLUSH_QUOTA)) { > + clear_sbi_flag(sbi, SBI_NEED_FLUSH_QUOTA); > + err = f2fs_quota_sync(sbi->sb, -1); > + if (err) > + goto out; > + } > + > f2fs_lock_all(sbi); > + if (is_sbi_flag_set(sbi, SBI_NEED_FLUSH_QUOTA)) { > + f2fs_unlock_all(sbi); > + goto retry_flush_dents; > + } > + > /* write all the dirty dentry pages */ > if (get_pages(sbi, F2FS_DIRTY_DENTS)) { > f2fs_unlock_all(sbi); > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > index 8e754710c746..0bfb10cd9ad2 100644 > --- a/fs/f2fs/data.c > +++ b/fs/f2fs/data.c > @@ -49,7 +49,7 @@ static bool __is_cp_guaranteed(struct page *page) > inode->i_ino == F2FS_NODE_INO(sbi) || > S_ISDIR(inode->i_mode) || > (S_ISREG(inode->i_mode) && > - is_inode_flag_set(inode, FI_ATOMIC_FILE)) || > + (f2fs_is_atomic_file(inode) || IS_NOQUOTA(inode))) || > is_cold_data(page)) > return true; > return false; > @@ -1721,6 +1721,8 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) > } > if (S_ISDIR(inode->i_mode)) > return true; > + if (IS_NOQUOTA(inode)) > + return true; > if (f2fs_is_atomic_file(inode)) > return true; > if (fio) { > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 54ee8217092e..b7ba5aaeb61e 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -1093,6 +1093,7 @@ enum { > SBI_NEED_CP, /* need to checkpoint */ > SBI_IS_SHUTDOWN, /* shutdown by ioctl */ > SBI_CP_DISABLED, /* CP was disabled last mount */ > + SBI_NEED_FLUSH_QUOTA, /* need to flush quota info in CP */ > }; > > enum { > @@ -2888,6 +2889,7 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) > int f2fs_inode_dirtied(struct inode *inode, bool sync); > void f2fs_inode_synced(struct inode *inode); > int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly); > +int f2fs_quota_sync(struct super_block *sb, int type); > void f2fs_quota_off_umount(struct super_block *sb); > int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover); > int f2fs_sync_fs(struct super_block *sb, int sync); > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > index 9647bbcdfd2b..f1482363b4eb 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -1886,7 +1886,7 @@ static int f2fs_enable_quotas(struct super_block *sb) > return 0; > } > > -static int f2fs_quota_sync(struct super_block *sb, int type) > +int f2fs_quota_sync(struct super_block *sb, int type) > { > struct quota_info *dqopt = sb_dqopt(sb); > int cnt; > @@ -1988,6 +1988,61 @@ void f2fs_quota_off_umount(struct super_block *sb) > } > } > > +static int f2fs_dquot_commit(struct dquot *dquot) > +{ > + int ret; > + > + ret = dquot_commit(dquot); > + if (ret == -ENOSPC || ret == -EIO) > + set_sbi_flag(F2FS_SB(dquot->dq_sb), SBI_NEED_FSCK); > + return ret; > +} > + > +static int f2fs_dquot_acquire(struct dquot *dquot) > +{ > + int ret; > + > + ret = dquot_acquire(dquot); > + if (ret == -ENOSPC || ret == -EIO) > + set_sbi_flag(F2FS_SB(dquot->dq_sb), SBI_NEED_FSCK); > + return ret; > +} > + > +static int f2fs_dquot_release(struct dquot *dquot) > +{ > + int ret; > + > + ret = dquot_release(dquot); > + if (ret == -ENOSPC || ret == -EIO) > + set_sbi_flag(F2FS_SB(dquot->dq_sb), SBI_NEED_FSCK); > + return ret; > +} > + > +static int f2fs_dquot_mark_dquot_dirty(struct dquot *dquot) > +{ > + struct super_block *sb = dquot->dq_sb; > + struct f2fs_sb_info *sbi = F2FS_SB(sb); > + > + /* if we are using journalled quota */ > + if (f2fs_sb_has_quota_ino(sbi) || > + F2FS_OPTION(sbi).s_qf_names[USRQUOTA] || > + F2FS_OPTION(sbi).s_qf_names[GRPQUOTA] || > + F2FS_OPTION(sbi).s_qf_names[PRJQUOTA]) > + set_sbi_flag(sbi, SBI_NEED_FLUSH_QUOTA); > + > + return dquot_mark_dquot_dirty(dquot); > +} > + > +static int f2fs_dquot_commit_info(struct super_block *sb, int type) > +{ > + int ret; > + > + ret = dquot_commit_info(sb, type); > + if (ret == -ENOSPC || ret == -EIO) > + set_sbi_flag(F2FS_SB(sb), SBI_NEED_FSCK); > + return ret; > +} > + > static int f2fs_get_projid(struct inode *inode, kprojid_t *projid) > { > *projid = F2FS_I(inode)->i_projid; > @@ -1996,11 +2051,11 @@ static int f2fs_get_projid(struct inode *inode, kprojid_t *projid) > > static const struct dquot_operations f2fs_quota_operations = { > .get_reserved_space = f2fs_get_reserved_space, > - .write_dquot = dquot_commit, > - .acquire_dquot = dquot_acquire, > - .release_dquot = dquot_release, > - .mark_dirty = dquot_mark_dquot_dirty, > - .write_info = dquot_commit_info, > + .write_dquot = f2fs_dquot_commit, > + .acquire_dquot = f2fs_dquot_acquire, > + .release_dquot = f2fs_dquot_release, > + .mark_dirty = f2fs_dquot_mark_dquot_dirty, > + .write_info = f2fs_dquot_commit_info, > .alloc_dquot = dquot_alloc, > .destroy_dquot = dquot_destroy, > .get_projid = f2fs_get_projid, > -- > 2.18.0.rc1
|  |