kmirr = page_address(mirr_page);
++index;
}
- /* Make sure the record is ok. */
- if (ntfs_is_baad_recordp((le32*)kmft)) {
- ntfs_error(sb, "Incomplete multi sector transfer "
- "detected in mft record %i.", i);
+ /* Do not check the record if it is not in use. */
+ if (((MFT_RECORD*)kmft)->flags & MFT_RECORD_IN_USE) {
+ /* Make sure the record is ok. */
+ if (ntfs_is_baad_recordp((le32*)kmft)) {
+ ntfs_error(sb, "Incomplete multi sector "
+ "transfer detected in mft "
+ "record %i.", i);
mm_unmap_out:
- ntfs_unmap_page(mirr_page);
+ ntfs_unmap_page(mirr_page);
mft_unmap_out:
- ntfs_unmap_page(mft_page);
- return FALSE;
+ ntfs_unmap_page(mft_page);
+ return FALSE;
+ }
}
- if (ntfs_is_baad_recordp((le32*)kmirr)) {
- ntfs_error(sb, "Incomplete multi sector transfer "
- "detected in mft mirror record %i.", i);
- goto mm_unmap_out;
+ /* Do not check the mirror record if it is not in use. */
+ if (((MFT_RECORD*)kmirr)->flags & MFT_RECORD_IN_USE) {
+ if (ntfs_is_baad_recordp((le32*)kmirr)) {
+ ntfs_error(sb, "Incomplete multi sector "
+ "transfer detected in mft "
+ "mirror record %i.", i);
+ goto mm_unmap_out;
+ }
}
/* Get the amount of data in the current record. */
bytes = le32_to_cpu(((MFT_RECORD*)kmft)->bytes_in_use);
- if (!bytes || bytes > vol->mft_record_size) {
+ if (bytes < sizeof(MFT_RECORD_OLD) ||
+ bytes > vol->mft_record_size ||
+ ntfs_is_baad_recordp((le32*)kmft)) {
bytes = le32_to_cpu(((MFT_RECORD*)kmirr)->bytes_in_use);
- if (!bytes || bytes > vol->mft_record_size)
+ if (bytes < sizeof(MFT_RECORD_OLD) ||
+ bytes > vol->mft_record_size ||
+ ntfs_is_baad_recordp((le32*)kmirr))
bytes = vol->mft_record_size;
}
/* Compare the two records. */
ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).",
i_size, 64 * 1024 * sizeof(ntfschar));
iput(ino);
- down(&ntfs_lock);
+ mutex_lock(&ntfs_lock);
if (!default_upcase) {
ntfs_debug("Using volume specified $UpCase since default is "
"not present.");
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
return TRUE;
}
max = default_upcase_len;
vol->upcase = default_upcase;
vol->upcase_len = max;
ntfs_nr_upcase_users++;
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
ntfs_debug("Volume specified $UpCase matches default. Using "
"default.");
return TRUE;
}
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
ntfs_debug("Using volume specified $UpCase since it does not match "
"the default.");
return TRUE;
ntfs_free(vol->upcase);
vol->upcase = NULL;
upcase_failed:
- down(&ntfs_lock);
+ mutex_lock(&ntfs_lock);
if (default_upcase) {
vol->upcase = default_upcase;
vol->upcase_len = default_upcase_len;
ntfs_nr_upcase_users++;
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
ntfs_error(sb, "Failed to load $UpCase from the volume. Using "
"default.");
return TRUE;
}
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
ntfs_error(sb, "Failed to initialize upcase table.");
return FALSE;
}
iput_upcase_err_out:
#endif /* NTFS_RW */
vol->upcase_len = 0;
- down(&ntfs_lock);
+ mutex_lock(&ntfs_lock);
if (vol->upcase == default_upcase) {
ntfs_nr_upcase_users--;
vol->upcase = NULL;
}
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
if (vol->upcase) {
ntfs_free(vol->upcase);
vol->upcase = NULL;
* Destroy the global default upcase table if necessary. Also decrease
* the number of upcase users if we are a user.
*/
- down(&ntfs_lock);
+ mutex_lock(&ntfs_lock);
if (vol->upcase == default_upcase) {
ntfs_nr_upcase_users--;
vol->upcase = NULL;
}
if (vol->cluster_size <= 4096 && !--ntfs_nr_compression_users)
free_compression_buffers();
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
if (vol->upcase) {
ntfs_free(vol->upcase);
vol->upcase = NULL;
ntfs_error(sb, "Failed to load essential metadata.");
goto iput_tmp_ino_err_out_now;
}
- down(&ntfs_lock);
+ mutex_lock(&ntfs_lock);
/*
* The current mount is a compression user if the cluster size is
* less than or equal 4kiB.
ntfs_error(NULL, "Failed to allocate buffers "
"for compression engine.");
ntfs_nr_compression_users--;
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
goto iput_tmp_ino_err_out_now;
}
}
if (!default_upcase)
default_upcase = generate_default_upcase();
ntfs_nr_upcase_users++;
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
/*
* From now on, ignore @silent parameter. If we fail below this line,
* it will be due to a corrupt fs or a system error, so we report it.
atomic_inc(&vol->root_ino->i_count);
ntfs_debug("Exiting, status successful.");
/* Release the default upcase if it has no users. */
- down(&ntfs_lock);
+ mutex_lock(&ntfs_lock);
if (!--ntfs_nr_upcase_users && default_upcase) {
ntfs_free(default_upcase);
default_upcase = NULL;
}
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
sb->s_export_op = &ntfs_export_ops;
lock_kernel();
return 0;
vol->attrdef = NULL;
}
vol->upcase_len = 0;
- down(&ntfs_lock);
+ mutex_lock(&ntfs_lock);
if (vol->upcase == default_upcase) {
ntfs_nr_upcase_users--;
vol->upcase = NULL;
}
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
if (vol->upcase) {
ntfs_free(vol->upcase);
vol->upcase = NULL;
* Decrease the number of upcase users and destroy the global default
* upcase table if necessary.
*/
- down(&ntfs_lock);
+ mutex_lock(&ntfs_lock);
if (!--ntfs_nr_upcase_users && default_upcase) {
ntfs_free(default_upcase);
default_upcase = NULL;
}
if (vol->cluster_size <= 4096 && !--ntfs_nr_compression_users)
free_compression_buffers();
- up(&ntfs_lock);
+ mutex_unlock(&ntfs_lock);
iput_tmp_ino_err_out_now:
iput(tmp_ino);
if (vol->mft_ino && vol->mft_ino != tmp_ino)
struct kmem_cache *ntfs_attr_ctx_cache;
struct kmem_cache *ntfs_index_ctx_cache;
-/* Driver wide semaphore. */
-DECLARE_MUTEX(ntfs_lock);
+/* Driver wide mutex. */
+DEFINE_MUTEX(ntfs_lock);
static struct super_block *ntfs_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
ntfs_inode_cache = kmem_cache_create(ntfs_inode_cache_name,
sizeof(ntfs_inode), 0,
- SLAB_RECLAIM_ACCOUNT, NULL, NULL);
+ SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL, NULL);
if (!ntfs_inode_cache) {
printk(KERN_CRIT "NTFS: Failed to create %s!\n",
ntfs_inode_cache_name);
ntfs_big_inode_cache = kmem_cache_create(ntfs_big_inode_cache_name,
sizeof(big_ntfs_inode), 0,
- SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
ntfs_big_inode_init_once, NULL);
if (!ntfs_big_inode_cache) {
printk(KERN_CRIT "NTFS: Failed to create %s!\n",