diff options
| -rw-r--r-- | fs/ntfs/ChangeLog | 28 | ||||
| -rw-r--r-- | fs/ntfs/inode.c | 49 | ||||
| -rw-r--r-- | fs/ntfs/layout.h | 25 | 
3 files changed, 76 insertions, 26 deletions
| diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 02f44094bda9..4a62201e8441 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | ToDo/Notes: | 1 | ToDo/Notes: | 
| 2 | - Find and fix bugs. | 2 | - Find and fix bugs. | 
| 3 | - The only places in the kernel where a file is resized are | 3 | - The only places in the kernel where a file is resized are | 
| 4 | ntfs_file_write*() and ntfs_truncate() for both of which i_sem is | 4 | ntfs_file_write*() and ntfs_truncate() for both of which i_mutex is | 
| 5 | held. Just have to be careful in read-/writepage and other helpers | 5 | held. Just have to be careful in read-/writepage and other helpers | 
| 6 | not running under i_sem that we play nice... Also need to be careful | 6 | not running under i_mutex that we play nice. Also need to be careful | 
| 7 | with initialized_size extension in ntfs_file_write*() and writepage. | 7 | with initialized_size extension in ntfs_file_write*() and writepage. | 
| 8 | UPDATE: The only things that need to be checked are the compressed | 8 | UPDATE: The only things that need to be checked are the compressed | 
| 9 | write and the other attribute resize/write cases like index | 9 | write and the other attribute resize/write cases like index | 
| @@ -19,6 +19,16 @@ ToDo/Notes: | |||
| 19 | - Enable the code for setting the NT4 compatibility flag when we start | 19 | - Enable the code for setting the NT4 compatibility flag when we start | 
| 20 | making NTFS 1.2 specific modifications. | 20 | making NTFS 1.2 specific modifications. | 
| 21 | 21 | ||
| 22 | 2.1.26 - Minor bug fixes and updates. | ||
| 23 | |||
| 24 | - We have struct kmem_cache now so use it instead of the typedef | ||
| 25 | kmem_cache_t. (Pekka Enberg) | ||
| 26 | - Miscellaneous updates to layout.h. | ||
| 27 | - Cope with attribute list attribute having invalid flags. Windows | ||
| 28 | copes with this and even chkdsk does not detect or fix this so we | ||
| 29 | have to cope with it, too. Thanks to Pawel Kot for reporting the | ||
| 30 | problem. | ||
| 31 | |||
| 22 | 2.1.25 - (Almost) fully implement write(2) and truncate(2). | 32 | 2.1.25 - (Almost) fully implement write(2) and truncate(2). | 
| 23 | 33 | ||
| 24 | - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and | 34 | - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and | 
| @@ -373,7 +383,7 @@ ToDo/Notes: | |||
| 373 | single one of them had an mst error. (Thanks to Ken MacFerrin for | 383 | single one of them had an mst error. (Thanks to Ken MacFerrin for | 
| 374 | the bug report.) | 384 | the bug report.) | 
| 375 | - Fix error handling in fs/ntfs/quota.c::ntfs_mark_quotas_out_of_date() | 385 | - Fix error handling in fs/ntfs/quota.c::ntfs_mark_quotas_out_of_date() | 
| 376 | where we failed to release i_sem on the $Quota/$Q attribute inode. | 386 | where we failed to release i_mutex on the $Quota/$Q attribute inode. | 
| 377 | - Fix bug in handling of bad inodes in fs/ntfs/namei.c::ntfs_lookup(). | 387 | - Fix bug in handling of bad inodes in fs/ntfs/namei.c::ntfs_lookup(). | 
| 378 | - Add mapping of unmapped buffers to all remaining code paths, i.e. | 388 | - Add mapping of unmapped buffers to all remaining code paths, i.e. | 
| 379 | fs/ntfs/aops.c::ntfs_write_mst_block(), mft.c::ntfs_sync_mft_mirror(), | 389 | fs/ntfs/aops.c::ntfs_write_mst_block(), mft.c::ntfs_sync_mft_mirror(), | 
| @@ -874,7 +884,7 @@ ToDo/Notes: | |||
| 874 | clusters. (Philipp Thomas) | 884 | clusters. (Philipp Thomas) | 
| 875 | - attrib.c::load_attribute_list(): Fix bug when initialized_size is a | 885 | - attrib.c::load_attribute_list(): Fix bug when initialized_size is a | 
| 876 | multiple of the block_size but not the cluster size. (Szabolcs | 886 | multiple of the block_size but not the cluster size. (Szabolcs | 
| 877 | Szakacsits <szaka@sienet.hu>) | 887 | Szakacsits) | 
| 878 | 888 | ||
| 879 | 2.1.2 - Important bug fixes aleviating the hangs in statfs. | 889 | 2.1.2 - Important bug fixes aleviating the hangs in statfs. | 
| 880 | 890 | ||
| @@ -884,7 +894,7 @@ ToDo/Notes: | |||
| 884 | 894 | ||
| 885 | - Add handling for initialized_size != data_size in compressed files. | 895 | - Add handling for initialized_size != data_size in compressed files. | 
| 886 | - Reduce function local stack usage from 0x3d4 bytes to just noise in | 896 | - Reduce function local stack usage from 0x3d4 bytes to just noise in | 
| 887 | fs/ntfs/upcase.c. (Randy Dunlap <rdunlap@xenotime.net>) | 897 | fs/ntfs/upcase.c. (Randy Dunlap) | 
| 888 | - Remove compiler warnings for newer gcc. | 898 | - Remove compiler warnings for newer gcc. | 
| 889 | - Pages are no longer kmapped by mm/filemap.c::generic_file_write() | 899 | - Pages are no longer kmapped by mm/filemap.c::generic_file_write() | 
| 890 | around calls to ->{prepare,commit}_write. Adapt NTFS appropriately | 900 | around calls to ->{prepare,commit}_write. Adapt NTFS appropriately | 
| @@ -1201,11 +1211,11 @@ ToDo/Notes: | |||
| 1201 | the kernel. We probably want a kernel generic init_address_space() | 1211 | the kernel. We probably want a kernel generic init_address_space() | 
| 1202 | function... | 1212 | function... | 
| 1203 | - Drop BKL from ntfs_readdir() after consultation with Al Viro. The | 1213 | - Drop BKL from ntfs_readdir() after consultation with Al Viro. The | 
| 1204 | only caller of ->readdir() is vfs_readdir() which holds i_sem during | 1214 | only caller of ->readdir() is vfs_readdir() which holds i_mutex | 
| 1205 | the call, and i_sem is sufficient protection against changes in the | 1215 | during the call, and i_mutex is sufficient protection against changes | 
| 1206 | directory inode (including ->i_size). | 1216 | in the directory inode (including ->i_size). | 
| 1207 | - Use generic_file_llseek() for directories (as opposed to | 1217 | - Use generic_file_llseek() for directories (as opposed to | 
| 1208 | default_llseek()) as this downs i_sem instead of the BKL which is | 1218 | default_llseek()) as this downs i_mutex instead of the BKL which is | 
| 1209 | what we now need for exclusion against ->f_pos changes considering we | 1219 | what we now need for exclusion against ->f_pos changes considering we | 
| 1210 | no longer take the BKL in ntfs_readdir(). | 1220 | no longer take the BKL in ntfs_readdir(). | 
| 1211 | 1221 | ||
| diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index ea1bd3feea1b..55263b7de9c0 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
| @@ -677,13 +677,28 @@ static int ntfs_read_locked_inode(struct inode *vi) | |||
| 677 | ntfs_debug("Attribute list found in inode 0x%lx.", vi->i_ino); | 677 | ntfs_debug("Attribute list found in inode 0x%lx.", vi->i_ino); | 
| 678 | NInoSetAttrList(ni); | 678 | NInoSetAttrList(ni); | 
| 679 | a = ctx->attr; | 679 | a = ctx->attr; | 
| 680 | if (a->flags & ATTR_IS_ENCRYPTED || | 680 | if (a->flags & ATTR_COMPRESSION_MASK) { | 
| 681 | a->flags & ATTR_COMPRESSION_MASK || | ||
| 682 | a->flags & ATTR_IS_SPARSE) { | ||
| 683 | ntfs_error(vi->i_sb, "Attribute list attribute is " | 681 | ntfs_error(vi->i_sb, "Attribute list attribute is " | 
| 684 | "compressed/encrypted/sparse."); | 682 | "compressed."); | 
| 685 | goto unm_err_out; | 683 | goto unm_err_out; | 
| 686 | } | 684 | } | 
| 685 | if (a->flags & ATTR_IS_ENCRYPTED || | ||
| 686 | a->flags & ATTR_IS_SPARSE) { | ||
| 687 | if (a->non_resident) { | ||
| 688 | ntfs_error(vi->i_sb, "Non-resident attribute " | ||
| 689 | "list attribute is encrypted/" | ||
| 690 | "sparse."); | ||
| 691 | goto unm_err_out; | ||
| 692 | } | ||
| 693 | ntfs_warning(vi->i_sb, "Resident attribute list " | ||
| 694 | "attribute in inode 0x%lx is marked " | ||
| 695 | "encrypted/sparse which is not true. " | ||
| 696 | "However, Windows allows this and " | ||
| 697 | "chkdsk does not detect or correct it " | ||
| 698 | "so we will just ignore the invalid " | ||
| 699 | "flags and pretend they are not set.", | ||
| 700 | vi->i_ino); | ||
| 701 | } | ||
| 687 | /* Now allocate memory for the attribute list. */ | 702 | /* Now allocate memory for the attribute list. */ | 
| 688 | ni->attr_list_size = (u32)ntfs_attr_size(a); | 703 | ni->attr_list_size = (u32)ntfs_attr_size(a); | 
| 689 | ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size); | 704 | ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size); | 
| @@ -1809,19 +1824,33 @@ int ntfs_read_inode_mount(struct inode *vi) | |||
| 1809 | } else /* if (!err) */ { | 1824 | } else /* if (!err) */ { | 
| 1810 | ATTR_LIST_ENTRY *al_entry, *next_al_entry; | 1825 | ATTR_LIST_ENTRY *al_entry, *next_al_entry; | 
| 1811 | u8 *al_end; | 1826 | u8 *al_end; | 
| 1827 | static const char *es = " Not allowed. $MFT is corrupt. " | ||
| 1828 | "You should run chkdsk."; | ||
| 1812 | 1829 | ||
| 1813 | ntfs_debug("Attribute list attribute found in $MFT."); | 1830 | ntfs_debug("Attribute list attribute found in $MFT."); | 
| 1814 | NInoSetAttrList(ni); | 1831 | NInoSetAttrList(ni); | 
| 1815 | a = ctx->attr; | 1832 | a = ctx->attr; | 
| 1816 | if (a->flags & ATTR_IS_ENCRYPTED || | 1833 | if (a->flags & ATTR_COMPRESSION_MASK) { | 
| 1817 | a->flags & ATTR_COMPRESSION_MASK || | ||
| 1818 | a->flags & ATTR_IS_SPARSE) { | ||
| 1819 | ntfs_error(sb, "Attribute list attribute is " | 1834 | ntfs_error(sb, "Attribute list attribute is " | 
| 1820 | "compressed/encrypted/sparse. Not " | 1835 | "compressed.%s", es); | 
| 1821 | "allowed. $MFT is corrupt. You should " | ||
| 1822 | "run chkdsk."); | ||
| 1823 | goto put_err_out; | 1836 | goto put_err_out; | 
| 1824 | } | 1837 | } | 
| 1838 | if (a->flags & ATTR_IS_ENCRYPTED || | ||
| 1839 | a->flags & ATTR_IS_SPARSE) { | ||
| 1840 | if (a->non_resident) { | ||
| 1841 | ntfs_error(sb, "Non-resident attribute list " | ||
| 1842 | "attribute is encrypted/" | ||
| 1843 | "sparse.%s", es); | ||
| 1844 | goto put_err_out; | ||
| 1845 | } | ||
| 1846 | ntfs_warning(sb, "Resident attribute list attribute " | ||
| 1847 | "in $MFT system file is marked " | ||
| 1848 | "encrypted/sparse which is not true. " | ||
| 1849 | "However, Windows allows this and " | ||
| 1850 | "chkdsk does not detect or correct it " | ||
| 1851 | "so we will just ignore the invalid " | ||
| 1852 | "flags and pretend they are not set."); | ||
| 1853 | } | ||
| 1825 | /* Now allocate memory for the attribute list. */ | 1854 | /* Now allocate memory for the attribute list. */ | 
| 1826 | ni->attr_list_size = (u32)ntfs_attr_size(a); | 1855 | ni->attr_list_size = (u32)ntfs_attr_size(a); | 
| 1827 | ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size); | 1856 | ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size); | 
| diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h index f5678d5d7919..bb408d4dcbb0 100644 --- a/fs/ntfs/layout.h +++ b/fs/ntfs/layout.h | |||
| @@ -838,15 +838,19 @@ enum { | |||
| 838 | F_A_DEVICE, F_A_DIRECTORY, F_A_SPARSE_FILE, F_A_REPARSE_POINT, | 838 | F_A_DEVICE, F_A_DIRECTORY, F_A_SPARSE_FILE, F_A_REPARSE_POINT, | 
| 839 | F_A_COMPRESSED, and F_A_ENCRYPTED and preserves the rest. This mask | 839 | F_A_COMPRESSED, and F_A_ENCRYPTED and preserves the rest. This mask | 
| 840 | is used to to obtain all flags that are valid for setting. */ | 840 | is used to to obtain all flags that are valid for setting. */ | 
| 841 | |||
| 842 | /* | 841 | /* | 
| 843 | * The following flags are only present in the FILE_NAME attribute (in | 842 | * The following flag is only present in the FILE_NAME attribute (in | 
| 844 | * the field file_attributes). | 843 | * the field file_attributes). | 
| 845 | */ | 844 | */ | 
| 846 | FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT = const_cpu_to_le32(0x10000000), | 845 | FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT = const_cpu_to_le32(0x10000000), | 
| 847 | /* Note, this is a copy of the corresponding bit from the mft record, | 846 | /* Note, this is a copy of the corresponding bit from the mft record, | 
| 848 | telling us whether this is a directory or not, i.e. whether it has | 847 | telling us whether this is a directory or not, i.e. whether it has | 
| 849 | an index root attribute or not. */ | 848 | an index root attribute or not. */ | 
| 849 | /* | ||
| 850 | * The following flag is present both in the STANDARD_INFORMATION | ||
| 851 | * attribute and in the FILE_NAME attribute (in the field | ||
| 852 | * file_attributes). | ||
| 853 | */ | ||
| 850 | FILE_ATTR_DUP_VIEW_INDEX_PRESENT = const_cpu_to_le32(0x20000000), | 854 | FILE_ATTR_DUP_VIEW_INDEX_PRESENT = const_cpu_to_le32(0x20000000), | 
| 851 | /* Note, this is a copy of the corresponding bit from the mft record, | 855 | /* Note, this is a copy of the corresponding bit from the mft record, | 
| 852 | telling us whether this file has a view index present (eg. object id | 856 | telling us whether this file has a view index present (eg. object id | 
| @@ -1071,9 +1075,15 @@ typedef struct { | |||
| 1071 | modified. */ | 1075 | modified. */ | 
| 1072 | /* 20*/ sle64 last_access_time; /* Time this mft record was last | 1076 | /* 20*/ sle64 last_access_time; /* Time this mft record was last | 
| 1073 | accessed. */ | 1077 | accessed. */ | 
| 1074 | /* 28*/ sle64 allocated_size; /* Byte size of allocated space for the | 1078 | /* 28*/ sle64 allocated_size; /* Byte size of on-disk allocated space | 
| 1075 | data attribute. NOTE: Is a multiple | 1079 | for the data attribute. So for | 
| 1076 | of the cluster size. */ | 1080 | normal $DATA, this is the | 
| 1081 | allocated_size from the unnamed | ||
| 1082 | $DATA attribute and for compressed | ||
| 1083 | and/or sparse $DATA, this is the | ||
| 1084 | compressed_size from the unnamed | ||
| 1085 | $DATA attribute. NOTE: This is a | ||
| 1086 | multiple of the cluster size. */ | ||
| 1077 | /* 30*/ sle64 data_size; /* Byte size of actual data in data | 1087 | /* 30*/ sle64 data_size; /* Byte size of actual data in data | 
| 1078 | attribute. */ | 1088 | attribute. */ | 
| 1079 | /* 38*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */ | 1089 | /* 38*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */ | 
| @@ -1904,12 +1914,13 @@ enum { | |||
| 1904 | VOLUME_DELETE_USN_UNDERWAY = const_cpu_to_le16(0x0010), | 1914 | VOLUME_DELETE_USN_UNDERWAY = const_cpu_to_le16(0x0010), | 
| 1905 | VOLUME_REPAIR_OBJECT_ID = const_cpu_to_le16(0x0020), | 1915 | VOLUME_REPAIR_OBJECT_ID = const_cpu_to_le16(0x0020), | 
| 1906 | 1916 | ||
| 1917 | VOLUME_CHKDSK_UNDERWAY = const_cpu_to_le16(0x4000), | ||
| 1907 | VOLUME_MODIFIED_BY_CHKDSK = const_cpu_to_le16(0x8000), | 1918 | VOLUME_MODIFIED_BY_CHKDSK = const_cpu_to_le16(0x8000), | 
| 1908 | 1919 | ||
| 1909 | VOLUME_FLAGS_MASK = const_cpu_to_le16(0x803f), | 1920 | VOLUME_FLAGS_MASK = const_cpu_to_le16(0xc03f), | 
| 1910 | 1921 | ||
| 1911 | /* To make our life easier when checking if we must mount read-only. */ | 1922 | /* To make our life easier when checking if we must mount read-only. */ | 
| 1912 | VOLUME_MUST_MOUNT_RO_MASK = const_cpu_to_le16(0x8027), | 1923 | VOLUME_MUST_MOUNT_RO_MASK = const_cpu_to_le16(0xc027), | 
| 1913 | } __attribute__ ((__packed__)); | 1924 | } __attribute__ ((__packed__)); | 
| 1914 | 1925 | ||
| 1915 | typedef le16 VOLUME_FLAGS; | 1926 | typedef le16 VOLUME_FLAGS; | 
