diff options
| author | Steve French <sfrench@us.ibm.com> | 2006-03-03 06:27:25 -0500 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2006-03-03 06:27:25 -0500 |
| commit | c6ee60b7c8bbc78e3b1776b2820a7e7f95f8996a (patch) | |
| tree | 99b48ef0f5217fddc0aa897d9e60d95ace7da6ff /fs/ntfs | |
| parent | 13298defe5323c7fdcac268f588d8d1090758fb8 (diff) | |
| parent | c499ec24c31edf270e777a868ffd0daddcfe7ebd (diff) | |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/ntfs')
| -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 */ |
