+
+2.1.28 - Fix a deadlock.
+
+ - Fix deadlock in fs/ntfs/inode.c::ntfs_put_inode(). Thanks to Sergey
+ Vlasov for the report and detailed analysis of the deadlock. The fix
+ involved getting rid of ntfs_put_inode() altogether and hence NTFS no
+ longer has a ->put_inode super operation.
+
+2.1.27 - Various bug fixes and cleanups.
+
+ - Fix two compiler warnings on Alpha. Thanks to Andrew Morton for
+ reporting them.
+ - Fix an (innocent) off-by-one error in the runlist code.
+ - Fix a buggette in an "should be impossible" case handling where we
+ continued the attribute lookup loop instead of aborting it.
+ - Use buffer_migrate_page() for the ->migratepage function of all ntfs
+ address space operations.
+ - Fix comparison of $MFT and $MFTMirr to not bail out when there are
+ unused, invalid mft records which are the same in both $MFT and
+ $MFTMirr.
+ - Add support for sparse files which have a compression unit of 0.
+ - Remove all the make_bad_inode() calls. This should only be called
+ from read inode and new inode code paths.
+ - Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum
+ allowed by NTFS, i.e. 255 Unicode characters, not including the
+ terminating NULL (which is not stored on disk).
+ - Improve comments on file attribute flags in fs/ntfs/layout.h.
+ - Fix a bug in fs/ntfs/inode.c::ntfs_read_locked_index_inode() where we
+ forgot to update a temporary variable so loading index inodes which
+ have an index allocation attribute failed.
+ - Add a missing call to flush_dcache_mft_record_page() in
+ fs/ntfs/inode.c::ntfs_write_inode().
+ - Handle the recently introduced -ENAMETOOLONG return value from
+ fs/ntfs/unistr.c::ntfs_nlstoucs() in fs/ntfs/namei.c::ntfs_lookup().
+ - Semaphore to mutex conversion. (Ingo Molnar)
+
+2.1.26 - Minor bug fixes and updates.
+
+ - Fix a potential overflow in file.c where a cast to s64 was missing in
+ a left shift of a page index.
+ - The struct inode has had its i_sem semaphore changed to a mutex named
+ i_mutex.
+ - We have struct kmem_cache now so use it instead of the typedef
+ kmem_cache_t. (Pekka Enberg)
+ - Implement support for sector sizes above 512 bytes (up to the maximum
+ supported by NTFS which is 4096 bytes).
+ - Do more detailed reporting of why we cannot mount read-write by
+ special casing the VOLUME_MODIFIED_BY_CHKDSK flag.
+ - Miscellaneous updates to layout.h.
+ - Cope with attribute list attribute having invalid flags. Windows
+ copes with this and even chkdsk does not detect or fix this so we
+ have to cope with it, too. Thanks to Pawel Kot for reporting the
+ problem.
+
+2.1.25 - (Almost) fully implement write(2) and truncate(2).
+
+ - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and
+ {__,}ntfs_cluster_free() to also take an optional attribute search
+ context as argument. This allows calling these functions with the
+ mft record mapped. Update all callers.
+ - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock()
+ error handling by passing in the active search context when calling
+ ntfs_cluster_free().
+ - Change ntfs_cluster_alloc() to take an extra boolean parameter
+ specifying whether the cluster are being allocated to extend an
+ attribute or to fill a hole.
+ - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc()
+ with @is_extension set to TRUE and remove the runlist terminator
+ fixup code as this is now done by ntfs_cluster_alloc().
+ - Change ntfs_attr_make_non_resident to take the attribute value size
+ as an extra parameter. This is needed since we need to know the size
+ before we can map the mft record and our callers always know it. The
+ reason we cannot simply read the size from the vfs inode i_size is
+ that this is not necessarily uptodate. This happens when
+ ntfs_attr_make_non_resident() is called in the ->truncate call path.
+ - Fix ntfs_attr_make_non_resident() to update the vfs inode i_blocks
+ which is zero for a resident attribute but should no longer be zero
+ once the attribute is non-resident as it then has real clusters
+ allocated.
+ - Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to
+ extend the allocation of an attributes. Optionally, the data size,
+ but not the initialized size can be extended, too.
+ - Implement fs/ntfs/inode.[hc]::ntfs_truncate(). It only supports
+ uncompressed and unencrypted files and it never creates sparse files
+ at least for the moment (making a file sparse requires us to modify
+ its directory entries and we do not support directory operations at
+ the moment). Also, support for highly fragmented files, i.e. ones
+ whose data attribute is split across multiple extents, is severly
+ limited. When such a case is encountered, EOPNOTSUPP is returned.
+ - Enable ATTR_SIZE attribute changes in ntfs_setattr(). This completes
+ the initial implementation of file truncation. Now both open(2)ing
+ a file with the O_TRUNC flag and the {,f}truncate(2) system calls
+ will resize a file appropriately. The limitations are that only
+ uncompressed and unencrypted files are supported. Also, there is
+ only very limited support for highly fragmented files (the ones whose
+ $DATA attribute is split into multiple attribute extents).
+ - In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited()
+ and cond_resched() in the main loop as we could be dirtying a lot of
+ pages and this ensures we play nice with the VM and the system as a
+ whole.
+ - Implement file operations ->write, ->aio_write, ->writev for regular
+ files. This replaces the old use of generic_file_write(), et al and
+ the address space operations ->prepare_write and ->commit_write.
+ This means that both sparse and non-sparse (unencrypted and
+ uncompressed) files can now be extended using the normal write(2)
+ code path. There are two limitations at present and these are that
+ we never create sparse files and that we only have limited support
+ for highly fragmented files, i.e. ones whose data attribute is split
+ across multiple extents. When such a case is encountered,
+ EOPNOTSUPP is returned.
+ - $EA attributes can be both resident and non-resident.
+ - Use %z for size_t to fix compilation warnings. (Andrew Morton)
+ - Fix compilation warnings with gcc-4.0.2 on SUSE 10.0.
+ - Document extended attribute ($EA) NEED_EA flag. (Based on libntfs
+ patch by Yura Pakhuchiy.)
+
+2.1.24 - Lots of bug fixes and support more clean journal states.
+
+ - Support journals ($LogFile) which have been modified by chkdsk. This
+ means users can boot into Windows after we marked the volume dirty.
+ The Windows boot will run chkdsk and then reboot. The user can then
+ immediately boot into Linux rather than having to do a full Windows
+ boot first before rebooting into Linux and we will recognize such a
+ journal and empty it as it is clean by definition. Note, this only
+ works if chkdsk left the journal in an obviously clean state.
+ - Support journals ($LogFile) with only one restart page as well as
+ journals with two different restart pages. We sanity check both and
+ either use the only sane one or the more recent one of the two in the
+ case that both are valid.
+ - Add fs/ntfs/malloc.h::ntfs_malloc_nofs_nofail() which is analogous to
+ ntfs_malloc_nofs() but it performs allocations with __GFP_NOFAIL and
+ hence cannot fail.
+ - Use ntfs_malloc_nofs_nofail() in the two critical regions in
+ fs/ntfs/runlist.c::ntfs_runlists_merge(). This means we no longer
+ need to panic() if the allocation fails as it now cannot fail.
+ - Fix two nasty runlist merging bugs that had gone unnoticed so far.
+ Thanks to Stefano Picerno for the bug report.
+ - Remove two bogus BUG_ON()s from fs/ntfs/mft.c.
+ - Fix handling of valid but empty mapping pairs array in
+ fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress().
+ - Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING
+ messages and include the inode number. Thanks to Yura Pakhuchiy for
+ pointing this out.
+ - Change ntfs_rl_truncate_nolock() to throw away the runlist if the new
+ length is zero.
+ - Add runlist.[hc]::ntfs_rl_punch_nolock() which punches a caller
+ specified hole into a runlist.
+ - Fix a bug in fs/ntfs/index.c::ntfs_index_lookup(). When the returned
+ index entry is in the index root, we forgot to set the @ir pointer in
+ the index context. Thanks to Yura Pakhuchiy for finding this bug.
+ - Remove bogus setting of PageError in ntfs_read_compressed_block().
+ - Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
+ - Fix a bug in ntfs_map_runlist_nolock() where we forgot to protect
+ access to the allocated size in the ntfs inode with the size lock.
+ - Fix ntfs_attr_vcn_to_lcn_nolock() and ntfs_attr_find_vcn_nolock() to
+ return LCN_ENOENT when there is no runlist and the allocated size is
+ zero.
+ - Fix load_attribute_list() to handle the case of a NULL runlist.
+ - Fix handling of sparse attributes in ntfs_attr_make_non_resident().
+ - Add BUG() checks to ntfs_attr_make_non_resident() and ntfs_attr_set()
+ to ensure that these functions are never called for compressed or
+ encrypted attributes.
+ - Fix cluster (de)allocators to work when the runlist is NULL and more
+ importantly to take a locked runlist rather than them locking it
+ which leads to lock reversal.
+ - Truncate {a,c,m}time to the ntfs supported time granularity when
+ updating the times in the inode in ntfs_setattr().
+ - Fixup handling of sparse, compressed, and encrypted attributes in
+ fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode(),
+ fs/ntfs/aops.c::ntfs_{read,write}page().
+ - Make ntfs_write_block() not instantiate sparse blocks if they contain
+ only zeroes.
+ - Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
+ lock protection over the buffer submission for i/o which allows the
+ removal of the get_bh()/put_bh() pairs for each buffer.
+ - Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
+ where a concurrent truncate has truncated the runlist under our feet.
+ - Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c.
+ - In fs/ntfs/aops.c::ntfs_end_buffer_async_read(), use a bit spin lock
+ in the first buffer head instead of a driver global spin lock to
+ improve scalability.
+ - Minor fix to error handling and error message display in
+ fs/ntfs/aops.c::ntfs_prepare_nonresident_write().
+ - Change the mount options {u,f,d}mask to always parse the number as
+ an octal number to conform to how chmod(1) works, too. Thanks to
+ Giuseppe Bilotta and Horst von Brand for pointing out the errors of
+ my ways.
+ - Fix various bugs in the runlist merging code. (Based on libntfs
+ changes by Richard Russon.)
+ - Fix sparse warnings that have crept in over time.
+ - Change ntfs_cluster_free() to require a write locked runlist on entry
+ since we otherwise get into a lock reversal deadlock if a read locked
+ runlist is passed in. In the process also change it to take an ntfs
+ inode instead of a vfs inode as parameter.
+ - Fix the definition of the CHKD ntfs record magic. It had an off by
+ two error causing it to be CHKB instead of CHKD.
+ - Fix a stupid bug in __ntfs_bitmap_set_bits_in_run() which caused the
+ count to become negative and hence we had a wild memset() scribbling
+ all over the system's ram.
+
+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_mutex 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.