* [bug report] ntfs: update runlist handling and cluster allocator
@ 2026-04-28 6:43 Dan Carpenter
2026-04-28 12:53 ` Namjae Jeon
0 siblings, 1 reply; 2+ messages in thread
From: Dan Carpenter @ 2026-04-28 6:43 UTC (permalink / raw)
To: Namjae Jeon; +Cc: linux-fsdevel
Hello Namjae Jeon,
Commit 11ccc9107dc4 ("ntfs: update runlist handling and cluster
allocator") from Feb 13, 2026 (linux-next), leads to the following
Smatch static checker warning:
fs/ntfs/bitmap.c:268 __ntfs_bitmap_set_bits_in_run()
warn: passing a valid pointer to 'PTR_ERR'
fs/ntfs/bitmap.c
120 int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit,
121 const s64 count, const u8 value, const bool is_rollback)
122 {
123 s64 cnt = count;
124 pgoff_t index, end_index;
125 struct address_space *mapping;
126 struct folio *folio;
127 u8 *kaddr;
128 int pos, len;
129 u8 bit;
130 struct ntfs_inode *ni = NTFS_I(vi);
131 struct ntfs_volume *vol = ni->vol;
132
133 ntfs_debug("Entering for i_ino 0x%llx, start_bit 0x%llx, count 0x%llx, value %u.%s",
134 ni->mft_no, (unsigned long long)start_bit,
135 (unsigned long long)cnt, (unsigned int)value,
136 is_rollback ? " (rollback)" : "");
137
138 if (start_bit < 0 || cnt < 0 || value > 1)
139 return -EINVAL;
140
141 /*
142 * Calculate the indices for the pages containing the first and last
143 * bits, i.e. @start_bit and @start_bit + @cnt - 1, respectively.
144 */
145 index = start_bit >> (3 + PAGE_SHIFT);
146 end_index = (start_bit + cnt - 1) >> (3 + PAGE_SHIFT);
147
148 /* Get the page containing the first bit (@start_bit). */
149 mapping = vi->i_mapping;
150 folio = read_mapping_folio(mapping, index, NULL);
151 if (IS_ERR(folio)) {
152 if (!is_rollback)
153 ntfs_error(vi->i_sb,
154 "Failed to map first page (error %li), aborting.",
155 PTR_ERR(folio));
156 return PTR_ERR(folio);
157 }
158
159 folio_lock(folio);
160 kaddr = kmap_local_folio(folio, 0);
161
162 /* Set @pos to the position of the byte containing @start_bit. */
163 pos = (start_bit >> 3) & ~PAGE_MASK;
164
165 /* Calculate the position of @start_bit in the first byte. */
166 bit = start_bit & 7;
167
168 /* If the first byte is partial, modify the appropriate bits in it. */
169 if (bit) {
170 u8 *byte = kaddr + pos;
171
172 if (ni->mft_no == FILE_Bitmap)
173 ntfs_set_lcn_empty_bits(vol, index, value, min_t(s64, 8 - bit, cnt));
174 while ((bit & 7) && cnt) {
175 cnt--;
176 if (value)
177 *byte |= 1 << bit++;
178 else
179 *byte &= ~(1 << bit++);
180 }
181 /* If we are done, unmap the page and return success. */
182 if (!cnt)
183 goto done;
184
185 /* Update @pos to the new position. */
186 pos++;
187 }
188 /*
189 * Depending on @value, modify all remaining whole bytes in the page up
190 * to @cnt.
191 */
192 len = min_t(s64, cnt >> 3, PAGE_SIZE - pos);
193 memset(kaddr + pos, value ? 0xff : 0, len);
194 cnt -= len << 3;
195 if (ni->mft_no == FILE_Bitmap)
196 ntfs_set_lcn_empty_bits(vol, index, value, len << 3);
197
198 /* Update @len to point to the first not-done byte in the page. */
199 if (cnt < 8)
200 len += pos;
201
202 /* If we are not in the last page, deal with all subsequent pages. */
203 while (index < end_index) {
204 if (cnt <= 0)
205 goto rollback;
When we hit this goto then "folio" isn't set to an error pointer.
206
207 /* Update @index and get the next folio. */
208 folio_mark_dirty(folio);
209 folio_unlock(folio);
210 kunmap_local(kaddr);
211 folio_put(folio);
212 folio = read_mapping_folio(mapping, ++index, NULL);
213 if (IS_ERR(folio)) {
214 ntfs_error(vi->i_sb,
215 "Failed to map subsequent page (error %li), aborting.",
216 PTR_ERR(folio));
217 goto rollback;
218 }
219
220 folio_lock(folio);
221 kaddr = kmap_local_folio(folio, 0);
222 /*
223 * Depending on @value, modify all remaining whole bytes in the
224 * page up to @cnt.
225 */
226 len = min_t(s64, cnt >> 3, PAGE_SIZE);
227 memset(kaddr, value ? 0xff : 0, len);
228 cnt -= len << 3;
229 if (ni->mft_no == FILE_Bitmap)
230 ntfs_set_lcn_empty_bits(vol, index, value, len << 3);
231 }
232 /*
233 * The currently mapped page is the last one. If the last byte is
234 * partial, modify the appropriate bits in it. Note, @len is the
235 * position of the last byte inside the page.
236 */
237 if (cnt) {
238 u8 *byte;
239
240 WARN_ON(cnt > 7);
241
242 bit = cnt;
243 byte = kaddr + len;
244 if (ni->mft_no == FILE_Bitmap)
245 ntfs_set_lcn_empty_bits(vol, index, value, bit);
246 while (bit--) {
247 if (value)
248 *byte |= 1 << bit;
249 else
250 *byte &= ~(1 << bit);
251 }
252 }
253 done:
254 /* We are done. Unmap the folio and return success. */
255 folio_mark_dirty(folio);
256 folio_unlock(folio);
257 kunmap_local(kaddr);
258 folio_put(folio);
259 ntfs_debug("Done.");
260 return 0;
261 rollback:
262 /*
263 * Current state:
264 * - no pages are mapped
265 * - @count - @cnt is the number of bits that have been modified
266 */
267 if (is_rollback)
--> 268 return PTR_ERR(folio);
^^^^^^^^^^^^^^^
Warning here.
269 if (count != cnt)
270 pos = __ntfs_bitmap_set_bits_in_run(vi, start_bit, count - cnt,
271 value ? 0 : 1, true);
272 else
273 pos = 0;
274 if (!pos) {
275 /* Rollback was successful. */
276 ntfs_error(vi->i_sb,
277 "Failed to map subsequent page (error %li), aborting.",
278 PTR_ERR(folio));
279 } else {
280 /* Rollback failed. */
281 ntfs_error(vi->i_sb,
282 "Failed to map subsequent page (error %li) and rollback failed (error %i). Aborting and leaving inconsistent metadata. Unmount and run chkdsk.",
283 PTR_ERR(folio), pos);
284 NVolSetErrors(NTFS_SB(vi->i_sb));
285 }
286 return PTR_ERR(folio);
287 }
This email is a free service from the Smatch-CI project [smatch.sf.net].
regards,
dan carpenter
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [bug report] ntfs: update runlist handling and cluster allocator
2026-04-28 6:43 [bug report] ntfs: update runlist handling and cluster allocator Dan Carpenter
@ 2026-04-28 12:53 ` Namjae Jeon
0 siblings, 0 replies; 2+ messages in thread
From: Namjae Jeon @ 2026-04-28 12:53 UTC (permalink / raw)
To: Dan Carpenter; +Cc: linux-fsdevel
On Tue, Apr 28, 2026 at 3:43 PM Dan Carpenter <error27@gmail.com> wrote:
>
> Hello Namjae Jeon,
Hi Dan,
>
> Commit 11ccc9107dc4 ("ntfs: update runlist handling and cluster
> allocator") from Feb 13, 2026 (linux-next), leads to the following
> Smatch static checker warning:
>
> fs/ntfs/bitmap.c:268 __ntfs_bitmap_set_bits_in_run()
> warn: passing a valid pointer to 'PTR_ERR'
I will fix it. Thanks for the report!
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-04-28 12:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-28 6:43 [bug report] ntfs: update runlist handling and cluster allocator Dan Carpenter
2026-04-28 12:53 ` Namjae Jeon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox