* [bug report] xfs: don't swallow dquot recovery verification errors
@ 2026-08-12 8:21 Dan Carpenter
0 siblings, 0 replies; only message in thread
From: Dan Carpenter @ 2026-08-12 8:21 UTC (permalink / raw)
To: Long Li; +Cc: linux-xfs
Hello Long Li,
Commit e2b4a856085e ("xfs: don't swallow dquot recovery verification
errors") from Jul 27, 2026 (linux-next), leads to the following
Smatch static checker warning:
fs/xfs/xfs_dquot_item_recover.c:146 xlog_recover_dquot_commit_pass2()
warn: missing error code here? 'xfs_dquot_verify()' failed. 'error' = '0'
fs/xfs/xfs_dquot_item_recover.c
60 STATIC int
61 xlog_recover_dquot_commit_pass2(
62 struct xlog *log,
63 struct list_head *buffer_list,
64 struct xlog_recover_item *item,
65 xfs_lsn_t current_lsn)
66 {
67 struct xfs_mount *mp = log->l_mp;
68 struct xfs_buf *bp;
69 struct xfs_dqblk *dqb;
70 struct xfs_disk_dquot *ddq, *recddq;
71 struct xfs_dq_logformat *dq_f;
72 xfs_failaddr_t fa;
73 int error;
74 uint type;
75
76 /*
77 * Filesystems are required to send in quota flags at mount time.
78 */
79 if (mp->m_qflags == 0)
80 return 0;
81
82 recddq = item->ri_buf[1].iov_base;
83 if (recddq == NULL) {
84 xfs_alert(log->l_mp, "NULL dquot in %s.", __func__);
85 return -EFSCORRUPTED;
86 }
87 if (item->ri_buf[1].iov_len < sizeof(struct xfs_disk_dquot)) {
88 xfs_alert(log->l_mp, "dquot too small (%zd) in %s.",
89 item->ri_buf[1].iov_len, __func__);
90 return -EFSCORRUPTED;
91 }
92
93 /*
94 * This type of quotas was turned off, so ignore this record.
95 */
96 type = recddq->d_type & XFS_DQTYPE_REC_MASK;
97 ASSERT(type);
98 if (log->l_quotaoffs_flag & type)
99 return 0;
100
101 /*
102 * At this point we know that quota was _not_ turned off.
103 * Since the mount flags are not indicating to us otherwise, this
104 * must mean that quota is on, and the dquot needs to be replayed.
105 * Remember that we may not have fully recovered the superblock yet,
106 * so we can't do the usual trick of looking at the SB quota bits.
107 *
108 * The other possibility, of course, is that the quota subsystem was
109 * removed since the last mount - ENOSYS.
110 */
111 dq_f = item->ri_buf[0].iov_base;
112 ASSERT(dq_f);
113 fa = xfs_dquot_verify(mp, recddq, dq_f->qlf_id);
114 if (fa) {
115 xfs_alert(mp, "corrupt dquot ID 0x%x in log at %pS",
116 dq_f->qlf_id, fa);
117 return -EFSCORRUPTED;
118 }
119 ASSERT(dq_f->qlf_len == 1);
120
121 /*
122 * At this point we are assuming that the dquots have been allocated
123 * and hence the buffer has valid dquots stamped in it. It should,
124 * therefore, pass verifier validation. If the dquot is bad, then the
125 * we'll return an error here, so we don't need to specifically check
126 * the dquot in the buffer after the verifier has run.
127 */
128 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dq_f->qlf_blkno,
129 XFS_FSB_TO_BB(mp, dq_f->qlf_len), 0, &bp,
130 &xfs_dquot_buf_ops);
131 if (error)
132 return error;
133
134 ASSERT(bp);
135 dqb = xfs_buf_offset(bp, dq_f->qlf_boffset);
136 ddq = &dqb->dd_diskdq;
137
138 /*
139 * If the dquot has an LSN in it, recover the dquot only if it's less
140 * than the lsn of the transaction we are replaying.
141 */
142 if (xfs_has_crc(mp)) {
143 xfs_lsn_t lsn = be64_to_cpu(dqb->dd_lsn);
144
145 if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) >= 0) {
--> 146 goto out_release;
Originally this function always returned zero, but now it returns
error codes. Should this be an error path?
147 }
148 }
149
150 memcpy(ddq, recddq, item->ri_buf[1].iov_len);
151 if (xfs_has_crc(mp)) {
152 xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk),
153 XFS_DQUOT_CRC_OFF);
154 }
155
156 /* Validate the recovered dquot. */
157 fa = xfs_dqblk_verify(log->l_mp, dqb, dq_f->qlf_id);
158 if (fa) {
159 XFS_CORRUPTION_ERROR("Bad dquot after recovery",
160 XFS_ERRLEVEL_LOW, mp, dqb,
161 sizeof(struct xfs_dqblk));
162 xfs_alert(mp,
163 "Metadata corruption detected at %pS, dquot 0x%x",
164 fa, dq_f->qlf_id);
165 error = -EFSCORRUPTED;
166 goto out_release;
167 }
168
169 ASSERT(dq_f->qlf_size == 2);
170 ASSERT(bp->b_mount == mp);
171 xfs_buf_delwri_queue(bp, buffer_list);
172
173 out_release:
174 xfs_buf_relse(bp);
175 return error;
176 }
This email is a free service from the Smatch-CI project [smatch.sf.net].
regards,
dan carpenter
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-12 8:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12 8:21 [bug report] xfs: don't swallow dquot recovery verification errors Dan Carpenter
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.