diff options
Diffstat (limited to 'fs')
-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; |