aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ntfs/super.c')
-rw-r--r--fs/ntfs/super.c84
1 files changed, 48 insertions, 36 deletions
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