Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'xfs-6.7-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fix from Chandan Babu:

- Validate quota records recovered from the log before writing them to
the disk.

* tag 'xfs-6.7-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: dquot recovery does not validate the recovered dquot
xfs: clean up dqblk extraction

+21 -5
+3 -2
fs/xfs/xfs_dquot.c
··· 562 562 struct xfs_dquot *dqp, 563 563 struct xfs_buf *bp) 564 564 { 565 - struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; 565 + struct xfs_dqblk *dqb = xfs_buf_offset(bp, dqp->q_bufoffset); 566 + struct xfs_disk_dquot *ddqp = &dqb->dd_diskdq; 566 567 567 568 /* 568 569 * Ensure that we got the type and ID we were looking for. ··· 1251 1250 } 1252 1251 1253 1252 /* Flush the incore dquot to the ondisk buffer. */ 1254 - dqblk = bp->b_addr + dqp->q_bufoffset; 1253 + dqblk = xfs_buf_offset(bp, dqp->q_bufoffset); 1255 1254 xfs_dquot_to_disk(&dqblk->dd_diskdq, dqp); 1256 1255 1257 1256 /*
+18 -3
fs/xfs/xfs_dquot_item_recover.c
··· 19 19 #include "xfs_log.h" 20 20 #include "xfs_log_priv.h" 21 21 #include "xfs_log_recover.h" 22 + #include "xfs_error.h" 22 23 23 24 STATIC void 24 25 xlog_recover_dquot_ra_pass2( ··· 66 65 { 67 66 struct xfs_mount *mp = log->l_mp; 68 67 struct xfs_buf *bp; 68 + struct xfs_dqblk *dqb; 69 69 struct xfs_disk_dquot *ddq, *recddq; 70 70 struct xfs_dq_logformat *dq_f; 71 71 xfs_failaddr_t fa; ··· 132 130 return error; 133 131 134 132 ASSERT(bp); 135 - ddq = xfs_buf_offset(bp, dq_f->qlf_boffset); 133 + dqb = xfs_buf_offset(bp, dq_f->qlf_boffset); 134 + ddq = &dqb->dd_diskdq; 136 135 137 136 /* 138 137 * If the dquot has an LSN in it, recover the dquot only if it's less 139 138 * than the lsn of the transaction we are replaying. 140 139 */ 141 140 if (xfs_has_crc(mp)) { 142 - struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddq; 143 141 xfs_lsn_t lsn = be64_to_cpu(dqb->dd_lsn); 144 142 145 143 if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) { ··· 149 147 150 148 memcpy(ddq, recddq, item->ri_buf[1].i_len); 151 149 if (xfs_has_crc(mp)) { 152 - xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk), 150 + xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk), 153 151 XFS_DQUOT_CRC_OFF); 152 + } 153 + 154 + /* Validate the recovered dquot. */ 155 + fa = xfs_dqblk_verify(log->l_mp, dqb, dq_f->qlf_id); 156 + if (fa) { 157 + XFS_CORRUPTION_ERROR("Bad dquot after recovery", 158 + XFS_ERRLEVEL_LOW, mp, dqb, 159 + sizeof(struct xfs_dqblk)); 160 + xfs_alert(mp, 161 + "Metadata corruption detected at %pS, dquot 0x%x", 162 + fa, dq_f->qlf_id); 163 + error = -EFSCORRUPTED; 164 + goto out_release; 154 165 } 155 166 156 167 ASSERT(dq_f->qlf_size == 2);