From: Dave Chinner Date: Mon, 4 Aug 2014 02:43:26 +0000 (+1000) Subject: xfs: quotacheck leaves dquot buffers without verifiers X-Git-Tag: firefly_0821_release~3679^2~1570 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=9a9237c9e897fd73ee74689fc319a6412f4377f9;p=firefly-linux-kernel-4.4.55.git xfs: quotacheck leaves dquot buffers without verifiers commit 5fd364fee81a7888af806e42ed8a91c845894f2d upstream. When running xfs/305, I noticed that quotacheck was flushing dquot buffers that did not have the xfs_dquot_buf_ops verifiers attached: XFS (vdb): _xfs_buf_ioapply: no ops on block 0x1dc8/0x1dc8 ffff880052489000: 44 51 01 04 00 00 65 b8 00 00 00 00 00 00 00 00 DQ....e......... ffff880052489010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ffff880052489020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ffff880052489030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ CPU: 1 PID: 2376 Comm: mount Not tainted 3.16.0-rc2-dgc+ #306 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 ffff88006fe38000 ffff88004a0ffae8 ffffffff81cf1cca 0000000000000001 ffff88004a0ffb88 ffffffff814d50ca 000010004a0ffc70 0000000000000000 ffff88006be56dc4 0000000000000021 0000000000001dc8 ffff88007c773d80 Call Trace: [] dump_stack+0x45/0x56 [] _xfs_buf_ioapply+0x3ca/0x3d0 [] ? wake_up_state+0x20/0x20 [] ? xfs_bdstrat_cb+0x55/0xb0 [] xfs_buf_iorequest+0x6b/0xd0 [] xfs_bdstrat_cb+0x55/0xb0 [] __xfs_buf_delwri_submit+0x15b/0x220 [] ? xfs_buf_delwri_submit+0x30/0x90 [] xfs_buf_delwri_submit+0x30/0x90 [] xfs_qm_quotacheck+0x17d/0x3c0 [] xfs_qm_mount_quotas+0x151/0x1e0 [] xfs_mountfs+0x56c/0x7d0 [] xfs_fs_fill_super+0x2c2/0x340 [] mount_bdev+0x194/0x1d0 [] ? xfs_finish_flags+0x170/0x170 [] xfs_fs_mount+0x15/0x20 [] mount_fs+0x39/0x1b0 [] vfs_kern_mount+0x67/0x120 [] do_mount+0x23e/0xad0 [] ? __get_free_pages+0xe/0x50 [] ? copy_mount_options+0x36/0x150 [] SyS_mount+0x83/0xc0 [] tracesys+0xdd/0xe2 This was caused by dquot buffer readahead not attaching a verifier structure to the buffer when readahead was issued, resulting in the followup read of the buffer finding a valid buffer and so not attaching new verifiers to the buffer as part of the read. Also, when a verifier failure occurs, we then read the buffer without verifiers. Attach the verifiers manually after this read so that if the buffer is then written it will be verified that the corruption has been repaired. Further, when flushing a dquot we don't ask for a verifier when reading in the dquot buffer the dquot belongs to. Most of the time this isn't an issue because the buffer is still cached, but when it is not cached it will result in writing the dquot buffer without having the verfier attached. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner Signed-off-by: Greg Kroah-Hartman --- diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 044e97a33c8d..bac3e1635b7d 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -1104,7 +1104,8 @@ xfs_qm_dqflush( * Get the buffer containing the on-disk dquot */ error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, - mp->m_quotainfo->qi_dqchunklen, 0, &bp, NULL); + mp->m_quotainfo->qi_dqchunklen, 0, &bp, + &xfs_dquot_buf_ops); if (error) goto out_unlock; diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index b75c9bb6e71e..29d1ca567ed3 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -935,6 +935,12 @@ xfs_qm_dqiter_bufs( if (error) break; + /* + * A corrupt buffer might not have a verifier attached, so + * make sure we have the correct one attached before writeback + * occurs. + */ + bp->b_ops = &xfs_dquot_buf_ops; xfs_qm_reset_dqcounts(mp, bp, firstid, type); xfs_buf_delwri_queue(bp, buffer_list); xfs_buf_relse(bp); @@ -1018,7 +1024,7 @@ xfs_qm_dqiterate( xfs_buf_readahead(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, rablkno), mp->m_quotainfo->qi_dqchunklen, - NULL); + &xfs_dquot_buf_ops); rablkno++; } }