forked from microsoft/WSL2-Linux-Kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChangeLog
1496 lines (1375 loc) · 82 KB
/
ChangeLog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
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
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
ToDo/Notes:
- Find and fix bugs.
- In between ntfs_prepare/commit_write, need exclusion between
simultaneous file extensions. This is given to us by holding i_sem
on the inode. The only places in the kernel when a file is resized
are prepare/commit write and truncate for both of which i_sem is
held. Just have to be careful in readpage/writepage and all other
helpers not running under i_sem that we play nice...
Also need to be careful with initialized_size extention in
ntfs_prepare_write. Basically, just be _very_ careful in this code...
UPDATE: The only things that need to be checked are read/writepage
which do not hold i_sem. Note writepage cannot change i_size but it
needs to cope with a concurrent i_size change, just like readpage.
Also both need to cope with concurrent changes to the other sizes,
i.e. initialized/allocated/compressed size, as well.
- Implement mft.c::sync_mft_mirror_umount(). We currently will just
leave the volume dirty on umount if the final iput(vol->mft_ino)
causes a write of any mirrored mft records due to the mft mirror
inode having been discarded already. Whether this can actually ever
happen is unclear however so it is worth waiting until someone hits
the problem.
- Enable the code for setting the NT4 compatibility flag when we start
making NTFS 1.2 specific modifications.
2.1.23 - Implement extension of resident files and make writing safe as well as
many bug fixes, cleanups, and enhancements...
- Add printk rate limiting for ntfs_warning() and ntfs_error() when
compiled without debug. This avoids a possible denial of service
attack. Thanks to Carl-Daniel Hailfinger from SuSE for pointing this
out.
- Fix compilation warnings on ia64. (Randy Dunlap)
- Use i_size_{read,write}() instead of reading i_size by hand and cache
the value where apropriate.
- Add size_lock to the ntfs_inode structure. This is an rw spinlock
and it locks against access to the inode sizes. Note, ->size_lock
is also accessed from irq context so you must use the _irqsave and
_irqrestore lock and unlock functions, respectively. Protect all
accesses to allocated_size, initialized_size, and compressed_size.
- Minor optimization to fs/ntfs/super.c::ntfs_statfs() and its helpers.
- Implement extension of resident files in the regular file write code
paths (fs/ntfs/aops.c::ntfs_{prepare,commit}_write()). At present
this only works until the data attribute becomes too big for the mft
record after which we abort the write returning -EOPNOTSUPP from
ntfs_prepare_write().
- Add disable_sparse mount option together with a per volume sparse
enable bit which is set appropriately and a per inode sparse disable
bit which is preset on some system file inodes as appropriate.
- Enforce that sparse support is disabled on NTFS volumes pre 3.0.
- Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in
the creation of the unmapped runlist element for the base attribute
extent.
- Split ntfs_map_runlist() into ntfs_map_runlist() and a non-locking
helper ntfs_map_runlist_nolock() which is used by ntfs_map_runlist().
This allows us to map runlist fragments with the runlist lock already
held without having to drop and reacquire it around the call. Adapt
all callers.
- Change ntfs_find_vcn() to ntfs_find_vcn_nolock() which takes a locked
runlist. This allows us to find runlist elements with the runlist
lock already held without having to drop and reacquire it around the
call. Adapt all callers.
- Change time to u64 in time.h::ntfs2utc() as it otherwise generates a
warning in the do_div() call on sparc32. Thanks to Meelis Roos for
the report and analysis of the warning.
- Fix a nasty runlist merge bug when merging two holes.
- Set the ntfs_inode->allocated_size to the real allocated size in the
mft record for resident attributes (fs/ntfs/inode.c).
- Small readability cleanup to use "a" instead of "ctx->attr"
everywhere (fs/ntfs/inode.c).
- Make fs/ntfs/namei.c::ntfs_get_{parent,dentry} static and move the
definition of ntfs_export_ops from fs/ntfs/super.c to namei.c. Also,
declare ntfs_export_ops in fs/ntfs/ntfs.h.
- Correct sparse file handling. The compressed values need to be
checked and set in the ntfs inode as done for compressed files and
the compressed size needs to be used for vfs inode->i_blocks instead
of the allocated size, again, as done for compressed files.
- Add AT_EA in addition to AT_DATA to whitelist for being allowed to be
non-resident in fs/ntfs/attrib.c::ntfs_attr_can_be_non_resident().
- Add fs/ntfs/attrib.c::ntfs_attr_vcn_to_lcn_nolock() used by the new
write code.
- Fix bug in fs/ntfs/attrib.c::ntfs_find_vcn_nolock() where after
dropping the read lock and taking the write lock we were not checking
whether someone else did not already do the work we wanted to do.
- Rename fs/ntfs/attrib.c::ntfs_find_vcn_nolock() to
ntfs_attr_find_vcn_nolock() and update all callers.
- Add fs/ntfs/attrib.[hc]::ntfs_attr_make_non_resident().
- Fix sign of various error return values to be negative in
fs/ntfs/lcnalloc.c.
- Modify ->readpage and ->writepage (fs/ntfs/aops.c) so they detect and
handle the case where an attribute is converted from resident to
non-resident by a concurrent file write.
- Remove checks for NULL before calling kfree() since kfree() does the
checking itself. (Jesper Juhl)
- Some utilities modify the boot sector but do not update the checksum.
Thus, relax the checking in fs/ntfs/super.c::is_boot_sector_ntfs() to
only emit a warning when the checksum is incorrect rather than
refusing the mount. Thanks to Bernd Casimir for pointing this
problem out.
- Update attribute definition handling.
- Add NTFS_MAX_CLUSTER_SIZE and NTFS_MAX_PAGES_PER_CLUSTER constants.
- Use NTFS_MAX_CLUSTER_SIZE in super.c instead of hard coding 0x10000.
- Use MAX_BUF_PER_PAGE instead of variable sized array allocation for
better code generation and one less sparse warning in fs/ntfs/aops.c.
- Remove spurious void pointer casts from fs/ntfs/. (Pekka Enberg)
- Use C99 style structure initialization after memory allocation where
possible (fs/ntfs/{attrib.c,index.c,super.c}). Thanks to Al Viro and
Pekka Enberg.
- Stamp the transaction log ($UsnJrnl), aka user space journal, if it
is active on the volume and we are mounting read-write or remounting
from read-only to read-write.
- Fix a bug in address space operations error recovery code paths where
if the runlist was not mapped at all and a mapping error occured we
would leave the runlist locked on exit to the function so that the
next access to the same file would try to take the lock and deadlock.
- Detect the case when Windows has been suspended to disk on the volume
to be mounted and if this is the case do not allow (re)mounting
read-write. This is done by parsing hiberfil.sys if present.
- Fix several occurences of a bug where we would perform 'var & ~const'
with a 64-bit variable and a int, i.e. 32-bit, constant. This causes
the higher order 32-bits of the 64-bit variable to be zeroed. To fix
this cast the 'const' to the same 64-bit type as 'var'.
- Change the runlist terminator of the newly allocated cluster(s) to
LCN_ENOENT in ntfs_attr_make_non_resident(). Otherwise the runlist
code gets confused.
- Add an extra parameter @last_vcn to ntfs_get_size_for_mapping_pairs()
and ntfs_mapping_pairs_build() to allow the runlist encoding to be
partial which is desirable when filling holes in sparse attributes.
Update all callers.
- Change ntfs_map_runlist_nolock() to only decompress the mapping pairs
if the requested vcn is inside it. Otherwise we get into problems
when we try to map an out of bounds vcn because we then try to map
the already mapped runlist fragment which causes
ntfs_mapping_pairs_decompress() to fail and return error. Update
ntfs_attr_find_vcn_nolock() accordingly.
- Fix a nasty deadlock that appeared in recent kernels.
The situation: VFS inode X on a mounted ntfs volume is dirty. For
same inode X, the ntfs_inode is dirty and thus corresponding on-disk
inode, i.e. mft record, which is in a dirty PAGE_CACHE_PAGE belonging
to the table of inodes, i.e. $MFT, inode 0.
What happens:
Process 1: sys_sync()/umount()/whatever... calls
__sync_single_inode() for $MFT -> do_writepages() -> write_page for
the dirty page containing the on-disk inode X, the page is now locked
-> ntfs_write_mst_block() which clears PageUptodate() on the page to
prevent anyone else getting hold of it whilst it does the write out.
This is necessary as the on-disk inode needs "fixups" applied before
the write to disk which are removed again after the write and
PageUptodate is then set again. It then analyses the page looking
for dirty on-disk inodes and when it finds one it calls
ntfs_may_write_mft_record() to see if it is safe to write this
on-disk inode. This then calls ilookup5() to check if the
corresponding VFS inode is in icache(). This in turn calls ifind()
which waits on the inode lock via wait_on_inode whilst holding the
global inode_lock.
Process 2: pdflush results in a call to __sync_single_inode for the
same VFS inode X on the ntfs volume. This locks the inode (I_LOCK)
then calls write-inode -> ntfs_write_inode -> map_mft_record() ->
read_cache_page() for the page (in page cache of table of inodes
$MFT, inode 0) containing the on-disk inode. This page has
PageUptodate() clear because of Process 1 (see above) so
read_cache_page() blocks when it tries to take the page lock for the
page so it can call ntfs_read_page().
Thus Process 1 is holding the page lock on the page containing the
on-disk inode X and it is waiting on the inode X to be unlocked in
ifind() so it can write the page out and then unlock the page.
And Process 2 is holding the inode lock on inode X and is waiting for
the page to be unlocked so it can call ntfs_readpage() or discover
that Process 1 set PageUptodate() again and use the page.
Thus we have a deadlock due to ifind() waiting on the inode lock.
The solution: The fix is to use the newly introduced
ilookup5_nowait() which does not wait on the inode's lock and hence
avoids the deadlock. This is safe as we do not care about the VFS
inode and only use the fact that it is in the VFS inode cache and the
fact that the vfs and ntfs inodes are one struct in memory to find
the ntfs inode in memory if present. Also, the ntfs inode has its
own locking so it does not matter if the vfs inode is locked.
- Fix bug in mft record writing where we forgot to set the device in
the buffers when mapping them after the VM had discarded them.
Thanks to Martin MOKREJŠ for the bug report.
2.1.22 - Many bug and race fixes and error handling improvements.
- Improve error handling in fs/ntfs/inode.c::ntfs_truncate().
- Change fs/ntfs/inode.c::ntfs_truncate() to return an error code
instead of void and provide a helper ntfs_truncate_vfs() for the
vfs ->truncate method.
- Add a new ntfs inode flag NInoTruncateFailed() and modify
fs/ntfs/inode.c::ntfs_truncate() to set and clear it appropriately.
- Fix min_size and max_size definitions in ATTR_DEF structure in
fs/ntfs/layout.h to be signed.
- Add attribute definition handling helpers to fs/ntfs/attrib.[hc]:
ntfs_attr_size_bounds_check(), ntfs_attr_can_be_non_resident(), and
ntfs_attr_can_be_resident(), which in turn use the new private helper
ntfs_attr_find_in_attrdef().
- In fs/ntfs/aops.c::mark_ntfs_record_dirty(), take the
mapping->private_lock around the dirtying of the buffer heads
analagous to the way it is done in __set_page_dirty_buffers().
- Ensure the mft record size does not exceed the PAGE_CACHE_SIZE at
mount time as this cannot work with the current implementation.
- Check for location of attribute name and improve error handling in
general in fs/ntfs/inode.c::ntfs_read_locked_inode() and friends.
- In fs/ntfs/aops.c::ntfs_writepage(), if the page is fully outside
i_size, i.e. race with truncate, invalidate the buffers on the page
so that they become freeable and hence the page does not leak.
- Remove unused function fs/ntfs/runlist.c::ntfs_rl_merge(). (Adrian
Bunk)
- Fix stupid bug in fs/ntfs/attrib.c::ntfs_attr_find() that resulted in
a NULL pointer dereference in the error code path when a corrupt
attribute was found. (Thanks to Domen Puncer for the bug report.)
- Add MODULE_VERSION() to fs/ntfs/super.c.
- Make several functions and variables static. (Adrian Bunk)
- Modify fs/ntfs/aops.c::mark_ntfs_record_dirty() so it allocates
buffers for the page if they are not present and then marks the
buffers belonging to the ntfs record dirty. This causes the buffers
to become busy and hence they are safe from removal until the page
has been written out.
- Fix stupid bug in fs/ntfs/attrib.c::ntfs_external_attr_find() in the
error handling code path that resulted in a BUG() due to trying to
unmap an extent mft record when the mapping of it had failed and it
thus was not mapped. (Thanks to Ken MacFerrin for the bug report.)
- Drop the runlist lock after the vcn has been read in
fs/ntfs/lcnalloc.c::__ntfs_cluster_free().
- Rewrite handling of multi sector transfer errors. We now do not set
PageError() when such errors are detected in the async i/o handler
fs/ntfs/aops.c::ntfs_end_buffer_async_read(). All users of mst
protected attributes now check the magic of each ntfs record as they
use it and act appropriately. This has the effect of making errors
granular per ntfs record rather than per page which solves the case
where we cannot access any of the ntfs records in a page when a
single one of them had an mst error. (Thanks to Ken MacFerrin for
the bug report.)
- Fix error handling in fs/ntfs/quota.c::ntfs_mark_quotas_out_of_date()
where we failed to release i_sem on the $Quota/$Q attribute inode.
- Fix bug in handling of bad inodes in fs/ntfs/namei.c::ntfs_lookup().
- Add mapping of unmapped buffers to all remaining code paths, i.e.
fs/ntfs/aops.c::ntfs_write_mst_block(), mft.c::ntfs_sync_mft_mirror(),
and write_mft_record_nolock(). From now on we require that the
complete runlist for the mft mirror is always mapped into memory.
- Add creation of buffers to fs/ntfs/mft.c::ntfs_sync_mft_mirror().
- Improve error handling in fs/ntfs/aops.c::ntfs_{read,write}_block().
- Cleanup fs/ntfs/aops.c::ntfs_{read,write}page() since we know that a
resident attribute will be smaller than a page which makes the code
simpler. Also make the code more tolerant to concurrent ->truncate.
2.1.21 - Fix some races and bugs, rewrite mft write code, add mft allocator.
- Implement extent mft record deallocation
fs/ntfs/mft.c::ntfs_extent_mft_record_free().
- Splitt runlist related functions off from attrib.[hc] to runlist.[hc].
- Add vol->mft_data_pos and initialize it at mount time.
- Rename init_runlist() to ntfs_init_runlist(), ntfs_vcn_to_lcn() to
ntfs_rl_vcn_to_lcn(), decompress_mapping_pairs() to
ntfs_mapping_pairs_decompress(), ntfs_merge_runlists() to
ntfs_runlists_merge() and adapt all callers.
- Add fs/ntfs/runlist.[hc]::ntfs_get_nr_significant_bytes(),
ntfs_get_size_for_mapping_pairs(), ntfs_write_significant_bytes(),
and ntfs_mapping_pairs_build(), adapted from libntfs.
- Make fs/ntfs/lcnalloc.c::ntfs_cluster_free_from_rl_nolock() not
static and add a declaration for it to lcnalloc.h.
- Add fs/ntfs/lcnalloc.h::ntfs_cluster_free_from_rl() which is a static
inline wrapper for ntfs_cluster_free_from_rl_nolock() which takes the
cluster bitmap lock for the duration of the call.
- Add fs/ntfs/attrib.[hc]::ntfs_attr_record_resize().
- Implement the equivalent of memset() for an ntfs attribute in
fs/ntfs/attrib.[hc]::ntfs_attr_set() and switch
fs/ntfs/logfile.c::ntfs_empty_logfile() to using it.
- Remove unnecessary casts from LCN_* constants.
- Implement fs/ntfs/runlist.c::ntfs_rl_truncate_nolock().
- Add MFT_RECORD_OLD as a copy of MFT_RECORD in fs/ntfs/layout.h and
change MFT_RECORD to contain the NTFS 3.1+ specific fields.
- Add a helper function fs/ntfs/aops.c::mark_ntfs_record_dirty() which
marks all buffers belonging to an ntfs record dirty, followed by
marking the page the ntfs record is in dirty and also marking the vfs
inode containing the ntfs record dirty (I_DIRTY_PAGES).
- Switch fs/ntfs/index.h::ntfs_index_entry_mark_dirty() to using the
new helper fs/ntfs/aops.c::mark_ntfs_record_dirty() and remove the no
longer needed fs/ntfs/index.[hc]::__ntfs_index_entry_mark_dirty().
- Move ntfs_{un,}map_page() from ntfs.h to aops.h and fix resulting
include errors.
- Move the typedefs for runlist_element and runlist from types.h to
runlist.h and fix resulting include errors.
- Remove unused {__,}format_mft_record() from fs/ntfs/mft.c.
- Modify fs/ntfs/mft.c::__mark_mft_record_dirty() to use the helper
mark_ntfs_record_dirty() which also changes the behaviour in that we
now set the buffers belonging to the mft record dirty as well as the
page itself.
- Update fs/ntfs/mft.c::write_mft_record_nolock() and sync_mft_mirror()
to cope with the fact that there now are dirty buffers in mft pages.
- Update fs/ntfs/inode.c::ntfs_write_inode() to also use the helper
mark_ntfs_record_dirty() and thus to set the buffers belonging to the
mft record dirty as well as the page itself.
- Fix compiler warnings on x86-64 in fs/ntfs/dir.c. (Randy Dunlap,
slightly modified by me)
- Add fs/ntfs/mft.c::try_map_mft_record() which fails with -EALREADY if
the mft record is already locked and otherwise behaves the same way
as fs/ntfs/mft.c::map_mft_record().
- Modify fs/ntfs/mft.c::write_mft_record_nolock() so that it only
writes the mft record if the buffers belonging to it are dirty.
Otherwise we assume that it was written out by other means already.
- Attempting to write outside initialized size is _not_ a bug so remove
the bug check from fs/ntfs/aops.c::ntfs_write_mst_block(). It is in
fact required to write outside initialized size when preparing to
extend the initialized size.
- Map the page instead of using page_address() before writing to it in
fs/ntfs/aops.c::ntfs_mft_writepage().
- Provide exclusion between opening an inode / mapping an mft record
and accessing the mft record in fs/ntfs/mft.c::ntfs_mft_writepage()
by setting the page not uptodate throughout ntfs_mft_writepage().
- Clear the page uptodate flag in fs/ntfs/aops.c::ntfs_write_mst_block()
to ensure noone can see the page whilst the mst fixups are applied.
- Add the helper fs/ntfs/mft.c::ntfs_may_write_mft_record() which
checks if an mft record may be written out safely obtaining any
necessary locks in the process. This is used by
fs/ntfs/aops.c::ntfs_write_mst_block().
- Modify fs/ntfs/aops.c::ntfs_write_mst_block() to also work for
writing mft records and improve its error handling in the process.
Now if any of the records in the page fail to be written out, all
other records will be written out instead of aborting completely.
- Remove ntfs_mft_aops and update all users to use ntfs_mst_aops.
- Modify fs/ntfs/inode.c::ntfs_read_locked_inode() to set the
ntfs_mst_aops for all inodes which are NInoMstProtected() and
ntfs_aops for all other inodes.
- Rename fs/ntfs/mft.c::sync_mft_mirror{,_umount}() to
ntfs_sync_mft_mirror{,_umount}() and change their parameters so they
no longer require an ntfs inode to be present. Update all callers.
- Cleanup the error handling in fs/ntfs/mft.c::ntfs_sync_mft_mirror().
- Clear the page uptodate flag in fs/ntfs/mft.c::ntfs_sync_mft_mirror()
to ensure noone can see the page whilst the mst fixups are applied.
- Remove the no longer needed fs/ntfs/mft.c::ntfs_mft_writepage() and
fs/ntfs/mft.c::try_map_mft_record().
- Fix callers of fs/ntfs/aops.c::mark_ntfs_record_dirty() to call it
with the ntfs inode which contains the page rather than the ntfs
inode the mft record of which is in the page.
- Fix race condition in fs/ntfs/inode.c::ntfs_put_inode() by moving the
index inode bitmap inode release code from there to
fs/ntfs/inode.c::ntfs_clear_big_inode(). (Thanks to Christoph
Hellwig for spotting this.)
- Fix race condition in fs/ntfs/inode.c::ntfs_put_inode() by taking the
inode semaphore around the code that sets ni->itype.index.bmp_ino to
NULL and reorganize the code to optimize it a bit. (Thanks to
Christoph Hellwig for spotting this.)
- Modify fs/ntfs/aops.c::mark_ntfs_record_dirty() to no longer take the
ntfs inode as a parameter as this is confusing and misleading and the
needed ntfs inode is available via NTFS_I(page->mapping->host).
Adapt all callers to this change.
- Modify fs/ntfs/mft.c::write_mft_record_nolock() and
fs/ntfs/aops.c::ntfs_write_mst_block() to only check the dirty state
of the first buffer in a record and to take this as the ntfs record
dirty state. We cannot look at the dirty state for subsequent
buffers because we might be racing with
fs/ntfs/aops.c::mark_ntfs_record_dirty().
- Move the static inline ntfs_init_big_inode() from fs/ntfs/inode.c to
inode.h and make fs/ntfs/inode.c::__ntfs_init_inode() non-static and
add a declaration for it to inode.h. Fix some compilation issues
that resulted due to #includes and header file interdependencies.
- Simplify setup of i_mode in fs/ntfs/inode.c::ntfs_read_locked_inode().
- Add helpers fs/ntfs/layout.h::MK_MREF() and MK_LE_MREF().
- Modify fs/ntfs/mft.c::map_extent_mft_record() to only verify the mft
record sequence number if it is specified (i.e. not zero).
- Add fs/ntfs/mft.[hc]::ntfs_mft_record_alloc() and various helper
functions used by it.
- Update Documentation/filesystems/ntfs.txt with instructions on how to
use the Device-Mapper driver with NTFS ftdisk/LDM raid. This removes
the linear raid problem with the Software RAID / MD driver when one
or more of the devices has an odd number of sectors.
2.1.20 - Fix two stupid bugs introduced in 2.1.18 release.
- Fix stupid bug in fs/ntfs/attrib.c::ntfs_attr_reinit_search_ctx()
where we did not clear ctx->al_entry but it was still set due to
changes in ntfs_attr_lookup() and ntfs_external_attr_find() in
particular.
- Fix another stupid bug in fs/ntfs/attrib.c::ntfs_external_attr_find()
where we forgot to unmap the extent mft record when we had finished
enumerating an attribute which caused a bug check to trigger when the
VFS calls ->clear_inode.
2.1.19 - Many cleanups, improvements, and a minor bug fix.
- Update ->setattr (fs/ntfs/inode.c::ntfs_setattr()) to refuse to
change the uid, gid, and mode of an inode as we do not support NTFS
ACLs yet.
- Remove BKL use from ntfs_setattr() syncing up with the rest of the
kernel.
- Get rid of the ugly transparent union in fs/ntfs/dir.c::ntfs_readdir()
and ntfs_filldir() as per suggestion from Al Viro.
- Change '\0' and L'\0' to simply 0 as per advice from Linus Torvalds.
- Update ->truncate (fs/ntfs/inode.c::ntfs_truncate()) to check if the
inode size has changed and to only output an error if so.
- Rename fs/ntfs/attrib.h::attribute_value_length() to ntfs_attr_size().
- Add le{16,32,64} as well as sle{16,32,64} data types to
fs/ntfs/types.h.
- Change ntfschar to be le16 instead of u16 in fs/ntfs/types.h.
- Add le versions of VCN, LCN, and LSN called leVCN, leLCN, and leLSN,
respectively, to fs/ntfs/types.h.
- Update endianness conversion macros in fs/ntfs/endian.h to use the
new types as appropriate.
- Do proper type casting when using sle64_to_cpup() in fs/ntfs/dir.c
and index.c.
- Add leMFT_REF data type to fs/ntfs/layout.h.
- Update all NTFS header files with the new little endian data types.
Affected files are fs/ntfs/layout.h, logfile.h, and time.h.
- Do proper type casting when using ntfs_is_*_recordp() in
fs/ntfs/logfile.c, mft.c, and super.c.
- Fix all the sparse bitwise warnings. Had to change all the typedef
enums storing little endian values to simple enums plus a typedef for
the datatype to make sparse happy.
- Fix a bug found by the new sparse bitwise warnings where the default
upcase table was defined as a pointer to wchar_t rather than ntfschar
in fs/ntfs/ntfs.h and super.c.
- Change {const_,}cpu_to_le{16,32}(0) to just 0 as suggested by Al Viro.
2.1.18 - Fix scheduling latencies at mount time as well as an endianness bug.
- Remove vol->nr_mft_records as it was pretty meaningless and optimize
the calculation of total/free inodes as used by statfs().
- Fix scheduling latencies in ntfs_fill_super() by dropping the BKL
because the code itself is using the ntfs_lock semaphore which
provides safe locking. (Ingo Molnar)
- Fix a potential bug in fs/ntfs/mft.c::map_extent_mft_record() that
could occur in the future for when we start closing/freeing extent
inodes if we don't set base_ni->ext.extent_ntfs_inos to NULL after
we free it.
- Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as
find_external_attr() to ntfs_external_attr_find() to cleanup the
namespace a bit and to be more consistent with libntfs.
- Rename {{re,}init,get,put}_attr_search_ctx() to
ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type
attr_search_context to ntfs_attr_search_ctx.
- Force use of ntfs_attr_find() in ntfs_attr_lookup() when searching
for the attribute list attribute itself.
- Fix endianness bug in ntfs_external_attr_find().
- Change ntfs_{external_,}attr_find() to return 0 on success, -ENOENT
if the attribute is not found, and -EIO on real error. In the case
of -ENOENT, the search context is updated to describe the attribute
before which the attribute being searched for would need to be
inserted if such an action were to be desired and in the case of
ntfs_external_attr_find() the search context is also updated to
indicate the attribute list entry before which the attribute list
entry of the attribute being searched for would need to be inserted
if such an action were to be desired. Also make ntfs_find_attr()
static and remove its prototype from attrib.h as it is not used
anywhere other than attrib.c. Update ntfs_attr_lookup() and all
callers of ntfs_{external,}attr_{find,lookup}() for the new return
values.
- Minor cleanup of fs/ntfs/inode.c::ntfs_init_locked_inode().
2.1.17 - Fix bugs in mount time error code paths and other updates.
- Implement bitmap modification code (fs/ntfs/bitmap.[hc]). This
includes functions to set/clear a single bit or a run of bits.
- Add fs/ntfs/attrib.[hc]::ntfs_find_vcn() which returns the locked
runlist element containing a particular vcn. It also takes care of
mapping any needed runlist fragments.
- Implement cluster (de-)allocation code (fs/ntfs/lcnalloc.[hc]).
- Load attribute definition table from $AttrDef at mount time.
- Fix bugs in mount time error code paths involving (de)allocation of
the default and volume upcase tables.
- Remove ntfs_nr_mounts as it is no longer used.
2.1.16 - Implement access time updates, file sync, async io, and read/writev.
- Add support for readv/writev and aio_read/aio_write (fs/ntfs/file.c).
This is done by setting the appropriate file operations pointers to
the generic helper functions provided by mm/filemap.c.
- Implement fsync, fdatasync, and msync both for files (fs/ntfs/file.c)
and directories (fs/ntfs/dir.c).
- Add support for {a,m,c}time updates to inode.c::ntfs_write_inode().
Note, except for the root directory and any other system files opened
by the user, the system files will not have their access times
updated as they are only accessed at the inode level an hence the
file level functions which cause the times to be updated are never
invoked.
2.1.15 - Invalidate quotas when (re)mounting read-write.
- Add new element itype.index.collation_rule to the ntfs inode
structure and set it appropriately in ntfs_read_locked_inode().
- Implement a new inode type "index" to allow efficient access to the
indices found in various system files and adapt inode handling
accordingly (fs/ntfs/inode.[hc]). An index inode is essentially an
attribute inode (NInoAttr() is true) with an attribute type of
AT_INDEX_ALLOCATION. As such, it is no longer allowed to call
ntfs_attr_iget() with an attribute type of AT_INDEX_ALLOCATION as
there would be no way to distinguish between normal attribute inodes
and index inodes. The function to obtain an index inode is
ntfs_index_iget() and it uses the helper function
ntfs_read_locked_index_inode(). Note, we do not overload
ntfs_attr_iget() as indices consist of multiple attributes so using
ntfs_attr_iget() to obtain an index inode would be confusing.
- Ensure that there is no overflow when doing page->index <<
PAGE_CACHE_SHIFT by casting page->index to s64 in fs/ntfs/aops.c.
- Use atomic kmap instead of kmap() in fs/ntfs/aops.c::ntfs_read_page()
and ntfs_read_block().
- Use case sensitive attribute lookups instead of case insensitive ones.
- Lock all page cache pages belonging to mst protected attributes while
accessing them to ensure we never see corrupt data while the page is
under writeout.
- Add framework for generic ntfs collation (fs/ntfs/collation.[hc]).
We have ntfs_is_collation_rule_supported() to check if the collation
rule you want to use is supported and ntfs_collation() which actually
collates two data items. We currently only support COLLATION_BINARY
and COLLATION_NTOFS_ULONG but support for other collation rules will
be added as the need arises.
- Add a new type, ntfs_index_context, to allow retrieval of an index
entry using the corresponding index key. To get an index context,
use ntfs_index_ctx_get() and to release it, use ntfs_index_ctx_put().
This also adds a new slab cache for the index contexts. To lookup a
key in an index inode, use ntfs_index_lookup(). After modifying an
index entry, call ntfs_index_entry_flush_dcache_page() followed by
ntfs_index_entry_mark_dirty() to ensure the changes are written out
to disk. For details see fs/ntfs/index.[hc]. Note, at present, if
an index entry is in the index allocation attribute rather than the
index root attribute it will not be written out (you will get a
warning message about discarded changes instead).
- Load the quota file ($Quota) and check if quota tracking is enabled
and if so, mark the quotas out of date. This causes windows to
rescan the volume on boot and update all quota entries.
- Add a set_page_dirty address space operation for ntfs_m[fs]t_aops.
It is simply set to __set_page_dirty_nobuffers() to make sure that
running set_page_dirty() on a page containing mft/ntfs records will
not affect the dirty state of the page buffers.
- Add fs/ntfs/index.c::__ntfs_index_entry_mark_dirty() which sets all
buffers that are inside the ntfs record in the page dirty after which
it sets the page dirty. This allows ->writepage to only write the
dirty index records rather than having to write all the records in
the page. Modify fs/ntfs/index.h::ntfs_index_entry_mark_dirty() to
use this rather than __set_page_dirty_nobuffers().
- Implement fs/ntfs/aops.c::ntfs_write_mst_block() which enables the
writing of page cache pages belonging to mst protected attributes
like the index allocation attribute in directory indices and other
indices like $Quota/$Q, etc. This means that the quota is now marked
out of date on all volumes rather than only on ones where the quota
defaults entry is in the index root attribute of the $Quota/$Q index.
2.1.14 - Fix an NFSd caused deadlock reported by several users.
- Modify fs/ntfs/ntfs_readdir() to copy the index root attribute value
to a buffer so that we can put the search context and unmap the mft
record before calling the filldir() callback. We need to do this
because of NFSd which calls ->lookup() from its filldir callback()
and this causes NTFS to deadlock as ntfs_lookup() maps the mft record
of the directory and since ntfs_readdir() has got it mapped already
ntfs_lookup() deadlocks.
2.1.13 - Enable overwriting of resident files and housekeeping of system files.
- Implement writing of mft records (fs/ntfs/mft.[hc]), which includes
keeping the mft mirror in sync with the mft when mirrored mft records
are written. The functions are write_mft_record{,_nolock}(). The
implementation is quite rudimentary for now with lots of things not
implemented yet but I am not sure any of them can actually occur so
I will wait for people to hit each one and only then implement it.
- Commit open system inodes at umount time. This should make it
virtually impossible for sync_mft_mirror_umount() to ever be needed.
- Implement ->write_inode (fs/ntfs/inode.c::ntfs_write_inode()) for the
ntfs super operations. This gives us inode writing via the VFS inode
dirty code paths. Note: Access time updates are not implemented yet.
- Implement fs/ntfs/mft.[hc]::{,__}mark_mft_record_dirty() and make
fs/ntfs/aops.c::ntfs_writepage() and ntfs_commit_write() use it, thus
finally enabling resident file overwrite! (-8 This also includes a
placeholder for ->writepage (ntfs_mft_writepage()), which for now
just redirties the page and returns. Also, at umount time, we for
now throw away all mft data page cache pages after the last call to
ntfs_commit_inode() in the hope that all inodes will have been
written out by then and hence no dirty (meta)data will be lost. We
also check for this case and emit an error message telling the user
to run chkdsk.
- Use set_page_writeback() and end_page_writeback() in the resident
attribute code path of fs/ntfs/aops.c::ntfs_writepage() otherwise
the radix-tree tag PAGECACHE_TAG_DIRTY remains set even though the
page is clean.
- Implement ntfs_mft_writepage() so it now checks if any of the mft
records in the page are dirty and if so redirties the page and
returns. Otherwise it just returns (after doing set_page_writeback(),
unlock_page(), end_page_writeback() or the radix-tree tag
PAGECACHE_TAG_DIRTY remains set even though the page is clean), thus
alowing the VM to do with the page as it pleases. Also, at umount
time, now only throw away dirty mft (meta)data pages if dirty inodes
are present and ask the user to email us if they see this happening.
- Add functions ntfs_{clear,set}_volume_flags(), to modify the volume
information flags (fs/ntfs/super.c).
- Mark the volume dirty when (re)mounting read-write and mark it clean
when unmounting or remounting read-only. If any volume errors are
found, the volume is left marked dirty to force chkdsk to run.
- Add code to set the NT4 compatibility flag when (re)mounting
read-write for newer NTFS versions but leave it commented out for now
since we do not make any modifications that are NTFS 1.2 specific yet
and since setting this flag breaks Captive-NTFS which is not nice.
This code must be enabled once we start writing NTFS 1.2 specific
changes otherwise Windows NTFS driver might crash / cause corruption.
2.1.12 - Fix the second fix to the decompression engine and some cleanups.
- Add a new address space operations struct, ntfs_mst_aops, for mst
protected attributes. This is because the default ntfs_aops do not
make sense with mst protected data and were they to write anything to
such an attribute they would cause data corruption so we provide
ntfs_mst_aops which does not have any write related operations set.
- Cleanup dirty ntfs inode handling (fs/ntfs/inode.[hc]) which also
includes an adapted ntfs_commit_inode() and an implementation of
ntfs_write_inode() which for now just cleans dirty inodes without
writing them (it does emit a warning that this is happening).
- Undo the second decompression engine fix (see 2.1.9 release ChangeLog
entry) as it was only fixing a theoretical bug but at the same time
it badly broke the handling of sparse and uncompressed compression
blocks.
2.1.11 - Driver internal cleanups.
- Only build logfile.o if building the driver with read-write support.
- Really final white space cleanups.
- Use generic_ffs() instead of ffs() in logfile.c which allows the
log_page_size variable to be optimized by gcc into a constant.
- Rename uchar_t to ntfschar everywhere as uchar_t is unsigned 1-byte
char as defined by POSIX and as found on some systems.
2.1.10 - Force read-only (re)mounting of volumes with unsupported volume flags.
- Finish off the white space cleanups (remove trailing spaces, etc).
- Clean up ntfs_fill_super() and ntfs_read_inode_mount() by removing
the kludges around the first iget(). Instead of (re)setting ->s_op
we have the $MFT inode set up by explicit new_inode() / set ->i_ino /
insert_inode_hash() / call ntfs_read_inode_mount() directly. This
kills the need for second super_operations and allows to return error
from ntfs_read_inode_mount() without resorting to ugly "poisoning"
tricks. (Al Viro)
- Force read-only (re)mounting if any of the following bits are set in
the volume information flags:
VOLUME_IS_DIRTY, VOLUME_RESIZE_LOG_FILE,
VOLUME_UPGRADE_ON_MOUNT, VOLUME_DELETE_USN_UNDERWAY,
VOLUME_REPAIR_OBJECT_ID, VOLUME_MODIFIED_BY_CHKDSK
To make this easier we define VOLUME_MUST_MOUNT_RO_MASK with all the
above bits set so the test is made easy.
2.1.9 - Fix two bugs in decompression engine.
- Fix a bug where we would not always detect that we have reached the
end of a compression block because we were ending at minus one byte
which is effectively the same as being at the end. The fix is to
check whether the uncompressed buffer has been fully filled and if so
we assume we have reached the end of the compression block. A big
thank you to Marcin Gibuła for the bug report, the assistance in
tracking down the bug and testing the fix.
- Fix a possible bug where when a compressed read is truncated to the
end of the file, the offset inside the last page was not truncated.
2.1.8 - Handle $MFT mirror and $LogFile, improve time handling, and cleanups.
- Use get_bh() instead of manual atomic_inc() in fs/ntfs/compress.c.
- Modify fs/ntfs/time.c::ntfs2utc(), get_current_ntfs_time(), and
utc2ntfs() to work with struct timespec instead of time_t on the
Linux UTC time side thus preserving the full precision of the NTFS
time and only loosing up to 99 nano-seconds in the Linux UTC time.
- Move fs/ntfs/time.c to fs/ntfs/time.h and make the time functions
static inline.
- Remove unused ntfs_dirty_inode().
- Cleanup super operations declaration in fs/ntfs/super.c.
- Wrap flush_dcache_mft_record_page() in #ifdef NTFS_RW.
- Add NInoTestSetFoo() and NInoTestClearFoo() macro magic to
fs/ntfs/inode.h and use it to declare NInoTest{Set,Clear}Dirty.
- Move typedefs for ntfs_attr and test_t from fs/ntfs/inode.c to
fs/ntfs/inode.h so they can be used elsewhere.
- Determine the mft mirror size as the number of mirrored mft records
and store it in ntfs_volume->mftmirr_size (fs/ntfs/super.c).
- Load the mft mirror at mount time and compare the mft records stored
in it to the ones in the mft. Force a read-only mount if the two do
not match (fs/ntfs/super.c).
- Fix type casting related warnings on 64-bit architectures. Thanks
to Meelis Roos for reporting them.
- Move %L to %ll as %L is floating point and %ll is integer which is
what we want.
- Read the journal ($LogFile) and determine if the volume has been
shutdown cleanly and force a read-only mount if not (fs/ntfs/super.c
and fs/ntfs/logfile.c). This is a little bit of a crude check in
that we only look at the restart areas and not at the actual log
records so that there will be a very small number of cases where we
think that a volume is dirty when in fact it is clean. This should
only affect volumes that have not been shutdown cleanly and did not
have any pending, non-check-pointed i/o.
- If the $LogFile indicates a clean shutdown and a read-write (re)mount
is requested, empty $LogFile by overwriting it with 0xff bytes to
ensure that Windows cannot cause data corruption by replaying a stale
journal after Linux has written to the volume.
2.1.7 - Enable NFS exporting of mounted NTFS volumes.
- Set i_generation in the VFS inode from the seq_no of the NTFS inode.
- Make ntfs_lookup() NFS export safe, i.e. use d_splice_alias(), etc.
- Implement ->get_dentry() in fs/ntfs/namei.c::ntfs_get_dentry() as the
default doesn't allow inode number 0 which is a valid inode on NTFS
and even if it did allow that it uses iget() instead of ntfs_iget()
which makes it useless for us.
- Implement ->get_parent() in fs/ntfs/namei.c::ntfs_get_parent() as the
default just returns -EACCES which is not very useful.
- Define export operations (->s_export_op) for NTFS (ntfs_export_ops)
and set them up in the super block at mount time (super.c) this
allows mounted NTFS volumes to be exported via NFS.
- Add missing return -EOPNOTSUPP; in
fs/ntfs/aops.c::ntfs_commit_nonresident_write().
- Enforce no atime and no dir atime updates at mount/remount time as
they are not implemented yet anyway.
- Move a few assignments in fs/ntfs/attrib.c::load_attribute_list() to
after a NULL check. Thanks to Dave Jones for pointing this out.
2.1.6 - Fix minor bug in handling of compressed directories.
- Fix bug in handling of compressed directories. A compressed
directory is not really compressed so when we set the ->i_blocks
field of a compressed directory inode we were setting it from the
non-existing field ni->itype.compressed.size which gave random
results... For directories we now always use ni->allocated_size.
2.1.5 - Fix minor bug in attribute list attribute handling.
- Fix bug in attribute list handling. Actually it is not as much a bug
as too much protection in that we were not allowing attribute lists
which waste space on disk while Windows XP clearly allows it and in
fact creates such attribute lists so our driver was failing.
- Update NTFS documentation ready for 2.6 kernel release.
2.1.4 - Reduce compiler requirements.
- Remove all uses of unnamed structs and unions in the driver to make
old and newer gcc versions happy. Makes it a bit uglier IMO but at
least people will stop hassling me about it.
2.1.3 - Important bug fixes in corner cases.
- super.c::parse_ntfs_boot_sector(): Correct the check for 64-bit
clusters. (Philipp Thomas)
- attrib.c::load_attribute_list(): Fix bug when initialized_size is a
multiple of the block_size but not the cluster size. (Szabolcs
Szakacsits <szaka@sienet.hu>)
2.1.2 - Important bug fixes aleviating the hangs in statfs.
- Fix buggy free cluster and free inode determination logic.
2.1.1 - Minor updates.
- Add handling for initialized_size != data_size in compressed files.
- Reduce function local stack usage from 0x3d4 bytes to just noise in
fs/ntfs/upcase.c. (Randy Dunlap <rddunlap@osdl.ord>)
- Remove compiler warnings for newer gcc.
- Pages are no longer kmapped by mm/filemap.c::generic_file_write()
around calls to ->{prepare,commit}_write. Adapt NTFS appropriately
in fs/ntfs/aops.c::ntfs_prepare_nonresident_write() by using
kmap_atomic(KM_USER0).
2.1.0 - First steps towards write support: implement file overwrite.
- Add configuration option for developmental write support with an
appropriately scary configuration help text.
- Initial implementation of fs/ntfs/aops.c::ntfs_writepage() and its
helper fs/ntfs/aops.c::ntfs_write_block(). This enables mmap(2) based
overwriting of existing files on ntfs. Note: Resident files are
only written into memory, and not written out to disk at present, so
avoid writing to files smaller than about 1kiB.
- Initial implementation of fs/ntfs/aops.c::ntfs_prepare_write(), its
helper fs/ntfs/aops.c::ntfs_prepare_nonresident_write() and their
counterparts, fs/ntfs/aops.c::ntfs_commit_write(), and
fs/ntfs/aops.c::ntfs_commit_nonresident_write(), respectively. Also,
add generic_file_write() to the ntfs file operations (fs/ntfs/file.c).
This enables write(2) based overwriting of existing files on ntfs.
Note: As with mmap(2) based overwriting, resident files are only
written into memory, and not written out to disk at present, so avoid
writing to files smaller than about 1kiB.
- Implement ->truncate (fs/ntfs/inode.c::ntfs_truncate()) and
->setattr() (fs/ntfs/inode.c::ntfs_setattr()) inode operations for
files with the purpose of intercepting and aborting all i_size
changes which we do not support yet. ntfs_truncate() actually only
emits a warning message but AFAICS our interception of i_size changes
elsewhere means ntfs_truncate() never gets called for i_size changes.
It is only called from generic_file_write() when we fail in
ntfs_prepare_{,nonresident_}write() in order to discard any
instantiated buffers beyond i_size. Thus i_size is not actually
changed so our warning message is enough. Unfortunately it is not
possible to easily determine if i_size is being changed or not hence
we just emit an appropriately worded error message.
2.0.25 - Small bug fixes and cleanups.
- Unlock the page in an out of memory error code path in
fs/ntfs/aops.c::ntfs_read_block().
- If fs/ntfs/aops.c::ntfs_read_page() is called on an uptodate page,
just unlock the page and return. (This can happen due to ->writepage
clearing PageUptodate() during write out of MstProtected()
attributes.
- Remove leaked write code again.
2.0.24 - Cleanups.
- Treat BUG_ON() as ASSERT() not VERIFY(), i.e. do not use side effects
inside BUG_ON(). (Adam J. Richter)
- Split logical OR expressions inside BUG_ON() into individual BUG_ON()
calls for improved debugging. (Adam J. Richter)
- Add errors flag to the ntfs volume state, accessed via
NVol{,Set,Clear}Errors(vol).
- Do not allow read-write remounts of read-only volumes with errors.
- Clarify comment for ntfs file operation sendfile which was added by
Christoph Hellwig a while ago (just using generic_file_sendfile())
to say that ntfs ->sendfile is only used for the case where the
source data is on the ntfs partition and the destination is
somewhere else, i.e. nothing we need to concern ourselves with.
- Add generic_file_write() as our ntfs file write operation.
2.0.23 - Major bug fixes (races, deadlocks, non-i386 architectures).
- Massive internal locking changes to mft record locking. Fixes lock
recursion and replaces the mrec_lock read/write semaphore with a
mutex. Also removes the now superfluous mft_count. This fixes several
race conditions and deadlocks, especially in the future write code.
- Fix ntfs over loopback for compressed files by adding an
optimization barrier. (gcc was screwing up otherwise ?)
- Miscellaneous cleanups all over the code and a fix or two in error
handling code paths.
Thanks go to Christoph Hellwig for pointing out the following two:
- Remove now unused function fs/ntfs/malloc.h::vmalloc_nofs().
- Fix ntfs_free() for ia64 and parisc by checking for VMALLOC_END, too.
2.0.22 - Cleanups, mainly to ntfs_readdir(), and use C99 initializers.
- Change fs/ntfs/dir.c::ntfs_reddir() to only read/write ->f_pos once
at entry/exit respectively.
- Use C99 initializers for structures.
- Remove unused variable blocks from fs/ntfs/aops.c::ntfs_read_block().
2.0.21 - Check for, and refuse to work with too large files/directories/volumes.
- Limit volume size at mount time to 2TiB on architectures where
unsigned long is 32-bits (fs/ntfs/super.c::parse_ntfs_boot_sector()).
This is the most we can do without overflowing the 32-bit limit of
the block device size imposed on us by sb_bread() and sb_getblk()
for the time being.
- Limit file/directory size at open() time to 16TiB on architectures
where unsigned long is 32-bits (fs/ntfs/file.c::ntfs_file_open() and
fs/ntfs/dir.c::ntfs_dir_open()). This is the most we can do without
overflowing the page cache page index.
2.0.20 - Support non-resident directory index bitmaps, fix page leak in readdir.
- Move the directory index bitmap to use an attribute inode instead of
having special fields for it inside the ntfs inode structure. This
means that the index bitmaps now use the page cache for i/o, too,
and also as a side effect we get support for non-resident index
bitmaps for free.
- Simplify/cleanup error handling in fs/ntfs/dir.c::ntfs_readdir() and
fix a page leak that manifested itself in some cases.
- Add fs/ntfs/inode.c::ntfs_put_inode(), which we need to release the
index bitmap inode on the final iput().
2.0.19 - Fix race condition, improvements, and optimizations in i/o interface.
- Apply block optimization added to fs/ntfs/aops.c::ntfs_read_block()
to fs/ntfs/compress.c::ntfs_file_read_compressed_block() as well.
- Drop the "file" from ntfs_file_read_compressed_block().
- Rename fs/ntfs/aops.c::ntfs_enb_buffer_read_async() to
ntfs_end_buffer_async_read() (more like the fs/buffer.c counterpart).
- Update ntfs_end_buffer_async_read() with the improved logic from
its updated counterpart fs/buffer.c::end_buffer_async_read(). Apply
further logic improvements to better determine when we set PageError.
- Update submission of buffers in fs/ntfs/aops.c::ntfs_read_block() to
check for the buffers being uptodate first in line with the updated
fs/buffer.c::block_read_full_page(). This plugs a small race
condition.
2.0.18 - Fix race condition in reading of compressed files.
- There was a narrow window between checking a buffer head for being
uptodate and locking it in ntfs_file_read_compressed_block(). We now
lock the buffer and then check whether it is uptodate or not.
2.0.17 - Cleanups and optimizations - shrinking the ToDo list.
- Modify fs/ntfs/inode.c::ntfs_read_locked_inode() to return an error
code and update callers, i.e. ntfs_iget(), to pass that error code
up instead of just using -EIO.
- Modifications to super.c to ensure that both mount and remount
cannot set any write related options when the driver is compiled
read-only.
- Optimize block resolution in fs/ntfs/aops.c::ntfs_read_block() to
cache the current runlist element. This should improve performance
when reading very large and/or very fragmented data.
2.0.16 - Convert access to $MFT/$BITMAP to attribute inode API.
- Fix a stupid bug introduced in 2.0.15 where we were unmapping the
wrong inode in fs/ntfs/inode.c::ntfs_attr_iget().
- Fix debugging check in fs/ntfs/aops.c::ntfs_read_block().
- Convert $MFT/$BITMAP access to attribute inode API and remove all
remnants of the ugly mftbmp address space and operations hack. This
means we finally have only one readpage function as well as only one
async io completion handler. Yey! The mft bitmap is now just an
attribute inode and is accessed from vol->mftbmp_ino just as if it
were a normal file. Fake inodes rule. (-:
2.0.15 - Fake inodes based attribute i/o via the pagecache, fixes and cleanups.
- Fix silly bug in fs/ntfs/super.c::parse_options() which was causing
remounts to fail when the partition had an entry in /etc/fstab and
the entry specified the nls= option.
- Apply same macro magic used in fs/ntfs/inode.h to fs/ntfs/volume.h to
expand all the helper functions NVolFoo(), NVolSetFoo(), and
NVolClearFoo().
- Move copyright statement from driver initialisation message to
module description (fs/super.c). This makes the initialisation
message fit on one line and fits in better with rest of kernel.
- Update fs/ntfs/attrib.c::map_run_list() to work on both real and
attribute inodes, and both for files and directories.
- Implement fake attribute inodes allowing all attribute i/o to go via
the page cache and to use all the normal vfs/mm functionality:
- Add ntfs_attr_iget() and its helper ntfs_read_locked_attr_inode()
to fs/ntfs/inode.c.
- Add needed cleanup code to ntfs_clear_big_inode().
- Merge address space operations for files and directories (aops.c),
now just have ntfs_aops:
- Rename:
end_buffer_read_attr_async() -> ntfs_end_buffer_read_async(),
ntfs_attr_read_block() -> ntfs_read_block(),
ntfs_file_read_page() -> ntfs_readpage().
- Rewrite fs/ntfs/aops.c::ntfs_readpage() to work on both real and
attribute inodes, and both for files and directories.
- Remove obsolete fs/ntfs/aops.c::ntfs_mst_readpage().
2.0.14 - Run list merging code cleanup, minor locking changes, typo fixes.
- Change fs/ntfs/super.c::ntfs_statfs() to not rely on BKL by moving
the locking out of super.c::get_nr_free_mft_records() and taking and
dropping the mftbmp_lock rw_semaphore in ntfs_statfs() itself.
- Bring attribute runlist merging code (fs/ntfs/attrib.c) in sync with
current userspace ntfs library code. This means that if a merge
fails the original runlists are always left unmodified instead of
being silently corrupted.
- Misc typo fixes.
2.0.13 - Use iget5_locked() in preparation for fake inodes and small cleanups.
- Remove nr_mft_bits and the now superfluous union with nr_mft_records
from ntfs_volume structure.
- Remove nr_lcn_bits and the now superfluous union with nr_clusters
from ntfs_volume structure.
- Use iget5_locked() and friends instead of conventional iget(). Wrap
the call in fs/ntfs/inode.c::ntfs_iget() and update callers of iget()
to use ntfs_iget(). Leave only one iget() call at mount time so we
don't need an ntfs_iget_mount().
- Change fs/ntfs/inode.c::ntfs_new_extent_inode() to take mft_no as an
additional argument.
2.0.12 - Initial cleanup of address space operations following 2.0.11 changes.
- Merge fs/ntfs/aops.c::end_buffer_read_mst_async() and
fs/ntfs/aops.c::end_buffer_read_file_async() into one function
fs/ntfs/aops.c::end_buffer_read_attr_async() using NInoMstProtected()
to determine whether to apply mst fixups or not.
- Above change allows merging fs/ntfs/aops.c::ntfs_file_read_block()
and fs/ntfs/aops.c::ntfs_mst_readpage() into one function
fs/ntfs/aops.c::ntfs_attr_read_block(). Also, create a tiny wrapper
fs/ntfs/aops.c::ntfs_mst_readpage() to transform the parameters from
the VFS readpage function prototype to the ntfs_attr_read_block()
function prototype.
2.0.11 - Initial preparations for fake inode based attribute i/o.
- Move definition of ntfs_inode_state_bits to fs/ntfs/inode.h and
do some macro magic (adapted from include/linux/buffer_head.h) to
expand all the helper functions NInoFoo(), NInoSetFoo(), and
NInoClearFoo().
- Add new flag to ntfs_inode_state_bits: NI_Sparse.
- Add new fields to ntfs_inode structure to allow use of fake inodes
for attribute i/o: type, name, name_len. Also add new state bits:
NI_Attr, which, if set, indicates the inode is a fake inode, and
NI_MstProtected, which, if set, indicates the attribute uses multi
sector transfer protection, i.e. fixups need to be applied after
reads and before/after writes.
- Rename fs/ntfs/inode.c::ntfs_{new,clear,destroy}_inode() to
ntfs_{new,clear,destroy}_extent_inode() and update callers.
- Use ntfs_clear_extent_inode() in fs/ntfs/inode.c::__ntfs_clear_inode()
instead of ntfs_destroy_extent_inode().
- Cleanup memory deallocations in {__,}ntfs_clear_{,big_}inode().
- Make all operations on ntfs inode state bits use the NIno* functions.
- Set up the new ntfs inode fields and state bits in
fs/ntfs/inode.c::ntfs_read_inode() and add appropriate cleanup of
allocated memory to __ntfs_clear_inode().
- Cleanup ntfs_inode structure a bit for better ordering of elements
w.r.t. their size to allow better packing of the structure in memory.
2.0.10 - There can only be 2^32 - 1 inodes on an NTFS volume.
- Add check at mount time to verify that the number of inodes on the
volume does not exceed 2^32 - 1, which is the maximum allowed for
NTFS according to Microsoft.
- Change mft_no member of ntfs_inode structure to be unsigned long.
Update all users. This makes ntfs_inode->mft_no just a copy of struct
inode->i_ino. But we can't just always use struct inode->i_ino and
remove mft_no because extent inodes do not have an attached struct
inode.
2.0.9 - Decompression engine now uses a single buffer and other cleanups.