fs/ntfs3: Restyle comments to better align with kernel-doc
[linux-block.git] / fs / ntfs3 / record.c
CommitLineData
4342306f
KK
1// SPDX-License-Identifier: GPL-2.0
2/*
3 *
4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
5 *
6 */
7
8#include <linux/blkdev.h>
9#include <linux/buffer_head.h>
10#include <linux/fs.h>
11#include <linux/nls.h>
12
13#include "debug.h"
14#include "ntfs.h"
15#include "ntfs_fs.h"
16
17static inline int compare_attr(const struct ATTRIB *left, enum ATTR_TYPE type,
18 const __le16 *name, u8 name_len,
19 const u16 *upcase)
20{
e8b8e97f 21 /* First, compare the type codes. */
4342306f
KK
22 int diff = le32_to_cpu(left->type) - le32_to_cpu(type);
23
24 if (diff)
25 return diff;
26
e8b8e97f 27 /* They have the same type code, so we have to compare the names. */
4342306f
KK
28 return ntfs_cmp_names(attr_name(left), left->name_len, name, name_len,
29 upcase, true);
30}
31
32/*
33 * mi_new_attt_id
34 *
e8b8e97f 35 * Return: Unused attribute id that is less than mrec->next_attr_id.
4342306f
KK
36 */
37static __le16 mi_new_attt_id(struct mft_inode *mi)
38{
39 u16 free_id, max_id, t16;
40 struct MFT_REC *rec = mi->mrec;
41 struct ATTRIB *attr;
42 __le16 id;
43
44 id = rec->next_attr_id;
45 free_id = le16_to_cpu(id);
46 if (free_id < 0x7FFF) {
47 rec->next_attr_id = cpu_to_le16(free_id + 1);
48 return id;
49 }
50
e8b8e97f 51 /* One record can store up to 1024/24 ~= 42 attributes. */
4342306f
KK
52 free_id = 0;
53 max_id = 0;
54
55 attr = NULL;
56
57 for (;;) {
58 attr = mi_enum_attr(mi, attr);
59 if (!attr) {
60 rec->next_attr_id = cpu_to_le16(max_id + 1);
61 mi->dirty = true;
62 return cpu_to_le16(free_id);
63 }
64
65 t16 = le16_to_cpu(attr->id);
66 if (t16 == free_id) {
67 free_id += 1;
68 attr = NULL;
69 } else if (max_id < t16)
70 max_id = t16;
71 }
72}
73
74int mi_get(struct ntfs_sb_info *sbi, CLST rno, struct mft_inode **mi)
75{
76 int err;
195c52bd 77 struct mft_inode *m = kzalloc(sizeof(struct mft_inode), GFP_NOFS);
4342306f
KK
78
79 if (!m)
80 return -ENOMEM;
81
82 err = mi_init(m, sbi, rno);
83 if (err) {
195c52bd 84 kfree(m);
4342306f
KK
85 return err;
86 }
87
88 err = mi_read(m, false);
89 if (err) {
90 mi_put(m);
91 return err;
92 }
93
94 *mi = m;
95 return 0;
96}
97
98void mi_put(struct mft_inode *mi)
99{
100 mi_clear(mi);
195c52bd 101 kfree(mi);
4342306f
KK
102}
103
104int mi_init(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno)
105{
106 mi->sbi = sbi;
107 mi->rno = rno;
195c52bd 108 mi->mrec = kmalloc(sbi->record_size, GFP_NOFS);
4342306f
KK
109 if (!mi->mrec)
110 return -ENOMEM;
111
112 return 0;
113}
114
115/*
e8b8e97f 116 * mi_read - Read MFT data.
4342306f
KK
117 */
118int mi_read(struct mft_inode *mi, bool is_mft)
119{
120 int err;
121 struct MFT_REC *rec = mi->mrec;
122 struct ntfs_sb_info *sbi = mi->sbi;
123 u32 bpr = sbi->record_size;
124 u64 vbo = (u64)mi->rno << sbi->record_bits;
125 struct ntfs_inode *mft_ni = sbi->mft.ni;
126 struct runs_tree *run = mft_ni ? &mft_ni->file.run : NULL;
127 struct rw_semaphore *rw_lock = NULL;
128
129 if (is_mounted(sbi)) {
130 if (!is_mft) {
131 rw_lock = &mft_ni->file.run_lock;
132 down_read(rw_lock);
133 }
134 }
135
136 err = ntfs_read_bh(sbi, run, vbo, &rec->rhdr, bpr, &mi->nb);
137 if (rw_lock)
138 up_read(rw_lock);
139 if (!err)
140 goto ok;
141
142 if (err == -E_NTFS_FIXUP) {
143 mi->dirty = true;
144 goto ok;
145 }
146
147 if (err != -ENOENT)
148 goto out;
149
150 if (rw_lock) {
151 ni_lock(mft_ni);
152 down_write(rw_lock);
153 }
154 err = attr_load_runs_vcn(mft_ni, ATTR_DATA, NULL, 0, &mft_ni->file.run,
155 vbo >> sbi->cluster_bits);
156 if (rw_lock) {
157 up_write(rw_lock);
158 ni_unlock(mft_ni);
159 }
160 if (err)
161 goto out;
162
163 if (rw_lock)
164 down_read(rw_lock);
165 err = ntfs_read_bh(sbi, run, vbo, &rec->rhdr, bpr, &mi->nb);
166 if (rw_lock)
167 up_read(rw_lock);
168
169 if (err == -E_NTFS_FIXUP) {
170 mi->dirty = true;
171 goto ok;
172 }
173 if (err)
174 goto out;
175
176ok:
e8b8e97f 177 /* Check field 'total' only here. */
4342306f
KK
178 if (le32_to_cpu(rec->total) != bpr) {
179 err = -EINVAL;
180 goto out;
181 }
182
183 return 0;
184
185out:
186 return err;
187}
188
189struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
190{
191 const struct MFT_REC *rec = mi->mrec;
192 u32 used = le32_to_cpu(rec->used);
193 u32 t32, off, asize;
194 u16 t16;
195
196 if (!attr) {
197 u32 total = le32_to_cpu(rec->total);
198
199 off = le16_to_cpu(rec->attr_off);
200
201 if (used > total)
202 return NULL;
203
204 if (off >= used || off < MFTRECORD_FIXUP_OFFSET_1 ||
fa3cacf5 205 !IS_ALIGNED(off, 4)) {
4342306f
KK
206 return NULL;
207 }
208
e8b8e97f 209 /* Skip non-resident records. */
4342306f
KK
210 if (!is_rec_inuse(rec))
211 return NULL;
212
213 attr = Add2Ptr(rec, off);
214 } else {
e8b8e97f 215 /* Check if input attr inside record. */
4342306f
KK
216 off = PtrOffset(rec, attr);
217 if (off >= used)
218 return NULL;
219
220 asize = le32_to_cpu(attr->size);
221 if (asize < SIZEOF_RESIDENT) {
d3624466 222 /* Impossible 'cause we should not return such attribute. */
4342306f
KK
223 return NULL;
224 }
225
226 attr = Add2Ptr(attr, asize);
227 off += asize;
228 }
229
230 asize = le32_to_cpu(attr->size);
231
e8b8e97f 232 /* Can we use the first field (attr->type). */
4342306f 233 if (off + 8 > used) {
fa3cacf5 234 static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8);
4342306f
KK
235 return NULL;
236 }
237
238 if (attr->type == ATTR_END) {
e8b8e97f 239 /* End of enumeration. */
4342306f
KK
240 return NULL;
241 }
242
e8b8e97f 243 /* 0x100 is last known attribute for now. */
4342306f
KK
244 t32 = le32_to_cpu(attr->type);
245 if ((t32 & 0xf) || (t32 > 0x100))
246 return NULL;
247
e8b8e97f 248 /* Check boundary. */
4342306f
KK
249 if (off + asize > used)
250 return NULL;
251
e8b8e97f 252 /* Check size of attribute. */
4342306f
KK
253 if (!attr->non_res) {
254 if (asize < SIZEOF_RESIDENT)
255 return NULL;
256
257 t16 = le16_to_cpu(attr->res.data_off);
258
259 if (t16 > asize)
260 return NULL;
261
262 t32 = le32_to_cpu(attr->res.data_size);
263 if (t16 + t32 > asize)
264 return NULL;
265
266 return attr;
267 }
268
e8b8e97f 269 /* Check some nonresident fields. */
4342306f
KK
270 if (attr->name_len &&
271 le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len >
272 le16_to_cpu(attr->nres.run_off)) {
273 return NULL;
274 }
275
276 if (attr->nres.svcn || !is_attr_ext(attr)) {
277 if (asize + 8 < SIZEOF_NONRESIDENT)
278 return NULL;
279
280 if (attr->nres.c_unit)
281 return NULL;
282 } else if (asize + 8 < SIZEOF_NONRESIDENT_EX)
283 return NULL;
284
285 return attr;
286}
287
288/*
e8b8e97f 289 * mi_find_attr - Find the attribute by type and name and id.
4342306f
KK
290 */
291struct ATTRIB *mi_find_attr(struct mft_inode *mi, struct ATTRIB *attr,
292 enum ATTR_TYPE type, const __le16 *name,
293 size_t name_len, const __le16 *id)
294{
295 u32 type_in = le32_to_cpu(type);
296 u32 atype;
297
298next_attr:
299 attr = mi_enum_attr(mi, attr);
300 if (!attr)
301 return NULL;
302
303 atype = le32_to_cpu(attr->type);
304 if (atype > type_in)
305 return NULL;
306
307 if (atype < type_in)
308 goto next_attr;
309
310 if (attr->name_len != name_len)
311 goto next_attr;
312
313 if (name_len && memcmp(attr_name(attr), name, name_len * sizeof(short)))
314 goto next_attr;
315
316 if (id && *id != attr->id)
317 goto next_attr;
318
319 return attr;
320}
321
322int mi_write(struct mft_inode *mi, int wait)
323{
324 struct MFT_REC *rec;
325 int err;
326 struct ntfs_sb_info *sbi;
327
328 if (!mi->dirty)
329 return 0;
330
331 sbi = mi->sbi;
332 rec = mi->mrec;
333
334 err = ntfs_write_bh(sbi, &rec->rhdr, &mi->nb, wait);
335 if (err)
336 return err;
337
338 if (mi->rno < sbi->mft.recs_mirr)
339 sbi->flags |= NTFS_FLAGS_MFTMIRR;
340
341 mi->dirty = false;
342
343 return 0;
344}
345
346int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno,
347 __le16 flags, bool is_mft)
348{
349 int err;
350 u16 seq = 1;
351 struct MFT_REC *rec;
352 u64 vbo = (u64)rno << sbi->record_bits;
353
354 err = mi_init(mi, sbi, rno);
355 if (err)
356 return err;
357
358 rec = mi->mrec;
359
360 if (rno == MFT_REC_MFT) {
361 ;
362 } else if (rno < MFT_REC_FREE) {
363 seq = rno;
364 } else if (rno >= sbi->mft.used) {
365 ;
366 } else if (mi_read(mi, is_mft)) {
367 ;
368 } else if (rec->rhdr.sign == NTFS_FILE_SIGNATURE) {
e8b8e97f 369 /* Record is reused. Update its sequence number. */
4342306f
KK
370 seq = le16_to_cpu(rec->seq) + 1;
371 if (!seq)
372 seq = 1;
373 }
374
375 memcpy(rec, sbi->new_rec, sbi->record_size);
376
377 rec->seq = cpu_to_le16(seq);
378 rec->flags = RECORD_FLAG_IN_USE | flags;
379
380 mi->dirty = true;
381
382 if (!mi->nb.nbufs) {
383 struct ntfs_inode *ni = sbi->mft.ni;
384 bool lock = false;
385
386 if (is_mounted(sbi) && !is_mft) {
387 down_read(&ni->file.run_lock);
388 lock = true;
389 }
390
391 err = ntfs_get_bh(sbi, &ni->file.run, vbo, sbi->record_size,
392 &mi->nb);
393 if (lock)
394 up_read(&ni->file.run_lock);
395 }
396
397 return err;
398}
399
400/*
e8b8e97f 401 * mi_mark_free - Mark record as unused and marks it as free in bitmap.
4342306f
KK
402 */
403void mi_mark_free(struct mft_inode *mi)
404{
405 CLST rno = mi->rno;
406 struct ntfs_sb_info *sbi = mi->sbi;
407
408 if (rno >= MFT_REC_RESERVED && rno < MFT_REC_FREE) {
409 ntfs_clear_mft_tail(sbi, rno, rno + 1);
410 mi->dirty = false;
411 return;
412 }
413
414 if (mi->mrec) {
415 clear_rec_inuse(mi->mrec);
416 mi->dirty = true;
417 mi_write(mi, 0);
418 }
419 ntfs_mark_rec_free(sbi, rno);
420}
421
422/*
e8b8e97f 423 * mi_insert_attr - Reserve space for new attribute.
4342306f 424 *
e8b8e97f 425 * Return: Not full constructed attribute or NULL if not possible to create.
4342306f
KK
426 */
427struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type,
428 const __le16 *name, u8 name_len, u32 asize,
429 u16 name_off)
430{
431 size_t tail;
432 struct ATTRIB *attr;
433 __le16 id;
434 struct MFT_REC *rec = mi->mrec;
435 struct ntfs_sb_info *sbi = mi->sbi;
436 u32 used = le32_to_cpu(rec->used);
437 const u16 *upcase = sbi->upcase;
438 int diff;
439
440 /* Can we insert mi attribute? */
441 if (used + asize > mi->sbi->record_size)
442 return NULL;
443
444 /*
445 * Scan through the list of attributes to find the point
446 * at which we should insert it.
447 */
448 attr = NULL;
449 while ((attr = mi_enum_attr(mi, attr))) {
450 diff = compare_attr(attr, type, name, name_len, upcase);
451 if (diff > 0)
452 break;
453 if (diff < 0)
454 continue;
455
456 if (!is_attr_indexed(attr))
457 return NULL;
458 break;
459 }
460
461 if (!attr) {
e8b8e97f 462 tail = 8; /* Not used, just to suppress warning. */
4342306f
KK
463 attr = Add2Ptr(rec, used - 8);
464 } else {
465 tail = used - PtrOffset(rec, attr);
466 }
467
468 id = mi_new_attt_id(mi);
469
470 memmove(Add2Ptr(attr, asize), attr, tail);
471 memset(attr, 0, asize);
472
473 attr->type = type;
474 attr->size = cpu_to_le32(asize);
475 attr->name_len = name_len;
476 attr->name_off = cpu_to_le16(name_off);
477 attr->id = id;
478
479 memmove(Add2Ptr(attr, name_off), name, name_len * sizeof(short));
480 rec->used = cpu_to_le32(used + asize);
481
482 mi->dirty = true;
483
484 return attr;
485}
486
487/*
e8b8e97f 488 * mi_remove_attr - Remove the attribute from record.
4342306f 489 *
e8b8e97f 490 * NOTE: The source attr will point to next attribute.
4342306f 491 */
78ab59fe
KK
492bool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi,
493 struct ATTRIB *attr)
4342306f
KK
494{
495 struct MFT_REC *rec = mi->mrec;
496 u32 aoff = PtrOffset(rec, attr);
497 u32 used = le32_to_cpu(rec->used);
498 u32 asize = le32_to_cpu(attr->size);
499
500 if (aoff + asize > used)
501 return false;
502
78ab59fe
KK
503 if (ni && is_attr_indexed(attr)) {
504 le16_add_cpu(&ni->mi.mrec->hard_links, -1);
505 ni->mi.dirty = true;
506 }
507
4342306f
KK
508 used -= asize;
509 memmove(attr, Add2Ptr(attr, asize), used - aoff);
510 rec->used = cpu_to_le32(used);
511 mi->dirty = true;
512
513 return true;
514}
515
516/* bytes = "new attribute size" - "old attribute size" */
517bool mi_resize_attr(struct mft_inode *mi, struct ATTRIB *attr, int bytes)
518{
519 struct MFT_REC *rec = mi->mrec;
520 u32 aoff = PtrOffset(rec, attr);
521 u32 total, used = le32_to_cpu(rec->used);
522 u32 nsize, asize = le32_to_cpu(attr->size);
523 u32 rsize = le32_to_cpu(attr->res.data_size);
524 int tail = (int)(used - aoff - asize);
525 int dsize;
526 char *next;
527
528 if (tail < 0 || aoff >= used)
529 return false;
530
531 if (!bytes)
532 return true;
533
534 total = le32_to_cpu(rec->total);
535 next = Add2Ptr(attr, asize);
536
537 if (bytes > 0) {
fa3cacf5 538 dsize = ALIGN(bytes, 8);
4342306f
KK
539 if (used + dsize > total)
540 return false;
541 nsize = asize + dsize;
e8b8e97f 542 /* Move tail */
4342306f
KK
543 memmove(next + dsize, next, tail);
544 memset(next, 0, dsize);
545 used += dsize;
546 rsize += dsize;
547 } else {
fa3cacf5 548 dsize = ALIGN(-bytes, 8);
4342306f
KK
549 if (dsize > asize)
550 return false;
551 nsize = asize - dsize;
552 memmove(next - dsize, next, tail);
553 used -= dsize;
554 rsize -= dsize;
555 }
556
557 rec->used = cpu_to_le32(used);
558 attr->size = cpu_to_le32(nsize);
559 if (!attr->non_res)
560 attr->res.data_size = cpu_to_le32(rsize);
561 mi->dirty = true;
562
563 return true;
564}
565
566int mi_pack_runs(struct mft_inode *mi, struct ATTRIB *attr,
567 struct runs_tree *run, CLST len)
568{
569 int err = 0;
570 struct ntfs_sb_info *sbi = mi->sbi;
571 u32 new_run_size;
572 CLST plen;
573 struct MFT_REC *rec = mi->mrec;
574 CLST svcn = le64_to_cpu(attr->nres.svcn);
575 u32 used = le32_to_cpu(rec->used);
576 u32 aoff = PtrOffset(rec, attr);
577 u32 asize = le32_to_cpu(attr->size);
578 char *next = Add2Ptr(attr, asize);
579 u16 run_off = le16_to_cpu(attr->nres.run_off);
580 u32 run_size = asize - run_off;
581 u32 tail = used - aoff - asize;
582 u32 dsize = sbi->record_size - used;
583
e8b8e97f 584 /* Make a maximum gap in current record. */
4342306f
KK
585 memmove(next + dsize, next, tail);
586
e8b8e97f 587 /* Pack as much as possible. */
4342306f
KK
588 err = run_pack(run, svcn, len, Add2Ptr(attr, run_off), run_size + dsize,
589 &plen);
590 if (err < 0) {
591 memmove(next, next + dsize, tail);
592 return err;
593 }
594
fa3cacf5 595 new_run_size = ALIGN(err, 8);
4342306f
KK
596
597 memmove(next + new_run_size - run_size, next + dsize, tail);
598
599 attr->size = cpu_to_le32(asize + new_run_size - run_size);
600 attr->nres.evcn = cpu_to_le64(svcn + plen - 1);
601 rec->used = cpu_to_le32(used + new_run_size - run_size);
602 mi->dirty = true;
603
604 return 0;
605}