1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#ifdef NTFS_RW
23
24#include <linux/types.h>
25#include <linux/fs.h>
26#include <linux/highmem.h>
27#include <linux/buffer_head.h>
28#include <linux/bitops.h>
29#include <linux/log2.h>
30
31#include "attrib.h"
32#include "aops.h"
33#include "debug.h"
34#include "logfile.h"
35#include "malloc.h"
36#include "volume.h"
37#include "ntfs.h"
38
39
40
41
42
43
44
45
46
47
48
49
50
51static bool ntfs_check_restart_page_header(struct inode *vi,
52 RESTART_PAGE_HEADER *rp, s64 pos)
53{
54 u32 logfile_system_page_size, logfile_log_page_size;
55 u16 ra_ofs, usa_count, usa_ofs, usa_end = 0;
56 bool have_usa = true;
57
58 ntfs_debug("Entering.");
59
60
61
62
63 logfile_system_page_size = le32_to_cpu(rp->system_page_size);
64 logfile_log_page_size = le32_to_cpu(rp->log_page_size);
65 if (logfile_system_page_size < NTFS_BLOCK_SIZE ||
66 logfile_log_page_size < NTFS_BLOCK_SIZE ||
67 logfile_system_page_size &
68 (logfile_system_page_size - 1) ||
69 !is_power_of_2(logfile_log_page_size)) {
70 ntfs_error(vi->i_sb, "$LogFile uses unsupported page size.");
71 return false;
72 }
73
74
75
76
77 if (pos && pos != logfile_system_page_size) {
78 ntfs_error(vi->i_sb, "Found restart area in incorrect "
79 "position in $LogFile.");
80 return false;
81 }
82
83 if (sle16_to_cpu(rp->major_ver) != 1 ||
84 sle16_to_cpu(rp->minor_ver) != 1) {
85 ntfs_error(vi->i_sb, "$LogFile version %i.%i is not "
86 "supported. (This driver supports version "
87 "1.1 only.)", (int)sle16_to_cpu(rp->major_ver),
88 (int)sle16_to_cpu(rp->minor_ver));
89 return false;
90 }
91
92
93
94
95 if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) {
96 have_usa = false;
97 goto skip_usa_checks;
98 }
99
100 usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS);
101 if (usa_count != le16_to_cpu(rp->usa_count)) {
102 ntfs_error(vi->i_sb, "$LogFile restart page specifies "
103 "inconsistent update sequence array count.");
104 return false;
105 }
106
107 usa_ofs = le16_to_cpu(rp->usa_ofs);
108 usa_end = usa_ofs + usa_count * sizeof(u16);
109 if (usa_ofs < sizeof(RESTART_PAGE_HEADER) ||
110 usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) {
111 ntfs_error(vi->i_sb, "$LogFile restart page specifies "
112 "inconsistent update sequence array offset.");
113 return false;
114 }
115skip_usa_checks:
116
117
118
119
120
121
122 ra_ofs = le16_to_cpu(rp->restart_area_offset);
123 if (ra_ofs & 7 || (have_usa ? ra_ofs < usa_end :
124 ra_ofs < sizeof(RESTART_PAGE_HEADER)) ||
125 ra_ofs > logfile_system_page_size) {
126 ntfs_error(vi->i_sb, "$LogFile restart page specifies "
127 "inconsistent restart area offset.");
128 return false;
129 }
130
131
132
133
134 if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) {
135 ntfs_error(vi->i_sb, "$LogFile restart page is not modified "
136 "by chkdsk but a chkdsk LSN is specified.");
137 return false;
138 }
139 ntfs_debug("Done.");
140 return true;
141}
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157static bool ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp)
158{
159 u64 file_size;
160 RESTART_AREA *ra;
161 u16 ra_ofs, ra_len, ca_ofs;
162 u8 fs_bits;
163
164 ntfs_debug("Entering.");
165 ra_ofs = le16_to_cpu(rp->restart_area_offset);
166 ra = (RESTART_AREA*)((u8*)rp + ra_ofs);
167
168
169
170
171
172 if (ra_ofs + offsetof(RESTART_AREA, file_size) >
173 NTFS_BLOCK_SIZE - sizeof(u16)) {
174 ntfs_error(vi->i_sb, "$LogFile restart area specifies "
175 "inconsistent file offset.");
176 return false;
177 }
178
179
180
181
182
183
184
185 ca_ofs = le16_to_cpu(ra->client_array_offset);
186 if (((ca_ofs + 7) & ~7) != ca_ofs ||
187 ra_ofs + ca_ofs > NTFS_BLOCK_SIZE - sizeof(u16)) {
188 ntfs_error(vi->i_sb, "$LogFile restart area specifies "
189 "inconsistent client array offset.");
190 return false;
191 }
192
193
194
195
196
197 ra_len = ca_ofs + le16_to_cpu(ra->log_clients) *
198 sizeof(LOG_CLIENT_RECORD);
199 if (ra_ofs + ra_len > le32_to_cpu(rp->system_page_size) ||
200 ra_ofs + le16_to_cpu(ra->restart_area_length) >
201 le32_to_cpu(rp->system_page_size) ||
202 ra_len > le16_to_cpu(ra->restart_area_length)) {
203 ntfs_error(vi->i_sb, "$LogFile restart area is out of bounds "
204 "of the system page size specified by the "
205 "restart page header and/or the specified "
206 "restart area length is inconsistent.");
207 return false;
208 }
209
210
211
212
213
214 if ((ra->client_free_list != LOGFILE_NO_CLIENT &&
215 le16_to_cpu(ra->client_free_list) >=
216 le16_to_cpu(ra->log_clients)) ||
217 (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
218 le16_to_cpu(ra->client_in_use_list) >=
219 le16_to_cpu(ra->log_clients))) {
220 ntfs_error(vi->i_sb, "$LogFile restart area specifies "
221 "overflowing client free and/or in use lists.");
222 return false;
223 }
224
225
226
227
228 file_size = (u64)sle64_to_cpu(ra->file_size);
229 fs_bits = 0;
230 while (file_size) {
231 file_size >>= 1;
232 fs_bits++;
233 }
234 if (le32_to_cpu(ra->seq_number_bits) != 67 - fs_bits) {
235 ntfs_error(vi->i_sb, "$LogFile restart area specifies "
236 "inconsistent sequence number bits.");
237 return false;
238 }
239
240 if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) !=
241 le16_to_cpu(ra->log_record_header_length)) {
242 ntfs_error(vi->i_sb, "$LogFile restart area specifies "
243 "inconsistent log record header length.");
244 return false;
245 }
246
247 if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) !=
248 le16_to_cpu(ra->log_page_data_offset)) {
249 ntfs_error(vi->i_sb, "$LogFile restart area specifies "
250 "inconsistent log page data offset.");
251 return false;
252 }
253 ntfs_debug("Done.");
254 return true;
255}
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272static bool ntfs_check_log_client_array(struct inode *vi,
273 RESTART_PAGE_HEADER *rp)
274{
275 RESTART_AREA *ra;
276 LOG_CLIENT_RECORD *ca, *cr;
277 u16 nr_clients, idx;
278 bool in_free_list, idx_is_first;
279
280 ntfs_debug("Entering.");
281 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
282 ca = (LOG_CLIENT_RECORD*)((u8*)ra +
283 le16_to_cpu(ra->client_array_offset));
284
285
286
287
288
289
290
291
292 nr_clients = le16_to_cpu(ra->log_clients);
293 idx = le16_to_cpu(ra->client_free_list);
294 in_free_list = true;
295check_list:
296 for (idx_is_first = true; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--,
297 idx = le16_to_cpu(cr->next_client)) {
298 if (!nr_clients || idx >= le16_to_cpu(ra->log_clients))
299 goto err_out;
300
301 cr = ca + idx;
302
303 if (idx_is_first) {
304 if (cr->prev_client != LOGFILE_NO_CLIENT)
305 goto err_out;
306 idx_is_first = false;
307 }
308 }
309
310 if (in_free_list) {
311 in_free_list = false;
312 idx = le16_to_cpu(ra->client_in_use_list);
313 goto check_list;
314 }
315 ntfs_debug("Done.");
316 return true;
317err_out:
318 ntfs_error(vi->i_sb, "$LogFile log client array is corrupt.");
319 return false;
320}
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349static int ntfs_check_and_load_restart_page(struct inode *vi,
350 RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp,
351 LSN *lsn)
352{
353 RESTART_AREA *ra;
354 RESTART_PAGE_HEADER *trp;
355 int size, err;
356
357 ntfs_debug("Entering.");
358
359 if (!ntfs_check_restart_page_header(vi, rp, pos)) {
360
361 return -EINVAL;
362 }
363
364 if (!ntfs_check_restart_area(vi, rp)) {
365
366 return -EINVAL;
367 }
368 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
369
370
371
372
373 trp = ntfs_malloc_nofs(le32_to_cpu(rp->system_page_size));
374 if (!trp) {
375 ntfs_error(vi->i_sb, "Failed to allocate memory for $LogFile "
376 "restart page buffer.");
377 return -ENOMEM;
378 }
379
380
381
382
383
384 size = PAGE_SIZE - (pos & ~PAGE_MASK);
385 if (size >= le32_to_cpu(rp->system_page_size)) {
386 memcpy(trp, rp, le32_to_cpu(rp->system_page_size));
387 } else {
388 pgoff_t idx;
389 struct page *page;
390 int have_read, to_read;
391
392
393 memcpy(trp, rp, size);
394
395 have_read = size;
396 to_read = le32_to_cpu(rp->system_page_size) - size;
397 idx = (pos + size) >> PAGE_SHIFT;
398 BUG_ON((pos + size) & ~PAGE_MASK);
399 do {
400 page = ntfs_map_page(vi->i_mapping, idx);
401 if (IS_ERR(page)) {
402 ntfs_error(vi->i_sb, "Error mapping $LogFile "
403 "page (index %lu).", idx);
404 err = PTR_ERR(page);
405 if (err != -EIO && err != -ENOMEM)
406 err = -EIO;
407 goto err_out;
408 }
409 size = min_t(int, to_read, PAGE_SIZE);
410 memcpy((u8*)trp + have_read, page_address(page), size);
411 ntfs_unmap_page(page);
412 have_read += size;
413 to_read -= size;
414 idx++;
415 } while (to_read > 0);
416 }
417
418
419
420
421 if ((!ntfs_is_chkd_record(trp->magic) || le16_to_cpu(trp->usa_count))
422 && post_read_mst_fixup((NTFS_RECORD*)trp,
423 le32_to_cpu(rp->system_page_size))) {
424
425
426
427
428
429 if (le16_to_cpu(rp->restart_area_offset) +
430 le16_to_cpu(ra->restart_area_length) >
431 NTFS_BLOCK_SIZE - sizeof(u16)) {
432 ntfs_error(vi->i_sb, "Multi sector transfer error "
433 "detected in $LogFile restart page.");
434 err = -EINVAL;
435 goto err_out;
436 }
437 }
438
439
440
441
442
443 err = 0;
444 if (ntfs_is_rstr_record(rp->magic) &&
445 ra->client_in_use_list != LOGFILE_NO_CLIENT) {
446 if (!ntfs_check_log_client_array(vi, trp)) {
447 err = -EINVAL;
448 goto err_out;
449 }
450 }
451 if (lsn) {
452 if (ntfs_is_rstr_record(rp->magic))
453 *lsn = sle64_to_cpu(ra->current_lsn);
454 else
455 *lsn = sle64_to_cpu(rp->chkdsk_lsn);
456 }
457 ntfs_debug("Done.");
458 if (wrp)
459 *wrp = trp;
460 else {
461err_out:
462 ntfs_free(trp);
463 }
464 return err;
465}
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484bool ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
485{
486 s64 size, pos;
487 LSN rstr1_lsn, rstr2_lsn;
488 ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
489 struct address_space *mapping = log_vi->i_mapping;
490 struct page *page = NULL;
491 u8 *kaddr = NULL;
492 RESTART_PAGE_HEADER *rstr1_ph = NULL;
493 RESTART_PAGE_HEADER *rstr2_ph = NULL;
494 int log_page_size, log_page_mask, err;
495 bool logfile_is_empty = true;
496 u8 log_page_bits;
497
498 ntfs_debug("Entering.");
499
500 if (NVolLogFileEmpty(vol))
501 goto is_empty;
502 size = i_size_read(log_vi);
503
504 if (size > MaxLogFileSize)
505 size = MaxLogFileSize;
506
507
508
509
510
511
512 if (PAGE_SIZE >= DefaultLogPageSize && PAGE_SIZE <=
513 DefaultLogPageSize * 2)
514 log_page_size = DefaultLogPageSize;
515 else
516 log_page_size = PAGE_SIZE;
517 log_page_mask = log_page_size - 1;
518
519
520
521
522 log_page_bits = ntfs_ffs(log_page_size) - 1;
523 size &= ~(s64)(log_page_size - 1);
524
525
526
527
528 if (size < log_page_size * 2 || (size - log_page_size * 2) >>
529 log_page_bits < MinLogRecordPages) {
530 ntfs_error(vol->sb, "$LogFile is too small.");
531 return false;
532 }
533
534
535
536
537
538
539
540
541 for (pos = 0; pos < size; pos <<= 1) {
542 pgoff_t idx = pos >> PAGE_SHIFT;
543 if (!page || page->index != idx) {
544 if (page)
545 ntfs_unmap_page(page);
546 page = ntfs_map_page(mapping, idx);
547 if (IS_ERR(page)) {
548 ntfs_error(vol->sb, "Error mapping $LogFile "
549 "page (index %lu).", idx);
550 goto err_out;
551 }
552 }
553 kaddr = (u8*)page_address(page) + (pos & ~PAGE_MASK);
554
555
556
557
558
559 if (!ntfs_is_empty_recordp((le32*)kaddr))
560 logfile_is_empty = false;
561 else if (!logfile_is_empty)
562 break;
563
564
565
566
567 if (ntfs_is_rcrd_recordp((le32*)kaddr))
568 break;
569
570 if (!ntfs_is_rstr_recordp((le32*)kaddr) &&
571 !ntfs_is_chkd_recordp((le32*)kaddr)) {
572 if (!pos)
573 pos = NTFS_BLOCK_SIZE >> 1;
574 continue;
575 }
576
577
578
579
580
581 err = ntfs_check_and_load_restart_page(log_vi,
582 (RESTART_PAGE_HEADER*)kaddr, pos,
583 !rstr1_ph ? &rstr1_ph : &rstr2_ph,
584 !rstr1_ph ? &rstr1_lsn : &rstr2_lsn);
585 if (!err) {
586
587
588
589
590 if (!pos) {
591 pos = NTFS_BLOCK_SIZE >> 1;
592 continue;
593 }
594
595
596
597
598 break;
599 }
600
601
602
603
604
605 if (err != -EINVAL) {
606 ntfs_unmap_page(page);
607 goto err_out;
608 }
609
610 if (!pos)
611 pos = NTFS_BLOCK_SIZE >> 1;
612 }
613 if (page)
614 ntfs_unmap_page(page);
615 if (logfile_is_empty) {
616 NVolSetLogFileEmpty(vol);
617is_empty:
618 ntfs_debug("Done. ($LogFile is empty.)");
619 return true;
620 }
621 if (!rstr1_ph) {
622 BUG_ON(rstr2_ph);
623 ntfs_error(vol->sb, "Did not find any restart pages in "
624 "$LogFile and it was not empty.");
625 return false;
626 }
627
628 if (rstr2_ph) {
629
630
631
632
633 if (rstr2_lsn > rstr1_lsn) {
634 ntfs_debug("Using second restart page as it is more "
635 "recent.");
636 ntfs_free(rstr1_ph);
637 rstr1_ph = rstr2_ph;
638
639 } else {
640 ntfs_debug("Using first restart page as it is more "
641 "recent.");
642 ntfs_free(rstr2_ph);
643 }
644 rstr2_ph = NULL;
645 }
646
647 if (rp)
648 *rp = rstr1_ph;
649 else
650 ntfs_free(rstr1_ph);
651 ntfs_debug("Done.");
652 return true;
653err_out:
654 if (rstr1_ph)
655 ntfs_free(rstr1_ph);
656 return false;
657}
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679bool ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
680{
681 ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
682 RESTART_AREA *ra;
683
684 ntfs_debug("Entering.");
685
686 if (NVolLogFileEmpty(vol)) {
687 ntfs_debug("Done. ($LogFile is empty.)");
688 return true;
689 }
690 BUG_ON(!rp);
691 if (!ntfs_is_rstr_record(rp->magic) &&
692 !ntfs_is_chkd_record(rp->magic)) {
693 ntfs_error(vol->sb, "Restart page buffer is invalid. This is "
694 "probably a bug in that the $LogFile should "
695 "have been consistency checked before calling "
696 "this function.");
697 return false;
698 }
699 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
700
701
702
703
704
705 if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
706 !(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
707 ntfs_debug("Done. $LogFile indicates a dirty shutdown.");
708 return false;
709 }
710
711 ntfs_debug("Done. $LogFile indicates a clean shutdown.");
712 return true;
713}
714
715
716
717
718
719
720
721
722
723
724
725
726bool ntfs_empty_logfile(struct inode *log_vi)
727{
728 VCN vcn, end_vcn;
729 ntfs_inode *log_ni = NTFS_I(log_vi);
730 ntfs_volume *vol = log_ni->vol;
731 struct super_block *sb = vol->sb;
732 runlist_element *rl;
733 unsigned long flags;
734 unsigned block_size, block_size_bits;
735 int err;
736 bool should_wait = true;
737
738 ntfs_debug("Entering.");
739 if (NVolLogFileEmpty(vol)) {
740 ntfs_debug("Done.");
741 return true;
742 }
743
744
745
746
747
748
749
750 block_size = sb->s_blocksize;
751 block_size_bits = sb->s_blocksize_bits;
752 vcn = 0;
753 read_lock_irqsave(&log_ni->size_lock, flags);
754 end_vcn = (log_ni->initialized_size + vol->cluster_size_mask) >>
755 vol->cluster_size_bits;
756 read_unlock_irqrestore(&log_ni->size_lock, flags);
757 truncate_inode_pages(log_vi->i_mapping, 0);
758 down_write(&log_ni->runlist.lock);
759 rl = log_ni->runlist.rl;
760 if (unlikely(!rl || vcn < rl->vcn || !rl->length)) {
761map_vcn:
762 err = ntfs_map_runlist_nolock(log_ni, vcn, NULL);
763 if (err) {
764 ntfs_error(sb, "Failed to map runlist fragment (error "
765 "%d).", -err);
766 goto err;
767 }
768 rl = log_ni->runlist.rl;
769 BUG_ON(!rl || vcn < rl->vcn || !rl->length);
770 }
771
772 while (rl->length && vcn >= rl[1].vcn)
773 rl++;
774 do {
775 LCN lcn;
776 sector_t block, end_block;
777 s64 len;
778
779
780
781
782
783 lcn = rl->lcn;
784 if (unlikely(lcn == LCN_RL_NOT_MAPPED)) {
785 vcn = rl->vcn;
786 goto map_vcn;
787 }
788
789 if (unlikely(!rl->length || lcn < LCN_HOLE))
790 goto rl_err;
791
792 if (lcn == LCN_HOLE)
793 continue;
794 block = lcn << vol->cluster_size_bits >> block_size_bits;
795 len = rl->length;
796 if (rl[1].vcn > end_vcn)
797 len = end_vcn - rl->vcn;
798 end_block = (lcn + len) << vol->cluster_size_bits >>
799 block_size_bits;
800
801 do {
802 struct buffer_head *bh;
803
804
805 bh = sb_getblk(sb, block);
806 BUG_ON(!bh);
807
808 lock_buffer(bh);
809 bh->b_end_io = end_buffer_write_sync;
810 get_bh(bh);
811
812 memset(bh->b_data, -1, block_size);
813 if (!buffer_uptodate(bh))
814 set_buffer_uptodate(bh);
815 if (buffer_dirty(bh))
816 clear_buffer_dirty(bh);
817
818
819
820
821
822
823
824 submit_bh(WRITE, bh);
825 if (should_wait) {
826 should_wait = false;
827 wait_on_buffer(bh);
828 if (unlikely(!buffer_uptodate(bh)))
829 goto io_err;
830 }
831 brelse(bh);
832 } while (++block < end_block);
833 } while ((++rl)->vcn < end_vcn);
834 up_write(&log_ni->runlist.lock);
835
836
837
838
839
840
841
842
843 truncate_inode_pages(log_vi->i_mapping, 0);
844
845 NVolSetLogFileEmpty(vol);
846 ntfs_debug("Done.");
847 return true;
848io_err:
849 ntfs_error(sb, "Failed to write buffer. Unmount and run chkdsk.");
850 goto dirty_err;
851rl_err:
852 ntfs_error(sb, "Runlist is corrupt. Unmount and run chkdsk.");
853dirty_err:
854 NVolSetErrors(vol);
855 err = -EIO;
856err:
857 up_write(&log_ni->runlist.lock);
858 ntfs_error(sb, "Failed to fill $LogFile with 0xff bytes (error %d).",
859 -err);
860 return false;
861}
862
863#endif
864