aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-23 19:26:56 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-23 19:26:56 -0500
commita1a051b1870f9e4607526c7e403abab06526c6d9 (patch)
tree08942e39ca8477c4b0f594deac9e966bb376db83 /fs
parentaca361c1a0dc0165ac3148137983cb4b1458b5c1 (diff)
parentb425c8c5922562c562dc55a636c3c8d758ed6d17 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6: NTFS: 2.1.27 - Various bug fixes and cleanups. NTFS: Semaphore to mutex conversion. NTFS: Handle the recently introduced -ENAMETOOLONG return value from NTFS: Add a missing call to flush_dcache_mft_record_page() in NTFS: Fix a bug in fs/ntfs/inode.c::ntfs_read_locked_index_inode() where we NTFS: Improve comments on file attribute flags in fs/ntfs/layout.h. NTFS: Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum NTFS: Remove all the make_bad_inode() calls. This should only be called NTFS: Add support for sparse files which have a compression unit of 0. NTFS: Fix comparison of $MFT and $MFTMirr to not bail out when there are NTFS: Use buffer_migrate_page() for the ->migratepage function of all ntfs NTFS: Fix a buggette in an "should be impossible" case handling where we NTFS: Fix an (innocent) off-by-one error in the runlist code. NTFS: Fix two compiler warnings on Alpha. Thanks to Andrew Morton for
Diffstat (limited to 'fs')
-rw-r--r--fs/ntfs/ChangeLog30
-rw-r--r--fs/ntfs/Makefile2
-rw-r--r--fs/ntfs/aops.c14
-rw-r--r--fs/ntfs/attrib.c35
-rw-r--r--fs/ntfs/compress.c4
-rw-r--r--fs/ntfs/dir.c2
-rw-r--r--fs/ntfs/file.c16
-rw-r--r--fs/ntfs/inode.c111
-rw-r--r--fs/ntfs/inode.h13
-rw-r--r--fs/ntfs/layout.h44
-rw-r--r--fs/ntfs/mft.c68
-rw-r--r--fs/ntfs/mft.h5
-rw-r--r--fs/ntfs/namei.c9
-rw-r--r--fs/ntfs/ntfs.h2
-rw-r--r--fs/ntfs/runlist.c12
-rw-r--r--fs/ntfs/super.c84
-rw-r--r--fs/ntfs/unistr.c51
17 files changed, 289 insertions, 213 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 9d8ffa89e2c2..35cc4b1d60f7 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -16,8 +16,34 @@ ToDo/Notes:
16 inode having been discarded already. Whether this can actually ever 16 inode having been discarded already. Whether this can actually ever
17 happen is unclear however so it is worth waiting until someone hits 17 happen is unclear however so it is worth waiting until someone hits
18 the problem. 18 the problem.
19 - Enable the code for setting the NT4 compatibility flag when we start 19
20 making NTFS 1.2 specific modifications. 202.1.27 - Various bug fixes and cleanups.
21
22 - Fix two compiler warnings on Alpha. Thanks to Andrew Morton for
23 reporting them.
24 - Fix an (innocent) off-by-one error in the runlist code.
25 - Fix a buggette in an "should be impossible" case handling where we
26 continued the attribute lookup loop instead of aborting it.
27 - Use buffer_migrate_page() for the ->migratepage function of all ntfs
28 address space operations.
29 - Fix comparison of $MFT and $MFTMirr to not bail out when there are
30 unused, invalid mft records which are the same in both $MFT and
31 $MFTMirr.
32 - Add support for sparse files which have a compression unit of 0.
33 - Remove all the make_bad_inode() calls. This should only be called
34 from read inode and new inode code paths.
35 - Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum
36 allowed by NTFS, i.e. 255 Unicode characters, not including the
37 terminating NULL (which is not stored on disk).
38 - Improve comments on file attribute flags in fs/ntfs/layout.h.
39 - Fix a bug in fs/ntfs/inode.c::ntfs_read_locked_index_inode() where we
40 forgot to update a temporary variable so loading index inodes which
41 have an index allocation attribute failed.
42 - Add a missing call to flush_dcache_mft_record_page() in
43 fs/ntfs/inode.c::ntfs_write_inode().
44 - Handle the recently introduced -ENAMETOOLONG return value from
45 fs/ntfs/unistr.c::ntfs_nlstoucs() in fs/ntfs/namei.c::ntfs_lookup().
46 - Semaphore to mutex conversion. (Ingo Molnar)
21 47
222.1.26 - Minor bug fixes and updates. 482.1.26 - Minor bug fixes and updates.
23 49
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
index d95fac7fdeb6..e27b4eacffbf 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
9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.26\" 9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.27\"
10 10
11ifeq ($(CONFIG_NTFS_DEBUG),y) 11ifeq ($(CONFIG_NTFS_DEBUG),y)
12EXTRA_CFLAGS += -DDEBUG 12EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 7e361da770b3..580412d330cb 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/fs.h>
25#include <linux/mm.h> 26#include <linux/mm.h>
26#include <linux/pagemap.h> 27#include <linux/pagemap.h>
27#include <linux/swap.h> 28#include <linux/swap.h>
@@ -1277,18 +1278,18 @@ unm_done:
1277 1278
1278 tni = locked_nis[nr_locked_nis]; 1279 tni = locked_nis[nr_locked_nis];
1279 /* Get the base inode. */ 1280 /* Get the base inode. */
1280 down(&tni->extent_lock); 1281 mutex_lock(&tni->extent_lock);
1281 if (tni->nr_extents >= 0) 1282 if (tni->nr_extents >= 0)
1282 base_tni = tni; 1283 base_tni = tni;
1283 else { 1284 else {
1284 base_tni = tni->ext.base_ntfs_ino; 1285 base_tni = tni->ext.base_ntfs_ino;
1285 BUG_ON(!base_tni); 1286 BUG_ON(!base_tni);
1286 } 1287 }
1287 up(&tni->extent_lock); 1288 mutex_unlock(&tni->extent_lock);
1288 ntfs_debug("Unlocking %s inode 0x%lx.", 1289 ntfs_debug("Unlocking %s inode 0x%lx.",
1289 tni == base_tni ? "base" : "extent", 1290 tni == base_tni ? "base" : "extent",
1290 tni->mft_no); 1291 tni->mft_no);
1291 up(&tni->mrec_lock); 1292 mutex_unlock(&tni->mrec_lock);
1292 atomic_dec(&tni->count); 1293 atomic_dec(&tni->count);
1293 iput(VFS_I(base_tni)); 1294 iput(VFS_I(base_tni));
1294 } 1295 }
@@ -1529,7 +1530,6 @@ err_out:
1529 "error %i.", err); 1530 "error %i.", err);
1530 SetPageError(page); 1531 SetPageError(page);
1531 NVolSetErrors(ni->vol); 1532 NVolSetErrors(ni->vol);
1532 make_bad_inode(vi);
1533 } 1533 }
1534 unlock_page(page); 1534 unlock_page(page);
1535 if (ctx) 1535 if (ctx)
@@ -1551,6 +1551,9 @@ struct address_space_operations ntfs_aops = {
1551#ifdef NTFS_RW 1551#ifdef NTFS_RW
1552 .writepage = ntfs_writepage, /* Write dirty page to disk. */ 1552 .writepage = ntfs_writepage, /* Write dirty page to disk. */
1553#endif /* NTFS_RW */ 1553#endif /* NTFS_RW */
1554 .migratepage = buffer_migrate_page, /* Move a page cache page from
1555 one physical page to an
1556 other. */
1554}; 1557};
1555 1558
1556/** 1559/**
@@ -1567,6 +1570,9 @@ struct address_space_operations ntfs_mst_aops = {
1567 without touching the buffers 1570 without touching the buffers
1568 belonging to the page. */ 1571 belonging to the page. */
1569#endif /* NTFS_RW */ 1572#endif /* NTFS_RW */
1573 .migratepage = buffer_migrate_page, /* Move a page cache page from
1574 one physical page to an
1575 other. */
1570}; 1576};
1571 1577
1572#ifdef NTFS_RW 1578#ifdef NTFS_RW
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 9480a0526cd3..1663f5c3c6aa 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * attrib.c - NTFS attribute operations. Part of the Linux-NTFS project. 2 * attrib.c - NTFS attribute 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
@@ -1048,7 +1048,7 @@ do_next_attr_loop:
1048 le32_to_cpu(ctx->mrec->bytes_allocated)) 1048 le32_to_cpu(ctx->mrec->bytes_allocated))
1049 break; 1049 break;
1050 if (a->type == AT_END) 1050 if (a->type == AT_END)
1051 continue; 1051 break;
1052 if (!a->length) 1052 if (!a->length)
1053 break; 1053 break;
1054 if (al_entry->instance != a->instance) 1054 if (al_entry->instance != a->instance)
@@ -1695,7 +1695,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
1695 a->data.non_resident.initialized_size = 1695 a->data.non_resident.initialized_size =
1696 cpu_to_sle64(attr_size); 1696 cpu_to_sle64(attr_size);
1697 if (NInoSparse(ni) || NInoCompressed(ni)) { 1697 if (NInoSparse(ni) || NInoCompressed(ni)) {
1698 a->data.non_resident.compression_unit = 4; 1698 a->data.non_resident.compression_unit = 0;
1699 if (NInoCompressed(ni) || vol->major_ver < 3)
1700 a->data.non_resident.compression_unit = 4;
1699 a->data.non_resident.compressed_size = 1701 a->data.non_resident.compressed_size =
1700 a->data.non_resident.allocated_size; 1702 a->data.non_resident.allocated_size;
1701 } else 1703 } else
@@ -1714,13 +1716,20 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
1714 ni->allocated_size = new_size; 1716 ni->allocated_size = new_size;
1715 if (NInoSparse(ni) || NInoCompressed(ni)) { 1717 if (NInoSparse(ni) || NInoCompressed(ni)) {
1716 ni->itype.compressed.size = ni->allocated_size; 1718 ni->itype.compressed.size = ni->allocated_size;
1717 ni->itype.compressed.block_size = 1U << 1719 if (a->data.non_resident.compression_unit) {
1718 (a->data.non_resident.compression_unit + 1720 ni->itype.compressed.block_size = 1U << (a->data.
1719 vol->cluster_size_bits); 1721 non_resident.compression_unit +
1720 ni->itype.compressed.block_size_bits = 1722 vol->cluster_size_bits);
1721 ffs(ni->itype.compressed.block_size) - 1; 1723 ni->itype.compressed.block_size_bits =
1722 ni->itype.compressed.block_clusters = 1U << 1724 ffs(ni->itype.compressed.block_size) -
1723 a->data.non_resident.compression_unit; 1725 1;
1726 ni->itype.compressed.block_clusters = 1U <<
1727 a->data.non_resident.compression_unit;
1728 } else {
1729 ni->itype.compressed.block_size = 0;
1730 ni->itype.compressed.block_size_bits = 0;
1731 ni->itype.compressed.block_clusters = 0;
1732 }
1724 vi->i_blocks = ni->itype.compressed.size >> 9; 1733 vi->i_blocks = ni->itype.compressed.size >> 9;
1725 } else 1734 } else
1726 vi->i_blocks = ni->allocated_size >> 9; 1735 vi->i_blocks = ni->allocated_size >> 9;
@@ -2429,16 +2438,12 @@ undo_alloc:
2429 "chkdsk to recover.", IS_ERR(m) ? 2438 "chkdsk to recover.", IS_ERR(m) ?
2430 "restore attribute search context" : 2439 "restore attribute search context" :
2431 "truncate attribute runlist"); 2440 "truncate attribute runlist");
2432 make_bad_inode(vi);
2433 make_bad_inode(VFS_I(base_ni));
2434 NVolSetErrors(vol); 2441 NVolSetErrors(vol);
2435 } else if (mp_rebuilt) { 2442 } else if (mp_rebuilt) {
2436 if (ntfs_attr_record_resize(m, a, attr_len)) { 2443 if (ntfs_attr_record_resize(m, a, attr_len)) {
2437 ntfs_error(vol->sb, "Failed to restore attribute " 2444 ntfs_error(vol->sb, "Failed to restore attribute "
2438 "record in error code path. Run " 2445 "record in error code path. Run "
2439 "chkdsk to recover."); 2446 "chkdsk to recover.");
2440 make_bad_inode(vi);
2441 make_bad_inode(VFS_I(base_ni));
2442 NVolSetErrors(vol); 2447 NVolSetErrors(vol);
2443 } else /* if (success) */ { 2448 } else /* if (success) */ {
2444 if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( 2449 if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
@@ -2451,8 +2456,6 @@ undo_alloc:
2451 "mapping pairs array in error " 2456 "mapping pairs array in error "
2452 "code path. Run chkdsk to " 2457 "code path. Run chkdsk to "
2453 "recover."); 2458 "recover.");
2454 make_bad_inode(vi);
2455 make_bad_inode(VFS_I(base_ni));
2456 NVolSetErrors(vol); 2459 NVolSetErrors(vol);
2457 } 2460 }
2458 flush_dcache_mft_record_page(ctx->ntfs_ino); 2461 flush_dcache_mft_record_page(ctx->ntfs_ino);
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index 25d24106f893..68a607ff9fd3 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(ntfs_cb_lock);
67/** 67/**
68 * allocate_compression_buffers - allocate the decompression buffers 68 * allocate_compression_buffers - allocate the decompression buffers
69 * 69 *
70 * Caller has to hold the ntfs_lock semaphore. 70 * Caller has to hold the ntfs_lock mutex.
71 * 71 *
72 * Return 0 on success or -ENOMEM if the allocations failed. 72 * Return 0 on success or -ENOMEM if the allocations failed.
73 */ 73 */
@@ -84,7 +84,7 @@ int allocate_compression_buffers(void)
84/** 84/**
85 * free_compression_buffers - free the decompression buffers 85 * free_compression_buffers - free the decompression buffers
86 * 86 *
87 * Caller has to hold the ntfs_lock semaphore. 87 * Caller has to hold the ntfs_lock mutex.
88 */ 88 */
89void free_compression_buffers(void) 89void free_compression_buffers(void)
90{ 90{
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index b0690d4c8906..9d9ed3fe371d 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1136,7 +1136,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
1136 if (fpos == 1) { 1136 if (fpos == 1) {
1137 ntfs_debug("Calling filldir for .. with len 2, fpos 0x1, " 1137 ntfs_debug("Calling filldir for .. with len 2, fpos 0x1, "
1138 "inode 0x%lx, DT_DIR.", 1138 "inode 0x%lx, DT_DIR.",
1139 parent_ino(filp->f_dentry)); 1139 (unsigned long)parent_ino(filp->f_dentry));
1140 rc = filldir(dirent, "..", 2, fpos, 1140 rc = filldir(dirent, "..", 2, fpos,
1141 parent_ino(filp->f_dentry), DT_DIR); 1141 parent_ino(filp->f_dentry), DT_DIR);
1142 if (rc) 1142 if (rc)
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 5027d3d1b3fe..f5d057e4acc2 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -943,7 +943,8 @@ rl_not_mapped_enoent:
943 } 943 }
944 ni->runlist.rl = rl; 944 ni->runlist.rl = rl;
945 status.runlist_merged = 1; 945 status.runlist_merged = 1;
946 ntfs_debug("Allocated cluster, lcn 0x%llx.", lcn); 946 ntfs_debug("Allocated cluster, lcn 0x%llx.",
947 (unsigned long long)lcn);
947 /* Map and lock the mft record and get the attribute record. */ 948 /* Map and lock the mft record and get the attribute record. */
948 if (!NInoAttr(ni)) 949 if (!NInoAttr(ni))
949 base_ni = ni; 950 base_ni = ni;
@@ -1206,8 +1207,6 @@ rl_not_mapped_enoent:
1206 "attribute runlist in error code " 1207 "attribute runlist in error code "
1207 "path. Run chkdsk to recover the " 1208 "path. Run chkdsk to recover the "
1208 "lost cluster."); 1209 "lost cluster.");
1209 make_bad_inode(vi);
1210 make_bad_inode(VFS_I(base_ni));
1211 NVolSetErrors(vol); 1210 NVolSetErrors(vol);
1212 } else /* if (success) */ { 1211 } else /* if (success) */ {
1213 status.runlist_merged = 0; 1212 status.runlist_merged = 0;
@@ -1238,8 +1237,6 @@ rl_not_mapped_enoent:
1238 ntfs_error(vol->sb, "Failed to restore attribute " 1237 ntfs_error(vol->sb, "Failed to restore attribute "
1239 "record in error code path. Run " 1238 "record in error code path. Run "
1240 "chkdsk to recover."); 1239 "chkdsk to recover.");
1241 make_bad_inode(vi);
1242 make_bad_inode(VFS_I(base_ni));
1243 NVolSetErrors(vol); 1240 NVolSetErrors(vol);
1244 } else /* if (success) */ { 1241 } else /* if (success) */ {
1245 if (ntfs_mapping_pairs_build(vol, (u8*)a + 1242 if (ntfs_mapping_pairs_build(vol, (u8*)a +
@@ -1252,8 +1249,6 @@ rl_not_mapped_enoent:
1252 "mapping pairs array in error " 1249 "mapping pairs array in error "
1253 "code path. Run chkdsk to " 1250 "code path. Run chkdsk to "
1254 "recover."); 1251 "recover.");
1255 make_bad_inode(vi);
1256 make_bad_inode(VFS_I(base_ni));
1257 NVolSetErrors(vol); 1252 NVolSetErrors(vol);
1258 } 1253 }
1259 flush_dcache_mft_record_page(ctx->ntfs_ino); 1254 flush_dcache_mft_record_page(ctx->ntfs_ino);
@@ -1622,11 +1617,8 @@ err_out:
1622 unmap_mft_record(base_ni); 1617 unmap_mft_record(base_ni);
1623 ntfs_error(vi->i_sb, "Failed to update initialized_size/i_size (error " 1618 ntfs_error(vi->i_sb, "Failed to update initialized_size/i_size (error "
1624 "code %i).", err); 1619 "code %i).", err);
1625 if (err != -ENOMEM) { 1620 if (err != -ENOMEM)
1626 NVolSetErrors(ni->vol); 1621 NVolSetErrors(ni->vol);
1627 make_bad_inode(VFS_I(base_ni));
1628 make_bad_inode(vi);
1629 }
1630 return err; 1622 return err;
1631} 1623}
1632 1624
@@ -1801,8 +1793,6 @@ err_out:
1801 ntfs_error(vi->i_sb, "Resident attribute commit write failed " 1793 ntfs_error(vi->i_sb, "Resident attribute commit write failed "
1802 "with error %i.", err); 1794 "with error %i.", err);
1803 NVolSetErrors(ni->vol); 1795 NVolSetErrors(ni->vol);
1804 make_bad_inode(VFS_I(base_ni));
1805 make_bad_inode(vi);
1806 } 1796 }
1807 if (ctx) 1797 if (ctx)
1808 ntfs_attr_put_search_ctx(ctx); 1798 ntfs_attr_put_search_ctx(ctx);
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 55263b7de9c0..4c86b7e1d1eb 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project. 2 * inode.c - NTFS kernel inode handling. 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
@@ -19,13 +19,19 @@
19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/pagemap.h>
23#include <linux/buffer_head.h> 22#include <linux/buffer_head.h>
24#include <linux/smp_lock.h> 23#include <linux/fs.h>
25#include <linux/quotaops.h> 24#include <linux/mm.h>
26#include <linux/mount.h> 25#include <linux/mount.h>
26#include <linux/mutex.h>
27#include <linux/pagemap.h>
28#include <linux/quotaops.h>
29#include <linux/slab.h>
30#include <linux/smp_lock.h>
27 31
28#include "aops.h" 32#include "aops.h"
33#include "attrib.h"
34#include "bitmap.h"
29#include "dir.h" 35#include "dir.h"
30#include "debug.h" 36#include "debug.h"
31#include "inode.h" 37#include "inode.h"
@@ -382,7 +388,7 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
382 atomic_set(&ni->count, 1); 388 atomic_set(&ni->count, 1);
383 ni->vol = NTFS_SB(sb); 389 ni->vol = NTFS_SB(sb);
384 ntfs_init_runlist(&ni->runlist); 390 ntfs_init_runlist(&ni->runlist);
385 init_MUTEX(&ni->mrec_lock); 391 mutex_init(&ni->mrec_lock);
386 ni->page = NULL; 392 ni->page = NULL;
387 ni->page_ofs = 0; 393 ni->page_ofs = 0;
388 ni->attr_list_size = 0; 394 ni->attr_list_size = 0;
@@ -394,7 +400,7 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
394 ni->itype.index.collation_rule = 0; 400 ni->itype.index.collation_rule = 0;
395 ni->itype.index.block_size_bits = 0; 401 ni->itype.index.block_size_bits = 0;
396 ni->itype.index.vcn_size_bits = 0; 402 ni->itype.index.vcn_size_bits = 0;
397 init_MUTEX(&ni->extent_lock); 403 mutex_init(&ni->extent_lock);
398 ni->nr_extents = 0; 404 ni->nr_extents = 0;
399 ni->ext.base_ntfs_ino = NULL; 405 ni->ext.base_ntfs_ino = NULL;
400} 406}
@@ -1064,10 +1070,10 @@ skip_large_dir_stuff:
1064 if (a->non_resident) { 1070 if (a->non_resident) {
1065 NInoSetNonResident(ni); 1071 NInoSetNonResident(ni);
1066 if (NInoCompressed(ni) || NInoSparse(ni)) { 1072 if (NInoCompressed(ni) || NInoSparse(ni)) {
1067 if (a->data.non_resident.compression_unit != 1073 if (NInoCompressed(ni) && a->data.non_resident.
1068 4) { 1074 compression_unit != 4) {
1069 ntfs_error(vi->i_sb, "Found " 1075 ntfs_error(vi->i_sb, "Found "
1070 "nonstandard " 1076 "non-standard "
1071 "compression unit (%u " 1077 "compression unit (%u "
1072 "instead of 4). " 1078 "instead of 4). "
1073 "Cannot handle this.", 1079 "Cannot handle this.",
@@ -1076,16 +1082,26 @@ skip_large_dir_stuff:
1076 err = -EOPNOTSUPP; 1082 err = -EOPNOTSUPP;
1077 goto unm_err_out; 1083 goto unm_err_out;
1078 } 1084 }
1079 ni->itype.compressed.block_clusters = 1U << 1085 if (a->data.non_resident.compression_unit) {
1080 a->data.non_resident. 1086 ni->itype.compressed.block_size = 1U <<
1081 compression_unit; 1087 (a->data.non_resident.
1082 ni->itype.compressed.block_size = 1U << ( 1088 compression_unit +
1083 a->data.non_resident. 1089 vol->cluster_size_bits);
1084 compression_unit + 1090 ni->itype.compressed.block_size_bits =
1085 vol->cluster_size_bits); 1091 ffs(ni->itype.
1086 ni->itype.compressed.block_size_bits = ffs( 1092 compressed.
1087 ni->itype.compressed. 1093 block_size) - 1;
1088 block_size) - 1; 1094 ni->itype.compressed.block_clusters =
1095 1U << a->data.
1096 non_resident.
1097 compression_unit;
1098 } else {
1099 ni->itype.compressed.block_size = 0;
1100 ni->itype.compressed.block_size_bits =
1101 0;
1102 ni->itype.compressed.block_clusters =
1103 0;
1104 }
1089 ni->itype.compressed.size = sle64_to_cpu( 1105 ni->itype.compressed.size = sle64_to_cpu(
1090 a->data.non_resident. 1106 a->data.non_resident.
1091 compressed_size); 1107 compressed_size);
@@ -1338,8 +1354,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1338 goto unm_err_out; 1354 goto unm_err_out;
1339 } 1355 }
1340 if (NInoCompressed(ni) || NInoSparse(ni)) { 1356 if (NInoCompressed(ni) || NInoSparse(ni)) {
1341 if (a->data.non_resident.compression_unit != 4) { 1357 if (NInoCompressed(ni) && a->data.non_resident.
1342 ntfs_error(vi->i_sb, "Found nonstandard " 1358 compression_unit != 4) {
1359 ntfs_error(vi->i_sb, "Found non-standard "
1343 "compression unit (%u instead " 1360 "compression unit (%u instead "
1344 "of 4). Cannot handle this.", 1361 "of 4). Cannot handle this.",
1345 a->data.non_resident. 1362 a->data.non_resident.
@@ -1347,13 +1364,22 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1347 err = -EOPNOTSUPP; 1364 err = -EOPNOTSUPP;
1348 goto unm_err_out; 1365 goto unm_err_out;
1349 } 1366 }
1350 ni->itype.compressed.block_clusters = 1U << 1367 if (a->data.non_resident.compression_unit) {
1351 a->data.non_resident.compression_unit; 1368 ni->itype.compressed.block_size = 1U <<
1352 ni->itype.compressed.block_size = 1U << ( 1369 (a->data.non_resident.
1353 a->data.non_resident.compression_unit + 1370 compression_unit +
1354 vol->cluster_size_bits); 1371 vol->cluster_size_bits);
1355 ni->itype.compressed.block_size_bits = ffs( 1372 ni->itype.compressed.block_size_bits =
1356 ni->itype.compressed.block_size) - 1; 1373 ffs(ni->itype.compressed.
1374 block_size) - 1;
1375 ni->itype.compressed.block_clusters = 1U <<
1376 a->data.non_resident.
1377 compression_unit;
1378 } else {
1379 ni->itype.compressed.block_size = 0;
1380 ni->itype.compressed.block_size_bits = 0;
1381 ni->itype.compressed.block_clusters = 0;
1382 }
1357 ni->itype.compressed.size = sle64_to_cpu( 1383 ni->itype.compressed.size = sle64_to_cpu(
1358 a->data.non_resident.compressed_size); 1384 a->data.non_resident.compressed_size);
1359 } 1385 }
@@ -1406,7 +1432,6 @@ err_out:
1406 "Run chkdsk.", err, vi->i_ino, ni->type, ni->name_len, 1432 "Run chkdsk.", err, vi->i_ino, ni->type, ni->name_len,
1407 base_vi->i_ino); 1433 base_vi->i_ino);
1408 make_bad_inode(vi); 1434 make_bad_inode(vi);
1409 make_bad_inode(base_vi);
1410 if (err != -ENOMEM) 1435 if (err != -ENOMEM)
1411 NVolSetErrors(vol); 1436 NVolSetErrors(vol);
1412 return err; 1437 return err;
@@ -1591,6 +1616,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
1591 "$INDEX_ALLOCATION attribute."); 1616 "$INDEX_ALLOCATION attribute.");
1592 goto unm_err_out; 1617 goto unm_err_out;
1593 } 1618 }
1619 a = ctx->attr;
1594 if (!a->non_resident) { 1620 if (!a->non_resident) {
1595 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is " 1621 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "
1596 "resident."); 1622 "resident.");
@@ -2823,11 +2849,8 @@ done:
2823old_bad_out: 2849old_bad_out:
2824 old_size = -1; 2850 old_size = -1;
2825bad_out: 2851bad_out:
2826 if (err != -ENOMEM && err != -EOPNOTSUPP) { 2852 if (err != -ENOMEM && err != -EOPNOTSUPP)
2827 make_bad_inode(vi);
2828 make_bad_inode(VFS_I(base_ni));
2829 NVolSetErrors(vol); 2853 NVolSetErrors(vol);
2830 }
2831 if (err != -EOPNOTSUPP) 2854 if (err != -EOPNOTSUPP)
2832 NInoSetTruncateFailed(ni); 2855 NInoSetTruncateFailed(ni);
2833 else if (old_size >= 0) 2856 else if (old_size >= 0)
@@ -2842,11 +2865,8 @@ out:
2842 ntfs_debug("Failed. Returning error code %i.", err); 2865 ntfs_debug("Failed. Returning error code %i.", err);
2843 return err; 2866 return err;
2844conv_err_out: 2867conv_err_out:
2845 if (err != -ENOMEM && err != -EOPNOTSUPP) { 2868 if (err != -ENOMEM && err != -EOPNOTSUPP)
2846 make_bad_inode(vi);
2847 make_bad_inode(VFS_I(base_ni));
2848 NVolSetErrors(vol); 2869 NVolSetErrors(vol);
2849 }
2850 if (err != -EOPNOTSUPP) 2870 if (err != -EOPNOTSUPP)
2851 NInoSetTruncateFailed(ni); 2871 NInoSetTruncateFailed(ni);
2852 else 2872 else
@@ -3044,15 +3064,18 @@ int ntfs_write_inode(struct inode *vi, int sync)
3044 * record will be cleaned and written out to disk below, i.e. before 3064 * record will be cleaned and written out to disk below, i.e. before
3045 * this function returns. 3065 * this function returns.
3046 */ 3066 */
3047 if (modified && !NInoTestSetDirty(ctx->ntfs_ino)) 3067 if (modified) {
3048 mark_ntfs_record_dirty(ctx->ntfs_ino->page, 3068 flush_dcache_mft_record_page(ctx->ntfs_ino);
3049 ctx->ntfs_ino->page_ofs); 3069 if (!NInoTestSetDirty(ctx->ntfs_ino))
3070 mark_ntfs_record_dirty(ctx->ntfs_ino->page,
3071 ctx->ntfs_ino->page_ofs);
3072 }
3050 ntfs_attr_put_search_ctx(ctx); 3073 ntfs_attr_put_search_ctx(ctx);
3051 /* Now the access times are updated, write the base mft record. */ 3074 /* Now the access times are updated, write the base mft record. */
3052 if (NInoDirty(ni)) 3075 if (NInoDirty(ni))
3053 err = write_mft_record(ni, m, sync); 3076 err = write_mft_record(ni, m, sync);
3054 /* Write all attached extent mft records. */ 3077 /* Write all attached extent mft records. */
3055 down(&ni->extent_lock); 3078 mutex_lock(&ni->extent_lock);
3056 if (ni->nr_extents > 0) { 3079 if (ni->nr_extents > 0) {
3057 ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos; 3080 ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos;
3058 int i; 3081 int i;
@@ -3079,7 +3102,7 @@ int ntfs_write_inode(struct inode *vi, int sync)
3079 } 3102 }
3080 } 3103 }
3081 } 3104 }
3082 up(&ni->extent_lock); 3105 mutex_unlock(&ni->extent_lock);
3083 unmap_mft_record(ni); 3106 unmap_mft_record(ni);
3084 if (unlikely(err)) 3107 if (unlikely(err))
3085 goto err_out; 3108 goto err_out;
@@ -3094,9 +3117,7 @@ err_out:
3094 "retries later."); 3117 "retries later.");
3095 mark_inode_dirty(vi); 3118 mark_inode_dirty(vi);
3096 } else { 3119 } else {
3097 ntfs_error(vi->i_sb, "Failed (error code %i): Marking inode " 3120 ntfs_error(vi->i_sb, "Failed (error %i): Run chkdsk.", -err);
3098 "as bad. You should run chkdsk.", -err);
3099 make_bad_inode(vi);
3100 NVolSetErrors(ni->vol); 3121 NVolSetErrors(ni->vol);
3101 } 3122 }
3102 return err; 3123 return err;
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h
index 3de5c0231966..f088291e017c 100644
--- a/fs/ntfs/inode.h
+++ b/fs/ntfs/inode.h
@@ -24,12 +24,13 @@
24#ifndef _LINUX_NTFS_INODE_H 24#ifndef _LINUX_NTFS_INODE_H
25#define _LINUX_NTFS_INODE_H 25#define _LINUX_NTFS_INODE_H
26 26
27#include <linux/mm.h> 27#include <asm/atomic.h>
28
28#include <linux/fs.h> 29#include <linux/fs.h>
29#include <linux/seq_file.h>
30#include <linux/list.h> 30#include <linux/list.h>
31#include <asm/atomic.h> 31#include <linux/mm.h>
32#include <asm/semaphore.h> 32#include <linux/mutex.h>
33#include <linux/seq_file.h>
33 34
34#include "layout.h" 35#include "layout.h"
35#include "volume.h" 36#include "volume.h"
@@ -81,7 +82,7 @@ struct _ntfs_inode {
81 * The following fields are only valid for real inodes and extent 82 * The following fields are only valid for real inodes and extent
82 * inodes. 83 * inodes.
83 */ 84 */
84 struct semaphore mrec_lock; /* Lock for serializing access to the 85 struct mutex mrec_lock; /* Lock for serializing access to the
85 mft record belonging to this inode. */ 86 mft record belonging to this inode. */
86 struct page *page; /* The page containing the mft record of the 87 struct page *page; /* The page containing the mft record of the
87 inode. This should only be touched by the 88 inode. This should only be touched by the
@@ -119,7 +120,7 @@ struct _ntfs_inode {
119 u8 block_clusters; /* Number of clusters per cb. */ 120 u8 block_clusters; /* Number of clusters per cb. */
120 } compressed; 121 } compressed;
121 } itype; 122 } itype;
122 struct semaphore extent_lock; /* Lock for accessing/modifying the 123 struct mutex extent_lock; /* Lock for accessing/modifying the
123 below . */ 124 below . */
124 s32 nr_extents; /* For a base mft record, the number of attached extent 125 s32 nr_extents; /* For a base mft record, the number of attached extent
125 inodes (0 if none), for extent records and for fake 126 inodes (0 if none), for extent records and for fake
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
index bb408d4dcbb0..d34b93cb8b48 100644
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -769,7 +769,7 @@ typedef struct {
769 compressed. (This effectively limits the 769 compressed. (This effectively limits the
770 compression unit size to be a power of two 770 compression unit size to be a power of two
771 clusters.) WinNT4 only uses a value of 4. 771 clusters.) WinNT4 only uses a value of 4.
772 Sparse files also have this set to 4. */ 772 Sparse files have this set to 0 on XPSP2. */
773/* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */ 773/* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */
774/* The sizes below are only used when lowest_vcn is zero, as otherwise it would 774/* The sizes below are only used when lowest_vcn is zero, as otherwise it would
775 be difficult to keep them up-to-date.*/ 775 be difficult to keep them up-to-date.*/
@@ -801,13 +801,16 @@ typedef struct {
801typedef ATTR_RECORD ATTR_REC; 801typedef ATTR_RECORD ATTR_REC;
802 802
803/* 803/*
804 * File attribute flags (32-bit). 804 * File attribute flags (32-bit) appearing in the file_attributes fields of the
805 * STANDARD_INFORMATION attribute of MFT_RECORDs and the FILENAME_ATTR
806 * attributes of MFT_RECORDs and directory index entries.
807 *
808 * All of the below flags appear in the directory index entries but only some
809 * appear in the STANDARD_INFORMATION attribute whilst only some others appear
810 * in the FILENAME_ATTR attribute of MFT_RECORDs. Unless otherwise stated the
811 * flags appear in all of the above.
805 */ 812 */
806enum { 813enum {
807 /*
808 * The following flags are only present in the STANDARD_INFORMATION
809 * attribute (in the field file_attributes).
810 */
811 FILE_ATTR_READONLY = const_cpu_to_le32(0x00000001), 814 FILE_ATTR_READONLY = const_cpu_to_le32(0x00000001),
812 FILE_ATTR_HIDDEN = const_cpu_to_le32(0x00000002), 815 FILE_ATTR_HIDDEN = const_cpu_to_le32(0x00000002),
813 FILE_ATTR_SYSTEM = const_cpu_to_le32(0x00000004), 816 FILE_ATTR_SYSTEM = const_cpu_to_le32(0x00000004),
@@ -839,18 +842,14 @@ enum {
839 F_A_COMPRESSED, and F_A_ENCRYPTED and preserves the rest. This mask 842 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. */ 843 is used to to obtain all flags that are valid for setting. */
841 /* 844 /*
842 * The following flag is only present in the FILE_NAME attribute (in 845 * The flag FILE_ATTR_DUP_FILENAME_INDEX_PRESENT is present in all
843 * the field file_attributes). 846 * FILENAME_ATTR attributes but not in the STANDARD_INFORMATION
847 * attribute of an mft record.
844 */ 848 */
845 FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT = const_cpu_to_le32(0x10000000), 849 FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT = const_cpu_to_le32(0x10000000),
846 /* Note, this is a copy of the corresponding bit from the mft record, 850 /* Note, this is a copy of the corresponding bit from the mft record,
847 telling us whether this is a directory or not, i.e. whether it has 851 telling us whether this is a directory or not, i.e. whether it has
848 an index root attribute or not. */ 852 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 */
854 FILE_ATTR_DUP_VIEW_INDEX_PRESENT = const_cpu_to_le32(0x20000000), 853 FILE_ATTR_DUP_VIEW_INDEX_PRESENT = const_cpu_to_le32(0x20000000),
855 /* Note, this is a copy of the corresponding bit from the mft record, 854 /* Note, this is a copy of the corresponding bit from the mft record,
856 telling us whether this file has a view index present (eg. object id 855 telling us whether this file has a view index present (eg. object id
@@ -891,7 +890,7 @@ typedef struct {
891 Windows this is only updated when 890 Windows this is only updated when
892 accessed if some time delta has 891 accessed if some time delta has
893 passed since the last update. Also, 892 passed since the last update. Also,
894 last access times updates can be 893 last access time updates can be
895 disabled altogether for speed. */ 894 disabled altogether for speed. */
896/* 32*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */ 895/* 32*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */
897/* 36*/ union { 896/* 36*/ union {
@@ -1076,16 +1075,21 @@ typedef struct {
1076/* 20*/ sle64 last_access_time; /* Time this mft record was last 1075/* 20*/ sle64 last_access_time; /* Time this mft record was last
1077 accessed. */ 1076 accessed. */
1078/* 28*/ sle64 allocated_size; /* Byte size of on-disk allocated space 1077/* 28*/ sle64 allocated_size; /* Byte size of on-disk allocated space
1079 for the data attribute. So for 1078 for the unnamed data attribute. So
1080 normal $DATA, this is the 1079 for normal $DATA, this is the
1081 allocated_size from the unnamed 1080 allocated_size from the unnamed
1082 $DATA attribute and for compressed 1081 $DATA attribute and for compressed
1083 and/or sparse $DATA, this is the 1082 and/or sparse $DATA, this is the
1084 compressed_size from the unnamed 1083 compressed_size from the unnamed
1085 $DATA attribute. NOTE: This is a 1084 $DATA attribute. For a directory or
1086 multiple of the cluster size. */ 1085 other inode without an unnamed $DATA
1087/* 30*/ sle64 data_size; /* Byte size of actual data in data 1086 attribute, this is always 0. NOTE:
1088 attribute. */ 1087 This is a multiple of the cluster
1088 size. */
1089/* 30*/ sle64 data_size; /* Byte size of actual data in unnamed
1090 data attribute. For a directory or
1091 other inode without an unnamed $DATA
1092 attribute, this is always 0. */
1089/* 38*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */ 1093/* 38*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */
1090/* 3c*/ union { 1094/* 3c*/ union {
1091 /* 3c*/ struct { 1095 /* 3c*/ struct {
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 6499aafc2258..4e72bc7afdf9 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -93,6 +93,7 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
93 "Run chkdsk.", ni->mft_no); 93 "Run chkdsk.", ni->mft_no);
94 ntfs_unmap_page(page); 94 ntfs_unmap_page(page);
95 page = ERR_PTR(-EIO); 95 page = ERR_PTR(-EIO);
96 NVolSetErrors(vol);
96 } 97 }
97err_out: 98err_out:
98 ni->page = NULL; 99 ni->page = NULL;
@@ -104,8 +105,8 @@ err_out:
104 * map_mft_record - map, pin and lock an mft record 105 * map_mft_record - map, pin and lock an mft record
105 * @ni: ntfs inode whose MFT record to map 106 * @ni: ntfs inode whose MFT record to map
106 * 107 *
107 * First, take the mrec_lock semaphore. We might now be sleeping, while waiting 108 * First, take the mrec_lock mutex. We might now be sleeping, while waiting
108 * for the semaphore if it was already locked by someone else. 109 * for the mutex if it was already locked by someone else.
109 * 110 *
110 * The page of the record is mapped using map_mft_record_page() before being 111 * The page of the record is mapped using map_mft_record_page() before being
111 * returned to the caller. 112 * returned to the caller.
@@ -135,9 +136,9 @@ err_out:
135 * So that code will end up having to own the mrec_lock of all mft 136 * So that code will end up having to own the mrec_lock of all mft
136 * records/inodes present in the page before I/O can proceed. In that case we 137 * records/inodes present in the page before I/O can proceed. In that case we
137 * wouldn't need to bother with PG_locked and PG_uptodate as nobody will be 138 * wouldn't need to bother with PG_locked and PG_uptodate as nobody will be
138 * accessing anything without owning the mrec_lock semaphore. But we do need 139 * accessing anything without owning the mrec_lock mutex. But we do need to
139 * to use them because of the read_cache_page() invocation and the code becomes 140 * use them because of the read_cache_page() invocation and the code becomes so
140 * so much simpler this way that it is well worth it. 141 * much simpler this way that it is well worth it.
141 * 142 *
142 * The mft record is now ours and we return a pointer to it. You need to check 143 * The mft record is now ours and we return a pointer to it. You need to check
143 * the returned pointer with IS_ERR() and if that is true, PTR_ERR() will return 144 * the returned pointer with IS_ERR() and if that is true, PTR_ERR() will return
@@ -160,13 +161,13 @@ MFT_RECORD *map_mft_record(ntfs_inode *ni)
160 atomic_inc(&ni->count); 161 atomic_inc(&ni->count);
161 162
162 /* Serialize access to this mft record. */ 163 /* Serialize access to this mft record. */
163 down(&ni->mrec_lock); 164 mutex_lock(&ni->mrec_lock);
164 165
165 m = map_mft_record_page(ni); 166 m = map_mft_record_page(ni);
166 if (likely(!IS_ERR(m))) 167 if (likely(!IS_ERR(m)))
167 return m; 168 return m;
168 169
169 up(&ni->mrec_lock); 170 mutex_unlock(&ni->mrec_lock);
170 atomic_dec(&ni->count); 171 atomic_dec(&ni->count);
171 ntfs_error(ni->vol->sb, "Failed with error code %lu.", -PTR_ERR(m)); 172 ntfs_error(ni->vol->sb, "Failed with error code %lu.", -PTR_ERR(m));
172 return m; 173 return m;
@@ -217,7 +218,7 @@ void unmap_mft_record(ntfs_inode *ni)
217 ntfs_debug("Entering for mft_no 0x%lx.", ni->mft_no); 218 ntfs_debug("Entering for mft_no 0x%lx.", ni->mft_no);
218 219
219 unmap_mft_record_page(ni); 220 unmap_mft_record_page(ni);
220 up(&ni->mrec_lock); 221 mutex_unlock(&ni->mrec_lock);
221 atomic_dec(&ni->count); 222 atomic_dec(&ni->count);
222 /* 223 /*
223 * If pure ntfs_inode, i.e. no vfs inode attached, we leave it to 224 * If pure ntfs_inode, i.e. no vfs inode attached, we leave it to
@@ -261,7 +262,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
261 * in which case just return it. If not found, add it to the base 262 * in which case just return it. If not found, add it to the base
262 * inode before returning it. 263 * inode before returning it.
263 */ 264 */
264 down(&base_ni->extent_lock); 265 mutex_lock(&base_ni->extent_lock);
265 if (base_ni->nr_extents > 0) { 266 if (base_ni->nr_extents > 0) {
266 extent_nis = base_ni->ext.extent_ntfs_inos; 267 extent_nis = base_ni->ext.extent_ntfs_inos;
267 for (i = 0; i < base_ni->nr_extents; i++) { 268 for (i = 0; i < base_ni->nr_extents; i++) {
@@ -274,7 +275,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
274 } 275 }
275 } 276 }
276 if (likely(ni != NULL)) { 277 if (likely(ni != NULL)) {
277 up(&base_ni->extent_lock); 278 mutex_unlock(&base_ni->extent_lock);
278 atomic_dec(&base_ni->count); 279 atomic_dec(&base_ni->count);
279 /* We found the record; just have to map and return it. */ 280 /* We found the record; just have to map and return it. */
280 m = map_mft_record(ni); 281 m = map_mft_record(ni);
@@ -301,7 +302,7 @@ map_err_out:
301 /* Record wasn't there. Get a new ntfs inode and initialize it. */ 302 /* Record wasn't there. Get a new ntfs inode and initialize it. */
302 ni = ntfs_new_extent_inode(base_ni->vol->sb, mft_no); 303 ni = ntfs_new_extent_inode(base_ni->vol->sb, mft_no);
303 if (unlikely(!ni)) { 304 if (unlikely(!ni)) {
304 up(&base_ni->extent_lock); 305 mutex_unlock(&base_ni->extent_lock);
305 atomic_dec(&base_ni->count); 306 atomic_dec(&base_ni->count);
306 return ERR_PTR(-ENOMEM); 307 return ERR_PTR(-ENOMEM);
307 } 308 }
@@ -312,7 +313,7 @@ map_err_out:
312 /* Now map the record. */ 313 /* Now map the record. */
313 m = map_mft_record(ni); 314 m = map_mft_record(ni);
314 if (IS_ERR(m)) { 315 if (IS_ERR(m)) {
315 up(&base_ni->extent_lock); 316 mutex_unlock(&base_ni->extent_lock);
316 atomic_dec(&base_ni->count); 317 atomic_dec(&base_ni->count);
317 ntfs_clear_extent_inode(ni); 318 ntfs_clear_extent_inode(ni);
318 goto map_err_out; 319 goto map_err_out;
@@ -347,14 +348,14 @@ map_err_out:
347 base_ni->ext.extent_ntfs_inos = tmp; 348 base_ni->ext.extent_ntfs_inos = tmp;
348 } 349 }
349 base_ni->ext.extent_ntfs_inos[base_ni->nr_extents++] = ni; 350 base_ni->ext.extent_ntfs_inos[base_ni->nr_extents++] = ni;
350 up(&base_ni->extent_lock); 351 mutex_unlock(&base_ni->extent_lock);
351 atomic_dec(&base_ni->count); 352 atomic_dec(&base_ni->count);
352 ntfs_debug("Done 2."); 353 ntfs_debug("Done 2.");
353 *ntfs_ino = ni; 354 *ntfs_ino = ni;
354 return m; 355 return m;
355unm_err_out: 356unm_err_out:
356 unmap_mft_record(ni); 357 unmap_mft_record(ni);
357 up(&base_ni->extent_lock); 358 mutex_unlock(&base_ni->extent_lock);
358 atomic_dec(&base_ni->count); 359 atomic_dec(&base_ni->count);
359 /* 360 /*
360 * If the extent inode was not attached to the base inode we need to 361 * If the extent inode was not attached to the base inode we need to
@@ -399,12 +400,12 @@ void __mark_mft_record_dirty(ntfs_inode *ni)
399 BUG_ON(NInoAttr(ni)); 400 BUG_ON(NInoAttr(ni));
400 mark_ntfs_record_dirty(ni->page, ni->page_ofs); 401 mark_ntfs_record_dirty(ni->page, ni->page_ofs);
401 /* Determine the base vfs inode and mark it dirty, too. */ 402 /* Determine the base vfs inode and mark it dirty, too. */
402 down(&ni->extent_lock); 403 mutex_lock(&ni->extent_lock);
403 if (likely(ni->nr_extents >= 0)) 404 if (likely(ni->nr_extents >= 0))
404 base_ni = ni; 405 base_ni = ni;
405 else 406 else
406 base_ni = ni->ext.base_ntfs_ino; 407 base_ni = ni->ext.base_ntfs_ino;
407 up(&ni->extent_lock); 408 mutex_unlock(&ni->extent_lock);
408 __mark_inode_dirty(VFS_I(base_ni), I_DIRTY_SYNC | I_DIRTY_DATASYNC); 409 __mark_inode_dirty(VFS_I(base_ni), I_DIRTY_SYNC | I_DIRTY_DATASYNC);
409} 410}
410 411
@@ -650,10 +651,7 @@ err_out:
650 * fs/ntfs/aops.c::mark_ntfs_record_dirty(). 651 * fs/ntfs/aops.c::mark_ntfs_record_dirty().
651 * 652 *
652 * On success, clean the mft record and return 0. On error, leave the mft 653 * On success, clean the mft record and return 0. On error, leave the mft
653 * record dirty and return -errno. The caller should call make_bad_inode() on 654 * record dirty and return -errno.
654 * the base inode to ensure no more access happens to this inode. We do not do
655 * it here as the caller may want to finish writing other extent mft records
656 * first to minimize on-disk metadata inconsistencies.
657 * 655 *
658 * NOTE: We always perform synchronous i/o and ignore the @sync parameter. 656 * NOTE: We always perform synchronous i/o and ignore the @sync parameter.
659 * However, if the mft record has a counterpart in the mft mirror and @sync is 657 * However, if the mft record has a counterpart in the mft mirror and @sync is
@@ -983,7 +981,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
983 } 981 }
984 ntfs_debug("Inode 0x%lx is not dirty.", mft_no); 982 ntfs_debug("Inode 0x%lx is not dirty.", mft_no);
985 /* The inode is not dirty, try to take the mft record lock. */ 983 /* The inode is not dirty, try to take the mft record lock. */
986 if (unlikely(down_trylock(&ni->mrec_lock))) { 984 if (unlikely(!mutex_trylock(&ni->mrec_lock))) {
987 ntfs_debug("Mft record 0x%lx is already locked, do " 985 ntfs_debug("Mft record 0x%lx is already locked, do "
988 "not write it.", mft_no); 986 "not write it.", mft_no);
989 atomic_dec(&ni->count); 987 atomic_dec(&ni->count);
@@ -1043,13 +1041,13 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
1043 * corresponding to this extent mft record attached. 1041 * corresponding to this extent mft record attached.
1044 */ 1042 */
1045 ni = NTFS_I(vi); 1043 ni = NTFS_I(vi);
1046 down(&ni->extent_lock); 1044 mutex_lock(&ni->extent_lock);
1047 if (ni->nr_extents <= 0) { 1045 if (ni->nr_extents <= 0) {
1048 /* 1046 /*
1049 * The base inode has no attached extent inodes, write this 1047 * The base inode has no attached extent inodes, write this
1050 * extent mft record. 1048 * extent mft record.
1051 */ 1049 */
1052 up(&ni->extent_lock); 1050 mutex_unlock(&ni->extent_lock);
1053 iput(vi); 1051 iput(vi);
1054 ntfs_debug("Base inode 0x%lx has no attached extent inodes, " 1052 ntfs_debug("Base inode 0x%lx has no attached extent inodes, "
1055 "write the extent record.", na.mft_no); 1053 "write the extent record.", na.mft_no);
@@ -1072,7 +1070,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
1072 * extent mft record. 1070 * extent mft record.
1073 */ 1071 */
1074 if (!eni) { 1072 if (!eni) {
1075 up(&ni->extent_lock); 1073 mutex_unlock(&ni->extent_lock);
1076 iput(vi); 1074 iput(vi);
1077 ntfs_debug("Extent inode 0x%lx is not attached to its base " 1075 ntfs_debug("Extent inode 0x%lx is not attached to its base "
1078 "inode 0x%lx, write the extent record.", 1076 "inode 0x%lx, write the extent record.",
@@ -1083,12 +1081,12 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
1083 mft_no, na.mft_no); 1081 mft_no, na.mft_no);
1084 /* Take a reference to the extent ntfs inode. */ 1082 /* Take a reference to the extent ntfs inode. */
1085 atomic_inc(&eni->count); 1083 atomic_inc(&eni->count);
1086 up(&ni->extent_lock); 1084 mutex_unlock(&ni->extent_lock);
1087 /* 1085 /*
1088 * Found the extent inode coresponding to this extent mft record. 1086 * Found the extent inode coresponding to this extent mft record.
1089 * Try to take the mft record lock. 1087 * Try to take the mft record lock.
1090 */ 1088 */
1091 if (unlikely(down_trylock(&eni->mrec_lock))) { 1089 if (unlikely(!mutex_trylock(&eni->mrec_lock))) {
1092 atomic_dec(&eni->count); 1090 atomic_dec(&eni->count);
1093 iput(vi); 1091 iput(vi);
1094 ntfs_debug("Extent mft record 0x%lx is already locked, do " 1092 ntfs_debug("Extent mft record 0x%lx is already locked, do "
@@ -2711,7 +2709,7 @@ mft_rec_already_initialized:
2711 * have its page mapped and it is very easy to do. 2709 * have its page mapped and it is very easy to do.
2712 */ 2710 */
2713 atomic_inc(&ni->count); 2711 atomic_inc(&ni->count);
2714 down(&ni->mrec_lock); 2712 mutex_lock(&ni->mrec_lock);
2715 ni->page = page; 2713 ni->page = page;
2716 ni->page_ofs = ofs; 2714 ni->page_ofs = ofs;
2717 /* 2715 /*
@@ -2798,22 +2796,22 @@ int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m)
2798 BUG_ON(NInoAttr(ni)); 2796 BUG_ON(NInoAttr(ni));
2799 BUG_ON(ni->nr_extents != -1); 2797 BUG_ON(ni->nr_extents != -1);
2800 2798
2801 down(&ni->extent_lock); 2799 mutex_lock(&ni->extent_lock);
2802 base_ni = ni->ext.base_ntfs_ino; 2800 base_ni = ni->ext.base_ntfs_ino;
2803 up(&ni->extent_lock); 2801 mutex_unlock(&ni->extent_lock);
2804 2802
2805 BUG_ON(base_ni->nr_extents <= 0); 2803 BUG_ON(base_ni->nr_extents <= 0);
2806 2804
2807 ntfs_debug("Entering for extent inode 0x%lx, base inode 0x%lx.\n", 2805 ntfs_debug("Entering for extent inode 0x%lx, base inode 0x%lx.\n",
2808 mft_no, base_ni->mft_no); 2806 mft_no, base_ni->mft_no);
2809 2807
2810 down(&base_ni->extent_lock); 2808 mutex_lock(&base_ni->extent_lock);
2811 2809
2812 /* Make sure we are holding the only reference to the extent inode. */ 2810 /* Make sure we are holding the only reference to the extent inode. */
2813 if (atomic_read(&ni->count) > 2) { 2811 if (atomic_read(&ni->count) > 2) {
2814 ntfs_error(vol->sb, "Tried to free busy extent inode 0x%lx, " 2812 ntfs_error(vol->sb, "Tried to free busy extent inode 0x%lx, "
2815 "not freeing.", base_ni->mft_no); 2813 "not freeing.", base_ni->mft_no);
2816 up(&base_ni->extent_lock); 2814 mutex_unlock(&base_ni->extent_lock);
2817 return -EBUSY; 2815 return -EBUSY;
2818 } 2816 }
2819 2817
@@ -2831,7 +2829,7 @@ int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m)
2831 break; 2829 break;
2832 } 2830 }
2833 2831
2834 up(&base_ni->extent_lock); 2832 mutex_unlock(&base_ni->extent_lock);
2835 2833
2836 if (unlikely(err)) { 2834 if (unlikely(err)) {
2837 ntfs_error(vol->sb, "Extent inode 0x%lx is not attached to " 2835 ntfs_error(vol->sb, "Extent inode 0x%lx is not attached to "
@@ -2890,7 +2888,7 @@ rollback_error:
2890 return 0; 2888 return 0;
2891rollback: 2889rollback:
2892 /* Rollback what we did... */ 2890 /* Rollback what we did... */
2893 down(&base_ni->extent_lock); 2891 mutex_lock(&base_ni->extent_lock);
2894 extent_nis = base_ni->ext.extent_ntfs_inos; 2892 extent_nis = base_ni->ext.extent_ntfs_inos;
2895 if (!(base_ni->nr_extents & 3)) { 2893 if (!(base_ni->nr_extents & 3)) {
2896 int new_size = (base_ni->nr_extents + 4) * sizeof(ntfs_inode*); 2894 int new_size = (base_ni->nr_extents + 4) * sizeof(ntfs_inode*);
@@ -2899,7 +2897,7 @@ rollback:
2899 if (unlikely(!extent_nis)) { 2897 if (unlikely(!extent_nis)) {
2900 ntfs_error(vol->sb, "Failed to allocate internal " 2898 ntfs_error(vol->sb, "Failed to allocate internal "
2901 "buffer during rollback.%s", es); 2899 "buffer during rollback.%s", es);
2902 up(&base_ni->extent_lock); 2900 mutex_unlock(&base_ni->extent_lock);
2903 NVolSetErrors(vol); 2901 NVolSetErrors(vol);
2904 goto rollback_error; 2902 goto rollback_error;
2905 } 2903 }
@@ -2914,7 +2912,7 @@ rollback:
2914 m->flags |= MFT_RECORD_IN_USE; 2912 m->flags |= MFT_RECORD_IN_USE;
2915 m->sequence_number = old_seq_no; 2913 m->sequence_number = old_seq_no;
2916 extent_nis[base_ni->nr_extents++] = ni; 2914 extent_nis[base_ni->nr_extents++] = ni;
2917 up(&base_ni->extent_lock); 2915 mutex_unlock(&base_ni->extent_lock);
2918 mark_mft_record_dirty(ni); 2916 mark_mft_record_dirty(ni);
2919 return err; 2917 return err;
2920} 2918}
diff --git a/fs/ntfs/mft.h b/fs/ntfs/mft.h
index 407de2cef1d6..639cd1bab08b 100644
--- a/fs/ntfs/mft.h
+++ b/fs/ntfs/mft.h
@@ -97,10 +97,7 @@ extern int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync);
97 * uptodate. 97 * uptodate.
98 * 98 *
99 * On success, clean the mft record and return 0. On error, leave the mft 99 * On success, clean the mft record and return 0. On error, leave the mft
100 * record dirty and return -errno. The caller should call make_bad_inode() on 100 * record dirty and return -errno.
101 * the base inode to ensure no more access happens to this inode. We do not do
102 * it here as the caller may want to finish writing other extent mft records
103 * first to minimize on-disk metadata inconsistencies.
104 */ 101 */
105static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync) 102static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync)
106{ 103{
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c
index 5ea9eb93af62..eddb2247cec5 100644
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -2,7 +2,7 @@
2 * namei.c - NTFS kernel directory inode operations. Part of the Linux-NTFS 2 * namei.c - NTFS kernel directory inode operations. Part of the Linux-NTFS
3 * project. 3 * project.
4 * 4 *
5 * Copyright (c) 2001-2004 Anton Altaparmakov 5 * Copyright (c) 2001-2006 Anton Altaparmakov
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
8 * modify it under the terms of the GNU General Public License as published 8 * modify it under the terms of the GNU General Public License as published
@@ -115,7 +115,9 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
115 uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len, 115 uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len,
116 &uname); 116 &uname);
117 if (uname_len < 0) { 117 if (uname_len < 0) {
118 ntfs_error(vol->sb, "Failed to convert name to Unicode."); 118 if (uname_len != -ENAMETOOLONG)
119 ntfs_error(vol->sb, "Failed to convert name to "
120 "Unicode.");
119 return ERR_PTR(uname_len); 121 return ERR_PTR(uname_len);
120 } 122 }
121 mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len, 123 mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len,
@@ -157,7 +159,7 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
157 /* Return the error code. */ 159 /* Return the error code. */
158 return (struct dentry *)dent_inode; 160 return (struct dentry *)dent_inode;
159 } 161 }
160 /* It is guaranteed that name is no longer allocated at this point. */ 162 /* It is guaranteed that @name is no longer allocated at this point. */
161 if (MREF_ERR(mref) == -ENOENT) { 163 if (MREF_ERR(mref) == -ENOENT) {
162 ntfs_debug("Entry was not found, adding negative dentry."); 164 ntfs_debug("Entry was not found, adding negative dentry.");
163 /* The dcache will handle negative entries. */ 165 /* The dcache will handle negative entries. */
@@ -168,7 +170,6 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
168 ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error " 170 ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error "
169 "code %i.", -MREF_ERR(mref)); 171 "code %i.", -MREF_ERR(mref));
170 return ERR_PTR(MREF_ERR(mref)); 172 return ERR_PTR(MREF_ERR(mref));
171
172 // TODO: Consider moving this lot to a separate function! (AIA) 173 // TODO: Consider moving this lot to a separate function! (AIA)
173handle_name: 174handle_name:
174 { 175 {
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
index 653d2a5c4899..0624c8ef4d9c 100644
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -91,7 +91,7 @@ extern void free_compression_buffers(void);
91 91
92/* From fs/ntfs/super.c */ 92/* From fs/ntfs/super.c */
93#define default_upcase_len 0x10000 93#define default_upcase_len 0x10000
94extern struct semaphore ntfs_lock; 94extern struct mutex ntfs_lock;
95 95
96typedef struct { 96typedef struct {
97 int val; 97 int val;
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
index 061b5ff6b73c..eb52b801512b 100644
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -381,6 +381,7 @@ static inline runlist_element *ntfs_rl_insert(runlist_element *dst,
381static inline runlist_element *ntfs_rl_replace(runlist_element *dst, 381static inline runlist_element *ntfs_rl_replace(runlist_element *dst,
382 int dsize, runlist_element *src, int ssize, int loc) 382 int dsize, runlist_element *src, int ssize, int loc)
383{ 383{
384 signed delta;
384 BOOL left = FALSE; /* Left end of @src needs merging. */ 385 BOOL left = FALSE; /* Left end of @src needs merging. */
385 BOOL right = FALSE; /* Right end of @src needs merging. */ 386 BOOL right = FALSE; /* Right end of @src needs merging. */
386 int tail; /* Start of tail of @dst. */ 387 int tail; /* Start of tail of @dst. */
@@ -396,11 +397,14 @@ static inline runlist_element *ntfs_rl_replace(runlist_element *dst,
396 left = ntfs_are_rl_mergeable(dst + loc - 1, src); 397 left = ntfs_are_rl_mergeable(dst + loc - 1, src);
397 /* 398 /*
398 * Allocate some space. We will need less if the left, right, or both 399 * Allocate some space. We will need less if the left, right, or both
399 * ends get merged. 400 * ends get merged. The -1 accounts for the run being replaced.
400 */ 401 */
401 dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left - right); 402 delta = ssize - 1 - left - right;
402 if (IS_ERR(dst)) 403 if (delta > 0) {
403 return dst; 404 dst = ntfs_rl_realloc(dst, dsize, dsize + delta);
405 if (IS_ERR(dst))
406 return dst;
407 }
404 /* 408 /*
405 * We are guaranteed to succeed from here so can start modifying the 409 * We are guaranteed to succeed from here so can start modifying the
406 * original runlists. 410 * original runlists.
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 368a8ec10668..7646b5059389 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1099,26 +1099,38 @@ static BOOL check_mft_mirror(ntfs_volume *vol)
1099 kmirr = page_address(mirr_page); 1099 kmirr = page_address(mirr_page);
1100 ++index; 1100 ++index;
1101 } 1101 }
1102 /* Make sure the record is ok. */ 1102 /* Do not check the record if it is not in use. */
1103 if (ntfs_is_baad_recordp((le32*)kmft)) { 1103 if (((MFT_RECORD*)kmft)->flags & MFT_RECORD_IN_USE) {
1104 ntfs_error(sb, "Incomplete multi sector transfer " 1104 /* Make sure the record is ok. */
1105 "detected in mft record %i.", i); 1105 if (ntfs_is_baad_recordp((le32*)kmft)) {
1106 ntfs_error(sb, "Incomplete multi sector "
1107 "transfer detected in mft "
1108 "record %i.", i);
1106mm_unmap_out: 1109mm_unmap_out:
1107 ntfs_unmap_page(mirr_page); 1110 ntfs_unmap_page(mirr_page);
1108mft_unmap_out: 1111mft_unmap_out:
1109 ntfs_unmap_page(mft_page); 1112 ntfs_unmap_page(mft_page);
1110 return FALSE; 1113 return FALSE;
1114 }
1111 } 1115 }
1112 if (ntfs_is_baad_recordp((le32*)kmirr)) { 1116 /* Do not check the mirror record if it is not in use. */
1113 ntfs_error(sb, "Incomplete multi sector transfer " 1117 if (((MFT_RECORD*)kmirr)->flags & MFT_RECORD_IN_USE) {
1114 "detected in mft mirror record %i.", i); 1118 if (ntfs_is_baad_recordp((le32*)kmirr)) {
1115 goto mm_unmap_out; 1119 ntfs_error(sb, "Incomplete multi sector "
1120 "transfer detected in mft "
1121 "mirror record %i.", i);
1122 goto mm_unmap_out;
1123 }
1116 } 1124 }
1117 /* Get the amount of data in the current record. */ 1125 /* Get the amount of data in the current record. */
1118 bytes = le32_to_cpu(((MFT_RECORD*)kmft)->bytes_in_use); 1126 bytes = le32_to_cpu(((MFT_RECORD*)kmft)->bytes_in_use);
1119 if (!bytes || bytes > vol->mft_record_size) { 1127 if (bytes < sizeof(MFT_RECORD_OLD) ||
1128 bytes > vol->mft_record_size ||
1129 ntfs_is_baad_recordp((le32*)kmft)) {
1120 bytes = le32_to_cpu(((MFT_RECORD*)kmirr)->bytes_in_use); 1130 bytes = le32_to_cpu(((MFT_RECORD*)kmirr)->bytes_in_use);
1121 if (!bytes || bytes > vol->mft_record_size) 1131 if (bytes < sizeof(MFT_RECORD_OLD) ||
1132 bytes > vol->mft_record_size ||
1133 ntfs_is_baad_recordp((le32*)kmirr))
1122 bytes = vol->mft_record_size; 1134 bytes = vol->mft_record_size;
1123 } 1135 }
1124 /* Compare the two records. */ 1136 /* Compare the two records. */
@@ -1665,11 +1677,11 @@ read_partial_upcase_page:
1665 ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).", 1677 ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).",
1666 i_size, 64 * 1024 * sizeof(ntfschar)); 1678 i_size, 64 * 1024 * sizeof(ntfschar));
1667 iput(ino); 1679 iput(ino);
1668 down(&ntfs_lock); 1680 mutex_lock(&ntfs_lock);
1669 if (!default_upcase) { 1681 if (!default_upcase) {
1670 ntfs_debug("Using volume specified $UpCase since default is " 1682 ntfs_debug("Using volume specified $UpCase since default is "
1671 "not present."); 1683 "not present.");
1672 up(&ntfs_lock); 1684 mutex_unlock(&ntfs_lock);
1673 return TRUE; 1685 return TRUE;
1674 } 1686 }
1675 max = default_upcase_len; 1687 max = default_upcase_len;
@@ -1683,12 +1695,12 @@ read_partial_upcase_page:
1683 vol->upcase = default_upcase; 1695 vol->upcase = default_upcase;
1684 vol->upcase_len = max; 1696 vol->upcase_len = max;
1685 ntfs_nr_upcase_users++; 1697 ntfs_nr_upcase_users++;
1686 up(&ntfs_lock); 1698 mutex_unlock(&ntfs_lock);
1687 ntfs_debug("Volume specified $UpCase matches default. Using " 1699 ntfs_debug("Volume specified $UpCase matches default. Using "
1688 "default."); 1700 "default.");
1689 return TRUE; 1701 return TRUE;
1690 } 1702 }
1691 up(&ntfs_lock); 1703 mutex_unlock(&ntfs_lock);
1692 ntfs_debug("Using volume specified $UpCase since it does not match " 1704 ntfs_debug("Using volume specified $UpCase since it does not match "
1693 "the default."); 1705 "the default.");
1694 return TRUE; 1706 return TRUE;
@@ -1697,17 +1709,17 @@ iput_upcase_failed:
1697 ntfs_free(vol->upcase); 1709 ntfs_free(vol->upcase);
1698 vol->upcase = NULL; 1710 vol->upcase = NULL;
1699upcase_failed: 1711upcase_failed:
1700 down(&ntfs_lock); 1712 mutex_lock(&ntfs_lock);
1701 if (default_upcase) { 1713 if (default_upcase) {
1702 vol->upcase = default_upcase; 1714 vol->upcase = default_upcase;
1703 vol->upcase_len = default_upcase_len; 1715 vol->upcase_len = default_upcase_len;
1704 ntfs_nr_upcase_users++; 1716 ntfs_nr_upcase_users++;
1705 up(&ntfs_lock); 1717 mutex_unlock(&ntfs_lock);
1706 ntfs_error(sb, "Failed to load $UpCase from the volume. Using " 1718 ntfs_error(sb, "Failed to load $UpCase from the volume. Using "
1707 "default."); 1719 "default.");
1708 return TRUE; 1720 return TRUE;
1709 } 1721 }
1710 up(&ntfs_lock); 1722 mutex_unlock(&ntfs_lock);
1711 ntfs_error(sb, "Failed to initialize upcase table."); 1723 ntfs_error(sb, "Failed to initialize upcase table.");
1712 return FALSE; 1724 return FALSE;
1713} 1725}
@@ -2183,12 +2195,12 @@ iput_attrdef_err_out:
2183iput_upcase_err_out: 2195iput_upcase_err_out:
2184#endif /* NTFS_RW */ 2196#endif /* NTFS_RW */
2185 vol->upcase_len = 0; 2197 vol->upcase_len = 0;
2186 down(&ntfs_lock); 2198 mutex_lock(&ntfs_lock);
2187 if (vol->upcase == default_upcase) { 2199 if (vol->upcase == default_upcase) {
2188 ntfs_nr_upcase_users--; 2200 ntfs_nr_upcase_users--;
2189 vol->upcase = NULL; 2201 vol->upcase = NULL;
2190 } 2202 }
2191 up(&ntfs_lock); 2203 mutex_unlock(&ntfs_lock);
2192 if (vol->upcase) { 2204 if (vol->upcase) {
2193 ntfs_free(vol->upcase); 2205 ntfs_free(vol->upcase);
2194 vol->upcase = NULL; 2206 vol->upcase = NULL;
@@ -2393,7 +2405,7 @@ static void ntfs_put_super(struct super_block *sb)
2393 * Destroy the global default upcase table if necessary. Also decrease 2405 * Destroy the global default upcase table if necessary. Also decrease
2394 * the number of upcase users if we are a user. 2406 * the number of upcase users if we are a user.
2395 */ 2407 */
2396 down(&ntfs_lock); 2408 mutex_lock(&ntfs_lock);
2397 if (vol->upcase == default_upcase) { 2409 if (vol->upcase == default_upcase) {
2398 ntfs_nr_upcase_users--; 2410 ntfs_nr_upcase_users--;
2399 vol->upcase = NULL; 2411 vol->upcase = NULL;
@@ -2404,7 +2416,7 @@ static void ntfs_put_super(struct super_block *sb)
2404 } 2416 }
2405 if (vol->cluster_size <= 4096 && !--ntfs_nr_compression_users) 2417 if (vol->cluster_size <= 4096 && !--ntfs_nr_compression_users)
2406 free_compression_buffers(); 2418 free_compression_buffers();
2407 up(&ntfs_lock); 2419 mutex_unlock(&ntfs_lock);
2408 if (vol->upcase) { 2420 if (vol->upcase) {
2409 ntfs_free(vol->upcase); 2421 ntfs_free(vol->upcase);
2410 vol->upcase = NULL; 2422 vol->upcase = NULL;
@@ -2878,7 +2890,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2878 ntfs_error(sb, "Failed to load essential metadata."); 2890 ntfs_error(sb, "Failed to load essential metadata.");
2879 goto iput_tmp_ino_err_out_now; 2891 goto iput_tmp_ino_err_out_now;
2880 } 2892 }
2881 down(&ntfs_lock); 2893 mutex_lock(&ntfs_lock);
2882 /* 2894 /*
2883 * The current mount is a compression user if the cluster size is 2895 * The current mount is a compression user if the cluster size is
2884 * less than or equal 4kiB. 2896 * less than or equal 4kiB.
@@ -2889,7 +2901,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2889 ntfs_error(NULL, "Failed to allocate buffers " 2901 ntfs_error(NULL, "Failed to allocate buffers "
2890 "for compression engine."); 2902 "for compression engine.");
2891 ntfs_nr_compression_users--; 2903 ntfs_nr_compression_users--;
2892 up(&ntfs_lock); 2904 mutex_unlock(&ntfs_lock);
2893 goto iput_tmp_ino_err_out_now; 2905 goto iput_tmp_ino_err_out_now;
2894 } 2906 }
2895 } 2907 }
@@ -2901,7 +2913,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2901 if (!default_upcase) 2913 if (!default_upcase)
2902 default_upcase = generate_default_upcase(); 2914 default_upcase = generate_default_upcase();
2903 ntfs_nr_upcase_users++; 2915 ntfs_nr_upcase_users++;
2904 up(&ntfs_lock); 2916 mutex_unlock(&ntfs_lock);
2905 /* 2917 /*
2906 * From now on, ignore @silent parameter. If we fail below this line, 2918 * From now on, ignore @silent parameter. If we fail below this line,
2907 * it will be due to a corrupt fs or a system error, so we report it. 2919 * it will be due to a corrupt fs or a system error, so we report it.
@@ -2919,12 +2931,12 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2919 atomic_inc(&vol->root_ino->i_count); 2931 atomic_inc(&vol->root_ino->i_count);
2920 ntfs_debug("Exiting, status successful."); 2932 ntfs_debug("Exiting, status successful.");
2921 /* Release the default upcase if it has no users. */ 2933 /* Release the default upcase if it has no users. */
2922 down(&ntfs_lock); 2934 mutex_lock(&ntfs_lock);
2923 if (!--ntfs_nr_upcase_users && default_upcase) { 2935 if (!--ntfs_nr_upcase_users && default_upcase) {
2924 ntfs_free(default_upcase); 2936 ntfs_free(default_upcase);
2925 default_upcase = NULL; 2937 default_upcase = NULL;
2926 } 2938 }
2927 up(&ntfs_lock); 2939 mutex_unlock(&ntfs_lock);
2928 sb->s_export_op = &ntfs_export_ops; 2940 sb->s_export_op = &ntfs_export_ops;
2929 lock_kernel(); 2941 lock_kernel();
2930 return 0; 2942 return 0;
@@ -2992,12 +3004,12 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2992 vol->attrdef = NULL; 3004 vol->attrdef = NULL;
2993 } 3005 }
2994 vol->upcase_len = 0; 3006 vol->upcase_len = 0;
2995 down(&ntfs_lock); 3007 mutex_lock(&ntfs_lock);
2996 if (vol->upcase == default_upcase) { 3008 if (vol->upcase == default_upcase) {
2997 ntfs_nr_upcase_users--; 3009 ntfs_nr_upcase_users--;
2998 vol->upcase = NULL; 3010 vol->upcase = NULL;
2999 } 3011 }
3000 up(&ntfs_lock); 3012 mutex_unlock(&ntfs_lock);
3001 if (vol->upcase) { 3013 if (vol->upcase) {
3002 ntfs_free(vol->upcase); 3014 ntfs_free(vol->upcase);
3003 vol->upcase = NULL; 3015 vol->upcase = NULL;
@@ -3012,14 +3024,14 @@ unl_upcase_iput_tmp_ino_err_out_now:
3012 * Decrease the number of upcase users and destroy the global default 3024 * Decrease the number of upcase users and destroy the global default
3013 * upcase table if necessary. 3025 * upcase table if necessary.
3014 */ 3026 */
3015 down(&ntfs_lock); 3027 mutex_lock(&ntfs_lock);
3016 if (!--ntfs_nr_upcase_users && default_upcase) { 3028 if (!--ntfs_nr_upcase_users && default_upcase) {
3017 ntfs_free(default_upcase); 3029 ntfs_free(default_upcase);
3018 default_upcase = NULL; 3030 default_upcase = NULL;
3019 } 3031 }
3020 if (vol->cluster_size <= 4096 && !--ntfs_nr_compression_users) 3032 if (vol->cluster_size <= 4096 && !--ntfs_nr_compression_users)
3021 free_compression_buffers(); 3033 free_compression_buffers();
3022 up(&ntfs_lock); 3034 mutex_unlock(&ntfs_lock);
3023iput_tmp_ino_err_out_now: 3035iput_tmp_ino_err_out_now:
3024 iput(tmp_ino); 3036 iput(tmp_ino);
3025 if (vol->mft_ino && vol->mft_ino != tmp_ino) 3037 if (vol->mft_ino && vol->mft_ino != tmp_ino)
@@ -3078,8 +3090,8 @@ static void ntfs_big_inode_init_once(void *foo, struct kmem_cache *cachep,
3078struct kmem_cache *ntfs_attr_ctx_cache; 3090struct kmem_cache *ntfs_attr_ctx_cache;
3079struct kmem_cache *ntfs_index_ctx_cache; 3091struct kmem_cache *ntfs_index_ctx_cache;
3080 3092
3081/* Driver wide semaphore. */ 3093/* Driver wide mutex. */
3082DECLARE_MUTEX(ntfs_lock); 3094DEFINE_MUTEX(ntfs_lock);
3083 3095
3084static struct super_block *ntfs_get_sb(struct file_system_type *fs_type, 3096static struct super_block *ntfs_get_sb(struct file_system_type *fs_type,
3085 int flags, const char *dev_name, void *data) 3097 int flags, const char *dev_name, void *data)
@@ -3234,7 +3246,7 @@ static void __exit exit_ntfs_fs(void)
3234} 3246}
3235 3247
3236MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); 3248MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>");
3237MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2005 Anton Altaparmakov"); 3249MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2006 Anton Altaparmakov");
3238MODULE_VERSION(NTFS_VERSION); 3250MODULE_VERSION(NTFS_VERSION);
3239MODULE_LICENSE("GPL"); 3251MODULE_LICENSE("GPL");
3240#ifdef DEBUG 3252#ifdef DEBUG
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c
index 0ea887fc859c..b123c0fa6bf6 100644
--- a/fs/ntfs/unistr.c
+++ b/fs/ntfs/unistr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project. 2 * unistr.c - NTFS Unicode string handling. 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
@@ -19,6 +19,8 @@
19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/slab.h>
23
22#include "types.h" 24#include "types.h"
23#include "debug.h" 25#include "debug.h"
24#include "ntfs.h" 26#include "ntfs.h"
@@ -242,7 +244,7 @@ int ntfs_file_compare_values(FILE_NAME_ATTR *file_name_attr1,
242 * map dictates, into a little endian, 2-byte Unicode string. 244 * map dictates, into a little endian, 2-byte Unicode string.
243 * 245 *
244 * This function allocates the string and the caller is responsible for 246 * This function allocates the string and the caller is responsible for
245 * calling kmem_cache_free(ntfs_name_cache, @outs); when finished with it. 247 * calling kmem_cache_free(ntfs_name_cache, *@outs); when finished with it.
246 * 248 *
247 * On success the function returns the number of Unicode characters written to 249 * On success the function returns the number of Unicode characters written to
248 * the output string *@outs (>= 0), not counting the terminating Unicode NULL 250 * the output string *@outs (>= 0), not counting the terminating Unicode NULL
@@ -262,37 +264,48 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins,
262 wchar_t wc; 264 wchar_t wc;
263 int i, o, wc_len; 265 int i, o, wc_len;
264 266
265 /* We don't trust outside sources. */ 267 /* We do not trust outside sources. */
266 if (ins) { 268 if (likely(ins)) {
267 ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); 269 ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS);
268 if (ucs) { 270 if (likely(ucs)) {
269 for (i = o = 0; i < ins_len; i += wc_len) { 271 for (i = o = 0; i < ins_len; i += wc_len) {
270 wc_len = nls->char2uni(ins + i, ins_len - i, 272 wc_len = nls->char2uni(ins + i, ins_len - i,
271 &wc); 273 &wc);
272 if (wc_len >= 0) { 274 if (likely(wc_len >= 0 &&
273 if (wc) { 275 o < NTFS_MAX_NAME_LEN)) {
276 if (likely(wc)) {
274 ucs[o++] = cpu_to_le16(wc); 277 ucs[o++] = cpu_to_le16(wc);
275 continue; 278 continue;
276 } /* else (!wc) */ 279 } /* else if (!wc) */
277 break; 280 break;
278 } /* else (wc_len < 0) */ 281 } /* else if (wc_len < 0 ||
279 goto conversion_err; 282 o >= NTFS_MAX_NAME_LEN) */
283 goto name_err;
280 } 284 }
281 ucs[o] = 0; 285 ucs[o] = 0;
282 *outs = ucs; 286 *outs = ucs;
283 return o; 287 return o;
284 } /* else (!ucs) */ 288 } /* else if (!ucs) */
285 ntfs_error(vol->sb, "Failed to allocate name from " 289 ntfs_error(vol->sb, "Failed to allocate buffer for converted "
286 "ntfs_name_cache!"); 290 "name from ntfs_name_cache.");
287 return -ENOMEM; 291 return -ENOMEM;
288 } /* else (!ins) */ 292 } /* else if (!ins) */
289 ntfs_error(NULL, "Received NULL pointer."); 293 ntfs_error(vol->sb, "Received NULL pointer.");
290 return -EINVAL; 294 return -EINVAL;
291conversion_err: 295name_err:
292 ntfs_error(vol->sb, "Name using character set %s contains characters "
293 "that cannot be converted to Unicode.", nls->charset);
294 kmem_cache_free(ntfs_name_cache, ucs); 296 kmem_cache_free(ntfs_name_cache, ucs);
295 return -EILSEQ; 297 if (wc_len < 0) {
298 ntfs_error(vol->sb, "Name using character set %s contains "
299 "characters that cannot be converted to "
300 "Unicode.", nls->charset);
301 i = -EILSEQ;
302 } else /* if (o >= NTFS_MAX_NAME_LEN) */ {
303 ntfs_error(vol->sb, "Name is too long (maximum length for a "
304 "name on NTFS is %d Unicode characters.",
305 NTFS_MAX_NAME_LEN);
306 i = -ENAMETOOLONG;
307 }
308 return i;
296} 309}
297 310
298/** 311/**