diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-24 17:36:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-24 17:36:42 -0500 |
commit | 2cb5b6beef3a3357ef1f2a580d5e2284516efc39 (patch) | |
tree | 8f9e12f91652c510632cb9965f2c4b92d2b19717 /fs | |
parent | 329dda083e496bc5ffbb4b1973243bd8a9420e24 (diff) | |
parent | 1cf3109ffb26a6ea572fd02436bd10458b4b2187 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ntfs/ChangeLog | 36 | ||||
-rw-r--r-- | fs/ntfs/Makefile | 2 | ||||
-rw-r--r-- | fs/ntfs/aops.c | 18 | ||||
-rw-r--r-- | fs/ntfs/file.c | 10 | ||||
-rw-r--r-- | fs/ntfs/inode.c | 49 | ||||
-rw-r--r-- | fs/ntfs/layout.h | 25 | ||||
-rw-r--r-- | fs/ntfs/mft.c | 8 | ||||
-rw-r--r-- | fs/ntfs/ntfs.h | 10 | ||||
-rw-r--r-- | fs/ntfs/super.c | 197 | ||||
-rw-r--r-- | fs/ntfs/upcase.c | 10 | ||||
-rw-r--r-- | fs/ntfs/volume.h | 28 |
11 files changed, 256 insertions, 137 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 02f44094bda9..9d8ffa89e2c2 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,24 @@ 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 | - Fix a potential overflow in file.c where a cast to s64 was missing in | ||
25 | a left shift of a page index. | ||
26 | - The struct inode has had its i_sem semaphore changed to a mutex named | ||
27 | i_mutex. | ||
28 | - We have struct kmem_cache now so use it instead of the typedef | ||
29 | kmem_cache_t. (Pekka Enberg) | ||
30 | - Implement support for sector sizes above 512 bytes (up to the maximum | ||
31 | supported by NTFS which is 4096 bytes). | ||
32 | - Do more detailed reporting of why we cannot mount read-write by | ||
33 | special casing the VOLUME_MODIFIED_BY_CHKDSK flag. | ||
34 | - Miscellaneous updates to layout.h. | ||
35 | - Cope with attribute list attribute having invalid flags. Windows | ||
36 | copes with this and even chkdsk does not detect or fix this so we | ||
37 | have to cope with it, too. Thanks to Pawel Kot for reporting the | ||
38 | problem. | ||
39 | |||
22 | 2.1.25 - (Almost) fully implement write(2) and truncate(2). | 40 | 2.1.25 - (Almost) fully implement write(2) and truncate(2). |
23 | 41 | ||
24 | - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and | 42 | - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and |
@@ -373,7 +391,7 @@ ToDo/Notes: | |||
373 | single one of them had an mst error. (Thanks to Ken MacFerrin for | 391 | single one of them had an mst error. (Thanks to Ken MacFerrin for |
374 | the bug report.) | 392 | the bug report.) |
375 | - Fix error handling in fs/ntfs/quota.c::ntfs_mark_quotas_out_of_date() | 393 | - 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. | 394 | 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(). | 395 | - 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. | 396 | - 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(), | 397 | fs/ntfs/aops.c::ntfs_write_mst_block(), mft.c::ntfs_sync_mft_mirror(), |
@@ -874,7 +892,7 @@ ToDo/Notes: | |||
874 | clusters. (Philipp Thomas) | 892 | clusters. (Philipp Thomas) |
875 | - attrib.c::load_attribute_list(): Fix bug when initialized_size is a | 893 | - attrib.c::load_attribute_list(): Fix bug when initialized_size is a |
876 | multiple of the block_size but not the cluster size. (Szabolcs | 894 | multiple of the block_size but not the cluster size. (Szabolcs |
877 | Szakacsits <szaka@sienet.hu>) | 895 | Szakacsits) |
878 | 896 | ||
879 | 2.1.2 - Important bug fixes aleviating the hangs in statfs. | 897 | 2.1.2 - Important bug fixes aleviating the hangs in statfs. |
880 | 898 | ||
@@ -884,7 +902,7 @@ ToDo/Notes: | |||
884 | 902 | ||
885 | - Add handling for initialized_size != data_size in compressed files. | 903 | - Add handling for initialized_size != data_size in compressed files. |
886 | - Reduce function local stack usage from 0x3d4 bytes to just noise in | 904 | - Reduce function local stack usage from 0x3d4 bytes to just noise in |
887 | fs/ntfs/upcase.c. (Randy Dunlap <rdunlap@xenotime.net>) | 905 | fs/ntfs/upcase.c. (Randy Dunlap) |
888 | - Remove compiler warnings for newer gcc. | 906 | - Remove compiler warnings for newer gcc. |
889 | - Pages are no longer kmapped by mm/filemap.c::generic_file_write() | 907 | - Pages are no longer kmapped by mm/filemap.c::generic_file_write() |
890 | around calls to ->{prepare,commit}_write. Adapt NTFS appropriately | 908 | around calls to ->{prepare,commit}_write. Adapt NTFS appropriately |
@@ -1201,11 +1219,11 @@ ToDo/Notes: | |||
1201 | the kernel. We probably want a kernel generic init_address_space() | 1219 | the kernel. We probably want a kernel generic init_address_space() |
1202 | function... | 1220 | function... |
1203 | - Drop BKL from ntfs_readdir() after consultation with Al Viro. The | 1221 | - Drop BKL from ntfs_readdir() after consultation with Al Viro. The |
1204 | only caller of ->readdir() is vfs_readdir() which holds i_sem during | 1222 | only caller of ->readdir() is vfs_readdir() which holds i_mutex |
1205 | the call, and i_sem is sufficient protection against changes in the | 1223 | during the call, and i_mutex is sufficient protection against changes |
1206 | directory inode (including ->i_size). | 1224 | in the directory inode (including ->i_size). |
1207 | - Use generic_file_llseek() for directories (as opposed to | 1225 | - Use generic_file_llseek() for directories (as opposed to |
1208 | default_llseek()) as this downs i_sem instead of the BKL which is | 1226 | 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 | 1227 | what we now need for exclusion against ->f_pos changes considering we |
1210 | no longer take the BKL in ntfs_readdir(). | 1228 | no longer take the BKL in ntfs_readdir(). |
1211 | 1229 | ||
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile index d0d45d1c853a..d95fac7fdeb6 100644 --- a/fs/ntfs/Makefile +++ b/fs/ntfs/Makefile | |||
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \ | |||
6 | index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ | 6 | index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ |
7 | unistr.o upcase.o | 7 | unistr.o upcase.o |
8 | 8 | ||
9 | EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\" | 9 | EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.26\" |
10 | 10 | ||
11 | ifeq ($(CONFIG_NTFS_DEBUG),y) | 11 | ifeq ($(CONFIG_NTFS_DEBUG),y) |
12 | EXTRA_CFLAGS += -DDEBUG | 12 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index 1c0a4315876a..7e361da770b3 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * aops.c - NTFS kernel address space operations and page cache handling. | 2 | * aops.c - NTFS kernel address space operations and page cache handling. |
3 | * Part of the Linux-NTFS project. | 3 | * Part of the Linux-NTFS project. |
4 | * | 4 | * |
5 | * Copyright (c) 2001-2005 Anton Altaparmakov | 5 | * Copyright (c) 2001-2006 Anton Altaparmakov |
6 | * Copyright (c) 2002 Richard Russon | 6 | * Copyright (c) 2002 Richard Russon |
7 | * | 7 | * |
8 | * This program/include file is free software; you can redistribute it and/or | 8 | * This program/include file is free software; you can redistribute it and/or |
@@ -200,8 +200,8 @@ static int ntfs_read_block(struct page *page) | |||
200 | /* $MFT/$DATA must have its complete runlist in memory at all times. */ | 200 | /* $MFT/$DATA must have its complete runlist in memory at all times. */ |
201 | BUG_ON(!ni->runlist.rl && !ni->mft_no && !NInoAttr(ni)); | 201 | BUG_ON(!ni->runlist.rl && !ni->mft_no && !NInoAttr(ni)); |
202 | 202 | ||
203 | blocksize_bits = VFS_I(ni)->i_blkbits; | 203 | blocksize = vol->sb->s_blocksize; |
204 | blocksize = 1 << blocksize_bits; | 204 | blocksize_bits = vol->sb->s_blocksize_bits; |
205 | 205 | ||
206 | if (!page_has_buffers(page)) { | 206 | if (!page_has_buffers(page)) { |
207 | create_empty_buffers(page, blocksize, 0); | 207 | create_empty_buffers(page, blocksize, 0); |
@@ -569,10 +569,8 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) | |||
569 | 569 | ||
570 | BUG_ON(!NInoNonResident(ni)); | 570 | BUG_ON(!NInoNonResident(ni)); |
571 | BUG_ON(NInoMstProtected(ni)); | 571 | BUG_ON(NInoMstProtected(ni)); |
572 | 572 | blocksize = vol->sb->s_blocksize; | |
573 | blocksize_bits = vi->i_blkbits; | 573 | blocksize_bits = vol->sb->s_blocksize_bits; |
574 | blocksize = 1 << blocksize_bits; | ||
575 | |||
576 | if (!page_has_buffers(page)) { | 574 | if (!page_has_buffers(page)) { |
577 | BUG_ON(!PageUptodate(page)); | 575 | BUG_ON(!PageUptodate(page)); |
578 | create_empty_buffers(page, blocksize, | 576 | create_empty_buffers(page, blocksize, |
@@ -949,8 +947,8 @@ static int ntfs_write_mst_block(struct page *page, | |||
949 | */ | 947 | */ |
950 | BUG_ON(!(is_mft || S_ISDIR(vi->i_mode) || | 948 | BUG_ON(!(is_mft || S_ISDIR(vi->i_mode) || |
951 | (NInoAttr(ni) && ni->type == AT_INDEX_ALLOCATION))); | 949 | (NInoAttr(ni) && ni->type == AT_INDEX_ALLOCATION))); |
952 | bh_size_bits = vi->i_blkbits; | 950 | bh_size = vol->sb->s_blocksize; |
953 | bh_size = 1 << bh_size_bits; | 951 | bh_size_bits = vol->sb->s_blocksize_bits; |
954 | max_bhs = PAGE_CACHE_SIZE / bh_size; | 952 | max_bhs = PAGE_CACHE_SIZE / bh_size; |
955 | BUG_ON(!max_bhs); | 953 | BUG_ON(!max_bhs); |
956 | BUG_ON(max_bhs > MAX_BUF_PER_PAGE); | 954 | BUG_ON(max_bhs > MAX_BUF_PER_PAGE); |
@@ -1596,7 +1594,7 @@ void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs) { | |||
1596 | 1594 | ||
1597 | BUG_ON(!PageUptodate(page)); | 1595 | BUG_ON(!PageUptodate(page)); |
1598 | end = ofs + ni->itype.index.block_size; | 1596 | end = ofs + ni->itype.index.block_size; |
1599 | bh_size = 1 << VFS_I(ni)->i_blkbits; | 1597 | bh_size = VFS_I(ni)->i_sb->s_blocksize; |
1600 | spin_lock(&mapping->private_lock); | 1598 | spin_lock(&mapping->private_lock); |
1601 | if (unlikely(!page_has_buffers(page))) { | 1599 | if (unlikely(!page_has_buffers(page))) { |
1602 | spin_unlock(&mapping->private_lock); | 1600 | spin_unlock(&mapping->private_lock); |
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index fb413d3d8618..5027d3d1b3fe 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * file.c - NTFS kernel file operations. Part of the Linux-NTFS project. | 2 | * file.c - NTFS kernel file operations. Part of the Linux-NTFS project. |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2005 Anton Altaparmakov | 4 | * Copyright (c) 2001-2006 Anton Altaparmakov |
5 | * | 5 | * |
6 | * This program/include file is free software; you can redistribute it and/or | 6 | * This program/include file is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License as published | 7 | * modify it under the terms of the GNU General Public License as published |
@@ -248,7 +248,7 @@ do_non_resident_extend: | |||
248 | * enough to make ntfs_writepage() work. | 248 | * enough to make ntfs_writepage() work. |
249 | */ | 249 | */ |
250 | write_lock_irqsave(&ni->size_lock, flags); | 250 | write_lock_irqsave(&ni->size_lock, flags); |
251 | ni->initialized_size = (index + 1) << PAGE_CACHE_SHIFT; | 251 | ni->initialized_size = (s64)(index + 1) << PAGE_CACHE_SHIFT; |
252 | if (ni->initialized_size > new_init_size) | 252 | if (ni->initialized_size > new_init_size) |
253 | ni->initialized_size = new_init_size; | 253 | ni->initialized_size = new_init_size; |
254 | write_unlock_irqrestore(&ni->size_lock, flags); | 254 | write_unlock_irqrestore(&ni->size_lock, flags); |
@@ -529,8 +529,8 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, | |||
529 | "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.", | 529 | "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.", |
530 | vi->i_ino, ni->type, pages[0]->index, nr_pages, | 530 | vi->i_ino, ni->type, pages[0]->index, nr_pages, |
531 | (long long)pos, bytes); | 531 | (long long)pos, bytes); |
532 | blocksize_bits = vi->i_blkbits; | 532 | blocksize = vol->sb->s_blocksize; |
533 | blocksize = 1 << blocksize_bits; | 533 | blocksize_bits = vol->sb->s_blocksize_bits; |
534 | u = 0; | 534 | u = 0; |
535 | do { | 535 | do { |
536 | struct page *page = pages[u]; | 536 | struct page *page = pages[u]; |
@@ -1525,7 +1525,7 @@ static inline int ntfs_commit_pages_after_non_resident_write( | |||
1525 | 1525 | ||
1526 | vi = pages[0]->mapping->host; | 1526 | vi = pages[0]->mapping->host; |
1527 | ni = NTFS_I(vi); | 1527 | ni = NTFS_I(vi); |
1528 | blocksize = 1 << vi->i_blkbits; | 1528 | blocksize = vi->i_sb->s_blocksize; |
1529 | end = pos + bytes; | 1529 | end = pos + bytes; |
1530 | u = 0; | 1530 | u = 0; |
1531 | do { | 1531 | do { |
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; |
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 0c65cbb8c5cf..6499aafc2258 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /** |
2 | * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project. | 2 | * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project. |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2005 Anton Altaparmakov | 4 | * Copyright (c) 2001-2006 Anton Altaparmakov |
5 | * Copyright (c) 2002 Richard Russon | 5 | * Copyright (c) 2002 Richard Russon |
6 | * | 6 | * |
7 | * This program/include file is free software; you can redistribute it and/or | 7 | * This program/include file is free software; you can redistribute it and/or |
@@ -473,7 +473,7 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no, | |||
473 | runlist_element *rl; | 473 | runlist_element *rl; |
474 | unsigned int block_start, block_end, m_start, m_end, page_ofs; | 474 | unsigned int block_start, block_end, m_start, m_end, page_ofs; |
475 | int i_bhs, nr_bhs, err = 0; | 475 | int i_bhs, nr_bhs, err = 0; |
476 | unsigned char blocksize_bits = vol->mftmirr_ino->i_blkbits; | 476 | unsigned char blocksize_bits = vol->sb->s_blocksize_bits; |
477 | 477 | ||
478 | ntfs_debug("Entering for inode 0x%lx.", mft_no); | 478 | ntfs_debug("Entering for inode 0x%lx.", mft_no); |
479 | BUG_ON(!max_bhs); | 479 | BUG_ON(!max_bhs); |
@@ -672,8 +672,8 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync) | |||
672 | { | 672 | { |
673 | ntfs_volume *vol = ni->vol; | 673 | ntfs_volume *vol = ni->vol; |
674 | struct page *page = ni->page; | 674 | struct page *page = ni->page; |
675 | unsigned char blocksize_bits = vol->mft_ino->i_blkbits; | 675 | unsigned int blocksize = vol->sb->s_blocksize; |
676 | unsigned int blocksize = 1 << blocksize_bits; | 676 | unsigned char blocksize_bits = vol->sb->s_blocksize_bits; |
677 | int max_bhs = vol->mft_record_size / blocksize; | 677 | int max_bhs = vol->mft_record_size / blocksize; |
678 | struct buffer_head *bhs[max_bhs]; | 678 | struct buffer_head *bhs[max_bhs]; |
679 | struct buffer_head *bh, *head; | 679 | struct buffer_head *bh, *head; |
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h index 446b5014115c..653d2a5c4899 100644 --- a/fs/ntfs/ntfs.h +++ b/fs/ntfs/ntfs.h | |||
@@ -50,11 +50,11 @@ typedef enum { | |||
50 | /* Global variables. */ | 50 | /* Global variables. */ |
51 | 51 | ||
52 | /* Slab caches (from super.c). */ | 52 | /* Slab caches (from super.c). */ |
53 | extern kmem_cache_t *ntfs_name_cache; | 53 | extern struct kmem_cache *ntfs_name_cache; |
54 | extern kmem_cache_t *ntfs_inode_cache; | 54 | extern struct kmem_cache *ntfs_inode_cache; |
55 | extern kmem_cache_t *ntfs_big_inode_cache; | 55 | extern struct kmem_cache *ntfs_big_inode_cache; |
56 | extern kmem_cache_t *ntfs_attr_ctx_cache; | 56 | extern struct kmem_cache *ntfs_attr_ctx_cache; |
57 | extern kmem_cache_t *ntfs_index_ctx_cache; | 57 | extern struct kmem_cache *ntfs_index_ctx_cache; |
58 | 58 | ||
59 | /* The various operations structs defined throughout the driver files. */ | 59 | /* The various operations structs defined throughout the driver files. */ |
60 | extern struct address_space_operations ntfs_aops; | 60 | extern struct address_space_operations ntfs_aops; |
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index c3a3f1a8310b..368a8ec10668 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. | 2 | * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2005 Anton Altaparmakov | 4 | * Copyright (c) 2001-2006 Anton Altaparmakov |
5 | * Copyright (c) 2001,2002 Richard Russon | 5 | * Copyright (c) 2001,2002 Richard Russon |
6 | * | 6 | * |
7 | * This program/include file is free software; you can redistribute it and/or | 7 | * This program/include file is free software; you can redistribute it and/or |
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/stddef.h> | 23 | #include <linux/stddef.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/slab.h> | ||
25 | #include <linux/string.h> | 26 | #include <linux/string.h> |
26 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
27 | #include <linux/blkdev.h> /* For bdev_hardsect_size(). */ | 28 | #include <linux/blkdev.h> /* For bdev_hardsect_size(). */ |
@@ -471,9 +472,16 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) | |||
471 | ntfs_error(sb, "Volume is dirty and read-only%s", es); | 472 | ntfs_error(sb, "Volume is dirty and read-only%s", es); |
472 | return -EROFS; | 473 | return -EROFS; |
473 | } | 474 | } |
475 | if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) { | ||
476 | ntfs_error(sb, "Volume has been modified by chkdsk " | ||
477 | "and is read-only%s", es); | ||
478 | return -EROFS; | ||
479 | } | ||
474 | if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { | 480 | if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { |
475 | ntfs_error(sb, "Volume has unsupported flags set and " | 481 | ntfs_error(sb, "Volume has unsupported flags set " |
476 | "is read-only%s", es); | 482 | "(0x%x) and is read-only%s", |
483 | (unsigned)le16_to_cpu(vol->vol_flags), | ||
484 | es); | ||
477 | return -EROFS; | 485 | return -EROFS; |
478 | } | 486 | } |
479 | if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { | 487 | if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { |
@@ -641,7 +649,7 @@ static struct buffer_head *read_ntfs_boot_sector(struct super_block *sb, | |||
641 | { | 649 | { |
642 | const char *read_err_str = "Unable to read %s boot sector."; | 650 | const char *read_err_str = "Unable to read %s boot sector."; |
643 | struct buffer_head *bh_primary, *bh_backup; | 651 | struct buffer_head *bh_primary, *bh_backup; |
644 | long nr_blocks = NTFS_SB(sb)->nr_blocks; | 652 | sector_t nr_blocks = NTFS_SB(sb)->nr_blocks; |
645 | 653 | ||
646 | /* Try to read primary boot sector. */ | 654 | /* Try to read primary boot sector. */ |
647 | if ((bh_primary = sb_bread(sb, 0))) { | 655 | if ((bh_primary = sb_bread(sb, 0))) { |
@@ -688,13 +696,18 @@ hotfix_primary_boot_sector: | |||
688 | /* | 696 | /* |
689 | * If we managed to read sector zero and the volume is not | 697 | * If we managed to read sector zero and the volume is not |
690 | * read-only, copy the found, valid backup boot sector to the | 698 | * read-only, copy the found, valid backup boot sector to the |
691 | * primary boot sector. | 699 | * primary boot sector. Note we only copy the actual boot |
700 | * sector structure, not the actual whole device sector as that | ||
701 | * may be bigger and would potentially damage the $Boot system | ||
702 | * file (FIXME: Would be nice to know if the backup boot sector | ||
703 | * on a large sector device contains the whole boot loader or | ||
704 | * just the first 512 bytes). | ||
692 | */ | 705 | */ |
693 | if (!(sb->s_flags & MS_RDONLY)) { | 706 | if (!(sb->s_flags & MS_RDONLY)) { |
694 | ntfs_warning(sb, "Hot-fix: Recovering invalid primary " | 707 | ntfs_warning(sb, "Hot-fix: Recovering invalid primary " |
695 | "boot sector from backup copy."); | 708 | "boot sector from backup copy."); |
696 | memcpy(bh_primary->b_data, bh_backup->b_data, | 709 | memcpy(bh_primary->b_data, bh_backup->b_data, |
697 | sb->s_blocksize); | 710 | NTFS_BLOCK_SIZE); |
698 | mark_buffer_dirty(bh_primary); | 711 | mark_buffer_dirty(bh_primary); |
699 | sync_dirty_buffer(bh_primary); | 712 | sync_dirty_buffer(bh_primary); |
700 | if (buffer_uptodate(bh_primary)) { | 713 | if (buffer_uptodate(bh_primary)) { |
@@ -733,9 +746,13 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) | |||
733 | vol->sector_size); | 746 | vol->sector_size); |
734 | ntfs_debug("vol->sector_size_bits = %i (0x%x)", vol->sector_size_bits, | 747 | ntfs_debug("vol->sector_size_bits = %i (0x%x)", vol->sector_size_bits, |
735 | vol->sector_size_bits); | 748 | vol->sector_size_bits); |
736 | if (vol->sector_size != vol->sb->s_blocksize) | 749 | if (vol->sector_size < vol->sb->s_blocksize) { |
737 | ntfs_warning(vol->sb, "The boot sector indicates a sector size " | 750 | ntfs_error(vol->sb, "Sector size (%i) is smaller than the " |
738 | "different from the device sector size."); | 751 | "device block size (%lu). This is not " |
752 | "supported. Sorry.", vol->sector_size, | ||
753 | vol->sb->s_blocksize); | ||
754 | return FALSE; | ||
755 | } | ||
739 | ntfs_debug("sectors_per_cluster = 0x%x", b->bpb.sectors_per_cluster); | 756 | ntfs_debug("sectors_per_cluster = 0x%x", b->bpb.sectors_per_cluster); |
740 | sectors_per_cluster_bits = ffs(b->bpb.sectors_per_cluster) - 1; | 757 | sectors_per_cluster_bits = ffs(b->bpb.sectors_per_cluster) - 1; |
741 | ntfs_debug("sectors_per_cluster_bits = 0x%x", | 758 | ntfs_debug("sectors_per_cluster_bits = 0x%x", |
@@ -748,16 +765,11 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) | |||
748 | ntfs_debug("vol->cluster_size = %i (0x%x)", vol->cluster_size, | 765 | ntfs_debug("vol->cluster_size = %i (0x%x)", vol->cluster_size, |
749 | vol->cluster_size); | 766 | vol->cluster_size); |
750 | ntfs_debug("vol->cluster_size_mask = 0x%x", vol->cluster_size_mask); | 767 | ntfs_debug("vol->cluster_size_mask = 0x%x", vol->cluster_size_mask); |
751 | ntfs_debug("vol->cluster_size_bits = %i (0x%x)", | 768 | ntfs_debug("vol->cluster_size_bits = %i", vol->cluster_size_bits); |
752 | vol->cluster_size_bits, vol->cluster_size_bits); | 769 | if (vol->cluster_size < vol->sector_size) { |
753 | if (vol->sector_size > vol->cluster_size) { | 770 | ntfs_error(vol->sb, "Cluster size (%i) is smaller than the " |
754 | ntfs_error(vol->sb, "Sector sizes above the cluster size are " | 771 | "sector size (%i). This is not supported. " |
755 | "not supported. Sorry."); | 772 | "Sorry.", vol->cluster_size, vol->sector_size); |
756 | return FALSE; | ||
757 | } | ||
758 | if (vol->sb->s_blocksize > vol->cluster_size) { | ||
759 | ntfs_error(vol->sb, "Cluster sizes smaller than the device " | ||
760 | "sector size are not supported. Sorry."); | ||
761 | return FALSE; | 773 | return FALSE; |
762 | } | 774 | } |
763 | clusters_per_mft_record = b->clusters_per_mft_record; | 775 | clusters_per_mft_record = b->clusters_per_mft_record; |
@@ -786,11 +798,18 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) | |||
786 | * we store $MFT/$DATA, the table of mft records in the page cache. | 798 | * we store $MFT/$DATA, the table of mft records in the page cache. |
787 | */ | 799 | */ |
788 | if (vol->mft_record_size > PAGE_CACHE_SIZE) { | 800 | if (vol->mft_record_size > PAGE_CACHE_SIZE) { |
789 | ntfs_error(vol->sb, "Mft record size %i (0x%x) exceeds the " | 801 | ntfs_error(vol->sb, "Mft record size (%i) exceeds the " |
790 | "page cache size on your system %lu (0x%lx). " | 802 | "PAGE_CACHE_SIZE on your system (%lu). " |
791 | "This is not supported. Sorry.", | 803 | "This is not supported. Sorry.", |
792 | vol->mft_record_size, vol->mft_record_size, | 804 | vol->mft_record_size, PAGE_CACHE_SIZE); |
793 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE); | 805 | return FALSE; |
806 | } | ||
807 | /* We cannot support mft record sizes below the sector size. */ | ||
808 | if (vol->mft_record_size < vol->sector_size) { | ||
809 | ntfs_error(vol->sb, "Mft record size (%i) is smaller than the " | ||
810 | "sector size (%i). This is not supported. " | ||
811 | "Sorry.", vol->mft_record_size, | ||
812 | vol->sector_size); | ||
794 | return FALSE; | 813 | return FALSE; |
795 | } | 814 | } |
796 | clusters_per_index_record = b->clusters_per_index_record; | 815 | clusters_per_index_record = b->clusters_per_index_record; |
@@ -816,6 +835,14 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) | |||
816 | ntfs_debug("vol->index_record_size_bits = %i (0x%x)", | 835 | ntfs_debug("vol->index_record_size_bits = %i (0x%x)", |
817 | vol->index_record_size_bits, | 836 | vol->index_record_size_bits, |
818 | vol->index_record_size_bits); | 837 | vol->index_record_size_bits); |
838 | /* We cannot support index record sizes below the sector size. */ | ||
839 | if (vol->index_record_size < vol->sector_size) { | ||
840 | ntfs_error(vol->sb, "Index record size (%i) is smaller than " | ||
841 | "the sector size (%i). This is not " | ||
842 | "supported. Sorry.", vol->index_record_size, | ||
843 | vol->sector_size); | ||
844 | return FALSE; | ||
845 | } | ||
819 | /* | 846 | /* |
820 | * Get the size of the volume in clusters and check for 64-bit-ness. | 847 | * Get the size of the volume in clusters and check for 64-bit-ness. |
821 | * Windows currently only uses 32 bits to save the clusters so we do | 848 | * Windows currently only uses 32 bits to save the clusters so we do |
@@ -845,15 +872,18 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) | |||
845 | } | 872 | } |
846 | ll = sle64_to_cpu(b->mft_lcn); | 873 | ll = sle64_to_cpu(b->mft_lcn); |
847 | if (ll >= vol->nr_clusters) { | 874 | if (ll >= vol->nr_clusters) { |
848 | ntfs_error(vol->sb, "MFT LCN is beyond end of volume. Weird."); | 875 | ntfs_error(vol->sb, "MFT LCN (%lli, 0x%llx) is beyond end of " |
876 | "volume. Weird.", (unsigned long long)ll, | ||
877 | (unsigned long long)ll); | ||
849 | return FALSE; | 878 | return FALSE; |
850 | } | 879 | } |
851 | vol->mft_lcn = ll; | 880 | vol->mft_lcn = ll; |
852 | ntfs_debug("vol->mft_lcn = 0x%llx", (long long)vol->mft_lcn); | 881 | ntfs_debug("vol->mft_lcn = 0x%llx", (long long)vol->mft_lcn); |
853 | ll = sle64_to_cpu(b->mftmirr_lcn); | 882 | ll = sle64_to_cpu(b->mftmirr_lcn); |
854 | if (ll >= vol->nr_clusters) { | 883 | if (ll >= vol->nr_clusters) { |
855 | ntfs_error(vol->sb, "MFTMirr LCN is beyond end of volume. " | 884 | ntfs_error(vol->sb, "MFTMirr LCN (%lli, 0x%llx) is beyond end " |
856 | "Weird."); | 885 | "of volume. Weird.", (unsigned long long)ll, |
886 | (unsigned long long)ll); | ||
857 | return FALSE; | 887 | return FALSE; |
858 | } | 888 | } |
859 | vol->mftmirr_lcn = ll; | 889 | vol->mftmirr_lcn = ll; |
@@ -1822,11 +1852,24 @@ get_ctx_vol_failed: | |||
1822 | /* Make sure that no unsupported volume flags are set. */ | 1852 | /* Make sure that no unsupported volume flags are set. */ |
1823 | if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { | 1853 | if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { |
1824 | static const char *es1a = "Volume is dirty"; | 1854 | static const char *es1a = "Volume is dirty"; |
1825 | static const char *es1b = "Volume has unsupported flags set"; | 1855 | static const char *es1b = "Volume has been modified by chkdsk"; |
1826 | static const char *es2 = ". Run chkdsk and mount in Windows."; | 1856 | static const char *es1c = "Volume has unsupported flags set"; |
1827 | const char *es1; | 1857 | static const char *es2a = ". Run chkdsk and mount in Windows."; |
1828 | 1858 | static const char *es2b = ". Mount in Windows."; | |
1829 | es1 = vol->vol_flags & VOLUME_IS_DIRTY ? es1a : es1b; | 1859 | const char *es1, *es2; |
1860 | |||
1861 | es2 = es2a; | ||
1862 | if (vol->vol_flags & VOLUME_IS_DIRTY) | ||
1863 | es1 = es1a; | ||
1864 | else if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) { | ||
1865 | es1 = es1b; | ||
1866 | es2 = es2b; | ||
1867 | } else { | ||
1868 | es1 = es1c; | ||
1869 | ntfs_warning(sb, "Unsupported volume flags 0x%x " | ||
1870 | "encountered.", | ||
1871 | (unsigned)le16_to_cpu(vol->vol_flags)); | ||
1872 | } | ||
1830 | /* If a read-write mount, convert it to a read-only mount. */ | 1873 | /* If a read-write mount, convert it to a read-only mount. */ |
1831 | if (!(sb->s_flags & MS_RDONLY)) { | 1874 | if (!(sb->s_flags & MS_RDONLY)) { |
1832 | if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | | 1875 | if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | |
@@ -2685,7 +2728,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) | |||
2685 | ntfs_volume *vol; | 2728 | ntfs_volume *vol; |
2686 | struct buffer_head *bh; | 2729 | struct buffer_head *bh; |
2687 | struct inode *tmp_ino; | 2730 | struct inode *tmp_ino; |
2688 | int result; | 2731 | int blocksize, result; |
2689 | 2732 | ||
2690 | ntfs_debug("Entering."); | 2733 | ntfs_debug("Entering."); |
2691 | #ifndef NTFS_RW | 2734 | #ifndef NTFS_RW |
@@ -2724,60 +2767,85 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) | |||
2724 | if (!parse_options(vol, (char*)opt)) | 2767 | if (!parse_options(vol, (char*)opt)) |
2725 | goto err_out_now; | 2768 | goto err_out_now; |
2726 | 2769 | ||
2770 | /* We support sector sizes up to the PAGE_CACHE_SIZE. */ | ||
2771 | if (bdev_hardsect_size(sb->s_bdev) > PAGE_CACHE_SIZE) { | ||
2772 | if (!silent) | ||
2773 | ntfs_error(sb, "Device has unsupported sector size " | ||
2774 | "(%i). The maximum supported sector " | ||
2775 | "size on this architecture is %lu " | ||
2776 | "bytes.", | ||
2777 | bdev_hardsect_size(sb->s_bdev), | ||
2778 | PAGE_CACHE_SIZE); | ||
2779 | goto err_out_now; | ||
2780 | } | ||
2727 | /* | 2781 | /* |
2728 | * TODO: Fail safety check. In the future we should really be able to | 2782 | * Setup the device access block size to NTFS_BLOCK_SIZE or the hard |
2729 | * cope with this being the case, but for now just bail out. | 2783 | * sector size, whichever is bigger. |
2730 | */ | 2784 | */ |
2731 | if (bdev_hardsect_size(sb->s_bdev) > NTFS_BLOCK_SIZE) { | 2785 | blocksize = sb_min_blocksize(sb, NTFS_BLOCK_SIZE); |
2786 | if (blocksize < NTFS_BLOCK_SIZE) { | ||
2732 | if (!silent) | 2787 | if (!silent) |
2733 | ntfs_error(sb, "Device has unsupported hardsect_size."); | 2788 | ntfs_error(sb, "Unable to set device block size."); |
2734 | goto err_out_now; | 2789 | goto err_out_now; |
2735 | } | 2790 | } |
2736 | 2791 | BUG_ON(blocksize != sb->s_blocksize); | |
2737 | /* Setup the device access block size to NTFS_BLOCK_SIZE. */ | 2792 | ntfs_debug("Set device block size to %i bytes (block size bits %i).", |
2738 | if (sb_set_blocksize(sb, NTFS_BLOCK_SIZE) != NTFS_BLOCK_SIZE) { | 2793 | blocksize, sb->s_blocksize_bits); |
2794 | /* Determine the size of the device in units of block_size bytes. */ | ||
2795 | if (!i_size_read(sb->s_bdev->bd_inode)) { | ||
2739 | if (!silent) | 2796 | if (!silent) |
2740 | ntfs_error(sb, "Unable to set block size."); | 2797 | ntfs_error(sb, "Unable to determine device size."); |
2741 | goto err_out_now; | 2798 | goto err_out_now; |
2742 | } | 2799 | } |
2743 | |||
2744 | /* Get the size of the device in units of NTFS_BLOCK_SIZE bytes. */ | ||
2745 | vol->nr_blocks = i_size_read(sb->s_bdev->bd_inode) >> | 2800 | vol->nr_blocks = i_size_read(sb->s_bdev->bd_inode) >> |
2746 | NTFS_BLOCK_SIZE_BITS; | 2801 | sb->s_blocksize_bits; |
2747 | |||
2748 | /* Read the boot sector and return unlocked buffer head to it. */ | 2802 | /* Read the boot sector and return unlocked buffer head to it. */ |
2749 | if (!(bh = read_ntfs_boot_sector(sb, silent))) { | 2803 | if (!(bh = read_ntfs_boot_sector(sb, silent))) { |
2750 | if (!silent) | 2804 | if (!silent) |
2751 | ntfs_error(sb, "Not an NTFS volume."); | 2805 | ntfs_error(sb, "Not an NTFS volume."); |
2752 | goto err_out_now; | 2806 | goto err_out_now; |
2753 | } | 2807 | } |
2754 | |||
2755 | /* | 2808 | /* |
2756 | * Extract the data from the boot sector and setup the ntfs super block | 2809 | * Extract the data from the boot sector and setup the ntfs volume |
2757 | * using it. | 2810 | * using it. |
2758 | */ | 2811 | */ |
2759 | result = parse_ntfs_boot_sector(vol, (NTFS_BOOT_SECTOR*)bh->b_data); | 2812 | result = parse_ntfs_boot_sector(vol, (NTFS_BOOT_SECTOR*)bh->b_data); |
2760 | |||
2761 | /* Initialize the cluster and mft allocators. */ | ||
2762 | ntfs_setup_allocators(vol); | ||
2763 | |||
2764 | brelse(bh); | 2813 | brelse(bh); |
2765 | |||
2766 | if (!result) { | 2814 | if (!result) { |
2767 | if (!silent) | 2815 | if (!silent) |
2768 | ntfs_error(sb, "Unsupported NTFS filesystem."); | 2816 | ntfs_error(sb, "Unsupported NTFS filesystem."); |
2769 | goto err_out_now; | 2817 | goto err_out_now; |
2770 | } | 2818 | } |
2771 | |||
2772 | /* | 2819 | /* |
2773 | * TODO: When we start coping with sector sizes different from | 2820 | * If the boot sector indicates a sector size bigger than the current |
2774 | * NTFS_BLOCK_SIZE, we now probably need to set the blocksize of the | 2821 | * device block size, switch the device block size to the sector size. |
2775 | * device (probably to NTFS_BLOCK_SIZE). | 2822 | * TODO: It may be possible to support this case even when the set |
2823 | * below fails, we would just be breaking up the i/o for each sector | ||
2824 | * into multiple blocks for i/o purposes but otherwise it should just | ||
2825 | * work. However it is safer to leave disabled until someone hits this | ||
2826 | * error message and then we can get them to try it without the setting | ||
2827 | * so we know for sure that it works. | ||
2776 | */ | 2828 | */ |
2777 | 2829 | if (vol->sector_size > blocksize) { | |
2830 | blocksize = sb_set_blocksize(sb, vol->sector_size); | ||
2831 | if (blocksize != vol->sector_size) { | ||
2832 | if (!silent) | ||
2833 | ntfs_error(sb, "Unable to set device block " | ||
2834 | "size to sector size (%i).", | ||
2835 | vol->sector_size); | ||
2836 | goto err_out_now; | ||
2837 | } | ||
2838 | BUG_ON(blocksize != sb->s_blocksize); | ||
2839 | vol->nr_blocks = i_size_read(sb->s_bdev->bd_inode) >> | ||
2840 | sb->s_blocksize_bits; | ||
2841 | ntfs_debug("Changed device block size to %i bytes (block size " | ||
2842 | "bits %i) to match volume sector size.", | ||
2843 | blocksize, sb->s_blocksize_bits); | ||
2844 | } | ||
2845 | /* Initialize the cluster and mft allocators. */ | ||
2846 | ntfs_setup_allocators(vol); | ||
2778 | /* Setup remaining fields in the super block. */ | 2847 | /* Setup remaining fields in the super block. */ |
2779 | sb->s_magic = NTFS_SB_MAGIC; | 2848 | sb->s_magic = NTFS_SB_MAGIC; |
2780 | |||
2781 | /* | 2849 | /* |
2782 | * Ntfs allows 63 bits for the file size, i.e. correct would be: | 2850 | * Ntfs allows 63 bits for the file size, i.e. correct would be: |
2783 | * sb->s_maxbytes = ~0ULL >> 1; | 2851 | * sb->s_maxbytes = ~0ULL >> 1; |
@@ -2787,9 +2855,8 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) | |||
2787 | * without overflowing the index or to 2^63 - 1, whichever is smaller. | 2855 | * without overflowing the index or to 2^63 - 1, whichever is smaller. |
2788 | */ | 2856 | */ |
2789 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 2857 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
2790 | 2858 | /* Ntfs measures time in 100ns intervals. */ | |
2791 | sb->s_time_gran = 100; | 2859 | sb->s_time_gran = 100; |
2792 | |||
2793 | /* | 2860 | /* |
2794 | * Now load the metadata required for the page cache and our address | 2861 | * Now load the metadata required for the page cache and our address |
2795 | * space operations to function. We do this by setting up a specialised | 2862 | * space operations to function. We do this by setting up a specialised |
@@ -2987,14 +3054,14 @@ err_out_now: | |||
2987 | * strings of the maximum length allowed by NTFS, which is NTFS_MAX_NAME_LEN | 3054 | * strings of the maximum length allowed by NTFS, which is NTFS_MAX_NAME_LEN |
2988 | * (255) Unicode characters + a terminating NULL Unicode character. | 3055 | * (255) Unicode characters + a terminating NULL Unicode character. |
2989 | */ | 3056 | */ |
2990 | kmem_cache_t *ntfs_name_cache; | 3057 | struct kmem_cache *ntfs_name_cache; |
2991 | 3058 | ||
2992 | /* Slab caches for efficient allocation/deallocation of inodes. */ | 3059 | /* Slab caches for efficient allocation/deallocation of inodes. */ |
2993 | kmem_cache_t *ntfs_inode_cache; | 3060 | struct kmem_cache *ntfs_inode_cache; |
2994 | kmem_cache_t *ntfs_big_inode_cache; | 3061 | struct kmem_cache *ntfs_big_inode_cache; |
2995 | 3062 | ||
2996 | /* Init once constructor for the inode slab cache. */ | 3063 | /* Init once constructor for the inode slab cache. */ |
2997 | static void ntfs_big_inode_init_once(void *foo, kmem_cache_t *cachep, | 3064 | static void ntfs_big_inode_init_once(void *foo, struct kmem_cache *cachep, |
2998 | unsigned long flags) | 3065 | unsigned long flags) |
2999 | { | 3066 | { |
3000 | ntfs_inode *ni = (ntfs_inode *)foo; | 3067 | ntfs_inode *ni = (ntfs_inode *)foo; |
@@ -3008,8 +3075,8 @@ static void ntfs_big_inode_init_once(void *foo, kmem_cache_t *cachep, | |||
3008 | * Slab caches to optimize allocations and deallocations of attribute search | 3075 | * Slab caches to optimize allocations and deallocations of attribute search |
3009 | * contexts and index contexts, respectively. | 3076 | * contexts and index contexts, respectively. |
3010 | */ | 3077 | */ |
3011 | kmem_cache_t *ntfs_attr_ctx_cache; | 3078 | struct kmem_cache *ntfs_attr_ctx_cache; |
3012 | kmem_cache_t *ntfs_index_ctx_cache; | 3079 | struct kmem_cache *ntfs_index_ctx_cache; |
3013 | 3080 | ||
3014 | /* Driver wide semaphore. */ | 3081 | /* Driver wide semaphore. */ |
3015 | DECLARE_MUTEX(ntfs_lock); | 3082 | DECLARE_MUTEX(ntfs_lock); |
diff --git a/fs/ntfs/upcase.c b/fs/ntfs/upcase.c index 879cdf1d5bd3..9101807dc81a 100644 --- a/fs/ntfs/upcase.c +++ b/fs/ntfs/upcase.c | |||
@@ -3,10 +3,7 @@ | |||
3 | * Part of the Linux-NTFS project. | 3 | * Part of the Linux-NTFS project. |
4 | * | 4 | * |
5 | * Copyright (c) 2001 Richard Russon <ntfs@flatcap.org> | 5 | * Copyright (c) 2001 Richard Russon <ntfs@flatcap.org> |
6 | * Copyright (c) 2001-2004 Anton Altaparmakov | 6 | * Copyright (c) 2001-2006 Anton Altaparmakov |
7 | * | ||
8 | * Modified for mkntfs inclusion 9 June 2001 by Anton Altaparmakov. | ||
9 | * Modified for kernel inclusion 10 September 2001 by Anton Altparmakov. | ||
10 | * | 7 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the Free | 9 | * under the terms of the GNU General Public License as published by the Free |
@@ -75,12 +72,13 @@ ntfschar *generate_default_upcase(void) | |||
75 | if (!uc) | 72 | if (!uc) |
76 | return uc; | 73 | return uc; |
77 | memset(uc, 0, default_upcase_len * sizeof(ntfschar)); | 74 | memset(uc, 0, default_upcase_len * sizeof(ntfschar)); |
75 | /* Generate the little endian Unicode upcase table used by ntfs. */ | ||
78 | for (i = 0; i < default_upcase_len; i++) | 76 | for (i = 0; i < default_upcase_len; i++) |
79 | uc[i] = cpu_to_le16(i); | 77 | uc[i] = cpu_to_le16(i); |
80 | for (r = 0; uc_run_table[r][0]; r++) | 78 | for (r = 0; uc_run_table[r][0]; r++) |
81 | for (i = uc_run_table[r][0]; i < uc_run_table[r][1]; i++) | 79 | for (i = uc_run_table[r][0]; i < uc_run_table[r][1]; i++) |
82 | uc[i] = cpu_to_le16((le16_to_cpu(uc[i]) + | 80 | uc[i] = cpu_to_le16(le16_to_cpu(uc[i]) + |
83 | uc_run_table[r][2])); | 81 | uc_run_table[r][2]); |
84 | for (r = 0; uc_dup_table[r][0]; r++) | 82 | for (r = 0; uc_dup_table[r][0]; r++) |
85 | for (i = uc_dup_table[r][0]; i < uc_dup_table[r][1]; i += 2) | 83 | for (i = uc_dup_table[r][0]; i < uc_dup_table[r][1]; i += 2) |
86 | uc[i + 1] = cpu_to_le16(le16_to_cpu(uc[i + 1]) - 1); | 84 | uc[i + 1] = cpu_to_le16(le16_to_cpu(uc[i + 1]) - 1); |
diff --git a/fs/ntfs/volume.h b/fs/ntfs/volume.h index 375cd20a9f61..406ab55dfb32 100644 --- a/fs/ntfs/volume.h +++ b/fs/ntfs/volume.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * volume.h - Defines for volume structures in NTFS Linux kernel driver. Part | 2 | * volume.h - Defines for volume structures in NTFS Linux kernel driver. Part |
3 | * of the Linux-NTFS project. | 3 | * of the Linux-NTFS project. |
4 | * | 4 | * |
5 | * Copyright (c) 2001-2005 Anton Altaparmakov | 5 | * Copyright (c) 2001-2006 Anton Altaparmakov |
6 | * Copyright (c) 2002 Richard Russon | 6 | * Copyright (c) 2002 Richard Russon |
7 | * | 7 | * |
8 | * This program/include file is free software; you can redistribute it and/or | 8 | * This program/include file is free software; you can redistribute it and/or |
@@ -41,10 +41,8 @@ typedef struct { | |||
41 | * structure has stabilized... (AIA) | 41 | * structure has stabilized... (AIA) |
42 | */ | 42 | */ |
43 | /* Device specifics. */ | 43 | /* Device specifics. */ |
44 | struct super_block *sb; /* Pointer back to the super_block, | 44 | struct super_block *sb; /* Pointer back to the super_block. */ |
45 | so we don't have to get the offset | 45 | LCN nr_blocks; /* Number of sb->s_blocksize bytes |
46 | every time. */ | ||
47 | LCN nr_blocks; /* Number of NTFS_BLOCK_SIZE bytes | ||
48 | sized blocks on the device. */ | 46 | sized blocks on the device. */ |
49 | /* Configuration provided by user at mount time. */ | 47 | /* Configuration provided by user at mount time. */ |
50 | unsigned long flags; /* Miscellaneous flags, see below. */ | 48 | unsigned long flags; /* Miscellaneous flags, see below. */ |
@@ -141,8 +139,8 @@ typedef enum { | |||
141 | NV_ShowSystemFiles, /* 1: Return system files in ntfs_readdir(). */ | 139 | NV_ShowSystemFiles, /* 1: Return system files in ntfs_readdir(). */ |
142 | NV_CaseSensitive, /* 1: Treat file names as case sensitive and | 140 | NV_CaseSensitive, /* 1: Treat file names as case sensitive and |
143 | create filenames in the POSIX namespace. | 141 | create filenames in the POSIX namespace. |
144 | Otherwise be case insensitive and create | 142 | Otherwise be case insensitive but still |
145 | file names in WIN32 namespace. */ | 143 | create file names in POSIX namespace. */ |
146 | NV_LogFileEmpty, /* 1: $LogFile journal is empty. */ | 144 | NV_LogFileEmpty, /* 1: $LogFile journal is empty. */ |
147 | NV_QuotaOutOfDate, /* 1: $Quota is out of date. */ | 145 | NV_QuotaOutOfDate, /* 1: $Quota is out of date. */ |
148 | NV_UsnJrnlStamped, /* 1: $UsnJrnl has been stamped. */ | 146 | NV_UsnJrnlStamped, /* 1: $UsnJrnl has been stamped. */ |
@@ -153,7 +151,7 @@ typedef enum { | |||
153 | * Macro tricks to expand the NVolFoo(), NVolSetFoo(), and NVolClearFoo() | 151 | * Macro tricks to expand the NVolFoo(), NVolSetFoo(), and NVolClearFoo() |
154 | * functions. | 152 | * functions. |
155 | */ | 153 | */ |
156 | #define NVOL_FNS(flag) \ | 154 | #define DEFINE_NVOL_BIT_OPS(flag) \ |
157 | static inline int NVol##flag(ntfs_volume *vol) \ | 155 | static inline int NVol##flag(ntfs_volume *vol) \ |
158 | { \ | 156 | { \ |
159 | return test_bit(NV_##flag, &(vol)->flags); \ | 157 | return test_bit(NV_##flag, &(vol)->flags); \ |
@@ -168,12 +166,12 @@ static inline void NVolClear##flag(ntfs_volume *vol) \ | |||
168 | } | 166 | } |
169 | 167 | ||
170 | /* Emit the ntfs volume bitops functions. */ | 168 | /* Emit the ntfs volume bitops functions. */ |
171 | NVOL_FNS(Errors) | 169 | DEFINE_NVOL_BIT_OPS(Errors) |
172 | NVOL_FNS(ShowSystemFiles) | 170 | DEFINE_NVOL_BIT_OPS(ShowSystemFiles) |
173 | NVOL_FNS(CaseSensitive) | 171 | DEFINE_NVOL_BIT_OPS(CaseSensitive) |
174 | NVOL_FNS(LogFileEmpty) | 172 | DEFINE_NVOL_BIT_OPS(LogFileEmpty) |
175 | NVOL_FNS(QuotaOutOfDate) | 173 | DEFINE_NVOL_BIT_OPS(QuotaOutOfDate) |
176 | NVOL_FNS(UsnJrnlStamped) | 174 | DEFINE_NVOL_BIT_OPS(UsnJrnlStamped) |
177 | NVOL_FNS(SparseEnabled) | 175 | DEFINE_NVOL_BIT_OPS(SparseEnabled) |
178 | 176 | ||
179 | #endif /* _LINUX_NTFS_VOLUME_H */ | 177 | #endif /* _LINUX_NTFS_VOLUME_H */ |