Loading Documentation/filesystems/ntfs.txt +6 −0 Original line number Diff line number Diff line Loading @@ -457,6 +457,12 @@ ChangeLog Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. 2.1.26: - Implement support for sector sizes above 512 bytes (up to the maximum supported by NTFS which is 4096 bytes). - Enhance support for NTFS volumes which were supported by Windows but not by Linux due to invalid attribute list attribute flags. - A few minor updates and bug fixes. 2.1.25: - Write support is now extended with write(2) being able to both overwrite existing file data and to extend files. Also, if a write Loading fs/ntfs/ChangeLog +27 −9 Original line number Diff line number Diff line ToDo/Notes: - Find and fix bugs. - The only places in the kernel where a file is resized are ntfs_file_write*() and ntfs_truncate() for both of which i_sem is ntfs_file_write*() and ntfs_truncate() for both of which i_mutex is held. Just have to be careful in read-/writepage and other helpers not running under i_sem that we play nice... Also need to be careful not running under i_mutex that we play nice. Also need to be careful with initialized_size extension in ntfs_file_write*() and writepage. UPDATE: The only things that need to be checked are the compressed write and the other attribute resize/write cases like index Loading @@ -19,6 +19,24 @@ ToDo/Notes: - Enable the code for setting the NT4 compatibility flag when we start making NTFS 1.2 specific modifications. 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 Loading Loading @@ -373,7 +391,7 @@ ToDo/Notes: 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. 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(), Loading Loading @@ -874,7 +892,7 @@ ToDo/Notes: 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>) Szakacsits) 2.1.2 - Important bug fixes aleviating the hangs in statfs. Loading @@ -884,7 +902,7 @@ ToDo/Notes: - 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 <rdunlap@xenotime.net>) fs/ntfs/upcase.c. (Randy Dunlap) - 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 Loading Loading @@ -1201,11 +1219,11 @@ ToDo/Notes: the kernel. We probably want a kernel generic init_address_space() function... - Drop BKL from ntfs_readdir() after consultation with Al Viro. The only caller of ->readdir() is vfs_readdir() which holds i_sem during the call, and i_sem is sufficient protection against changes in the directory inode (including ->i_size). only caller of ->readdir() is vfs_readdir() which holds i_mutex during the call, and i_mutex is sufficient protection against changes in the directory inode (including ->i_size). - Use generic_file_llseek() for directories (as opposed to default_llseek()) as this downs i_sem instead of the BKL which is default_llseek()) as this downs i_mutex instead of the BKL which is what we now need for exclusion against ->f_pos changes considering we no longer take the BKL in ntfs_readdir(). Loading fs/ntfs/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \ index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ unistr.o upcase.o EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.26\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG Loading fs/ntfs/aops.c +8 −10 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ * aops.c - NTFS kernel address space operations and page cache handling. * Part of the Linux-NTFS project. * * Copyright (c) 2001-2005 Anton Altaparmakov * Copyright (c) 2001-2006 Anton Altaparmakov * Copyright (c) 2002 Richard Russon * * This program/include file is free software; you can redistribute it and/or Loading Loading @@ -200,8 +200,8 @@ static int ntfs_read_block(struct page *page) /* $MFT/$DATA must have its complete runlist in memory at all times. */ BUG_ON(!ni->runlist.rl && !ni->mft_no && !NInoAttr(ni)); blocksize_bits = VFS_I(ni)->i_blkbits; blocksize = 1 << blocksize_bits; blocksize = vol->sb->s_blocksize; blocksize_bits = vol->sb->s_blocksize_bits; if (!page_has_buffers(page)) { create_empty_buffers(page, blocksize, 0); Loading Loading @@ -569,10 +569,8 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) BUG_ON(!NInoNonResident(ni)); BUG_ON(NInoMstProtected(ni)); blocksize_bits = vi->i_blkbits; blocksize = 1 << blocksize_bits; blocksize = vol->sb->s_blocksize; blocksize_bits = vol->sb->s_blocksize_bits; if (!page_has_buffers(page)) { BUG_ON(!PageUptodate(page)); create_empty_buffers(page, blocksize, Loading Loading @@ -949,8 +947,8 @@ static int ntfs_write_mst_block(struct page *page, */ BUG_ON(!(is_mft || S_ISDIR(vi->i_mode) || (NInoAttr(ni) && ni->type == AT_INDEX_ALLOCATION))); bh_size_bits = vi->i_blkbits; bh_size = 1 << bh_size_bits; bh_size = vol->sb->s_blocksize; bh_size_bits = vol->sb->s_blocksize_bits; max_bhs = PAGE_CACHE_SIZE / bh_size; BUG_ON(!max_bhs); BUG_ON(max_bhs > MAX_BUF_PER_PAGE); Loading Loading @@ -1596,7 +1594,7 @@ void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs) { BUG_ON(!PageUptodate(page)); end = ofs + ni->itype.index.block_size; bh_size = 1 << VFS_I(ni)->i_blkbits; bh_size = VFS_I(ni)->i_sb->s_blocksize; spin_lock(&mapping->private_lock); if (unlikely(!page_has_buffers(page))) { spin_unlock(&mapping->private_lock); Loading fs/ntfs/file.c +5 −5 Original line number Diff line number Diff line /* * file.c - NTFS kernel file operations. Part of the Linux-NTFS project. * * Copyright (c) 2001-2005 Anton Altaparmakov * Copyright (c) 2001-2006 Anton Altaparmakov * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published Loading Loading @@ -248,7 +248,7 @@ do_non_resident_extend: * enough to make ntfs_writepage() work. */ write_lock_irqsave(&ni->size_lock, flags); ni->initialized_size = (index + 1) << PAGE_CACHE_SHIFT; ni->initialized_size = (s64)(index + 1) << PAGE_CACHE_SHIFT; if (ni->initialized_size > new_init_size) ni->initialized_size = new_init_size; write_unlock_irqrestore(&ni->size_lock, flags); Loading Loading @@ -529,8 +529,8 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.", vi->i_ino, ni->type, pages[0]->index, nr_pages, (long long)pos, bytes); blocksize_bits = vi->i_blkbits; blocksize = 1 << blocksize_bits; blocksize = vol->sb->s_blocksize; blocksize_bits = vol->sb->s_blocksize_bits; u = 0; do { struct page *page = pages[u]; Loading Loading @@ -1525,7 +1525,7 @@ static inline int ntfs_commit_pages_after_non_resident_write( vi = pages[0]->mapping->host; ni = NTFS_I(vi); blocksize = 1 << vi->i_blkbits; blocksize = vi->i_sb->s_blocksize; end = pos + bytes; u = 0; do { Loading Loading
Documentation/filesystems/ntfs.txt +6 −0 Original line number Diff line number Diff line Loading @@ -457,6 +457,12 @@ ChangeLog Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. 2.1.26: - Implement support for sector sizes above 512 bytes (up to the maximum supported by NTFS which is 4096 bytes). - Enhance support for NTFS volumes which were supported by Windows but not by Linux due to invalid attribute list attribute flags. - A few minor updates and bug fixes. 2.1.25: - Write support is now extended with write(2) being able to both overwrite existing file data and to extend files. Also, if a write Loading
fs/ntfs/ChangeLog +27 −9 Original line number Diff line number Diff line ToDo/Notes: - Find and fix bugs. - The only places in the kernel where a file is resized are ntfs_file_write*() and ntfs_truncate() for both of which i_sem is ntfs_file_write*() and ntfs_truncate() for both of which i_mutex is held. Just have to be careful in read-/writepage and other helpers not running under i_sem that we play nice... Also need to be careful not running under i_mutex that we play nice. Also need to be careful with initialized_size extension in ntfs_file_write*() and writepage. UPDATE: The only things that need to be checked are the compressed write and the other attribute resize/write cases like index Loading @@ -19,6 +19,24 @@ ToDo/Notes: - Enable the code for setting the NT4 compatibility flag when we start making NTFS 1.2 specific modifications. 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 Loading Loading @@ -373,7 +391,7 @@ ToDo/Notes: 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. 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(), Loading Loading @@ -874,7 +892,7 @@ ToDo/Notes: 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>) Szakacsits) 2.1.2 - Important bug fixes aleviating the hangs in statfs. Loading @@ -884,7 +902,7 @@ ToDo/Notes: - 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 <rdunlap@xenotime.net>) fs/ntfs/upcase.c. (Randy Dunlap) - 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 Loading Loading @@ -1201,11 +1219,11 @@ ToDo/Notes: the kernel. We probably want a kernel generic init_address_space() function... - Drop BKL from ntfs_readdir() after consultation with Al Viro. The only caller of ->readdir() is vfs_readdir() which holds i_sem during the call, and i_sem is sufficient protection against changes in the directory inode (including ->i_size). only caller of ->readdir() is vfs_readdir() which holds i_mutex during the call, and i_mutex is sufficient protection against changes in the directory inode (including ->i_size). - Use generic_file_llseek() for directories (as opposed to default_llseek()) as this downs i_sem instead of the BKL which is default_llseek()) as this downs i_mutex instead of the BKL which is what we now need for exclusion against ->f_pos changes considering we no longer take the BKL in ntfs_readdir(). Loading
fs/ntfs/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \ index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ unistr.o upcase.o EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.26\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG Loading
fs/ntfs/aops.c +8 −10 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ * aops.c - NTFS kernel address space operations and page cache handling. * Part of the Linux-NTFS project. * * Copyright (c) 2001-2005 Anton Altaparmakov * Copyright (c) 2001-2006 Anton Altaparmakov * Copyright (c) 2002 Richard Russon * * This program/include file is free software; you can redistribute it and/or Loading Loading @@ -200,8 +200,8 @@ static int ntfs_read_block(struct page *page) /* $MFT/$DATA must have its complete runlist in memory at all times. */ BUG_ON(!ni->runlist.rl && !ni->mft_no && !NInoAttr(ni)); blocksize_bits = VFS_I(ni)->i_blkbits; blocksize = 1 << blocksize_bits; blocksize = vol->sb->s_blocksize; blocksize_bits = vol->sb->s_blocksize_bits; if (!page_has_buffers(page)) { create_empty_buffers(page, blocksize, 0); Loading Loading @@ -569,10 +569,8 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) BUG_ON(!NInoNonResident(ni)); BUG_ON(NInoMstProtected(ni)); blocksize_bits = vi->i_blkbits; blocksize = 1 << blocksize_bits; blocksize = vol->sb->s_blocksize; blocksize_bits = vol->sb->s_blocksize_bits; if (!page_has_buffers(page)) { BUG_ON(!PageUptodate(page)); create_empty_buffers(page, blocksize, Loading Loading @@ -949,8 +947,8 @@ static int ntfs_write_mst_block(struct page *page, */ BUG_ON(!(is_mft || S_ISDIR(vi->i_mode) || (NInoAttr(ni) && ni->type == AT_INDEX_ALLOCATION))); bh_size_bits = vi->i_blkbits; bh_size = 1 << bh_size_bits; bh_size = vol->sb->s_blocksize; bh_size_bits = vol->sb->s_blocksize_bits; max_bhs = PAGE_CACHE_SIZE / bh_size; BUG_ON(!max_bhs); BUG_ON(max_bhs > MAX_BUF_PER_PAGE); Loading Loading @@ -1596,7 +1594,7 @@ void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs) { BUG_ON(!PageUptodate(page)); end = ofs + ni->itype.index.block_size; bh_size = 1 << VFS_I(ni)->i_blkbits; bh_size = VFS_I(ni)->i_sb->s_blocksize; spin_lock(&mapping->private_lock); if (unlikely(!page_has_buffers(page))) { spin_unlock(&mapping->private_lock); Loading
fs/ntfs/file.c +5 −5 Original line number Diff line number Diff line /* * file.c - NTFS kernel file operations. Part of the Linux-NTFS project. * * Copyright (c) 2001-2005 Anton Altaparmakov * Copyright (c) 2001-2006 Anton Altaparmakov * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published Loading Loading @@ -248,7 +248,7 @@ do_non_resident_extend: * enough to make ntfs_writepage() work. */ write_lock_irqsave(&ni->size_lock, flags); ni->initialized_size = (index + 1) << PAGE_CACHE_SHIFT; ni->initialized_size = (s64)(index + 1) << PAGE_CACHE_SHIFT; if (ni->initialized_size > new_init_size) ni->initialized_size = new_init_size; write_unlock_irqrestore(&ni->size_lock, flags); Loading Loading @@ -529,8 +529,8 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.", vi->i_ino, ni->type, pages[0]->index, nr_pages, (long long)pos, bytes); blocksize_bits = vi->i_blkbits; blocksize = 1 << blocksize_bits; blocksize = vol->sb->s_blocksize; blocksize_bits = vol->sb->s_blocksize_bits; u = 0; do { struct page *page = pages[u]; Loading Loading @@ -1525,7 +1525,7 @@ static inline int ntfs_commit_pages_after_non_resident_write( vi = pages[0]->mapping->host; ni = NTFS_I(vi); blocksize = 1 << vi->i_blkbits; blocksize = vi->i_sb->s_blocksize; end = pos + bytes; u = 0; do { Loading