diff options
Diffstat (limited to 'fs/ntfs/super.c')
-rw-r--r-- | fs/ntfs/super.c | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 368a8ec10668..27833f6df49f 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); | ||
1106 | mm_unmap_out: | 1109 | mm_unmap_out: |
1107 | ntfs_unmap_page(mirr_page); | 1110 | ntfs_unmap_page(mirr_page); |
1108 | mft_unmap_out: | 1111 | mft_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; |
1699 | upcase_failed: | 1711 | upcase_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: | |||
2183 | iput_upcase_err_out: | 2195 | iput_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); |
3023 | iput_tmp_ino_err_out_now: | 3035 | iput_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, | |||
3078 | struct kmem_cache *ntfs_attr_ctx_cache; | 3090 | struct kmem_cache *ntfs_attr_ctx_cache; |
3079 | struct kmem_cache *ntfs_index_ctx_cache; | 3091 | struct kmem_cache *ntfs_index_ctx_cache; |
3080 | 3092 | ||
3081 | /* Driver wide semaphore. */ | 3093 | /* Driver wide mutex. */ |
3082 | DECLARE_MUTEX(ntfs_lock); | 3094 | DEFINE_MUTEX(ntfs_lock); |
3083 | 3095 | ||
3084 | static struct super_block *ntfs_get_sb(struct file_system_type *fs_type, | 3096 | static 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) |
@@ -3151,7 +3163,7 @@ static int __init init_ntfs_fs(void) | |||
3151 | 3163 | ||
3152 | ntfs_inode_cache = kmem_cache_create(ntfs_inode_cache_name, | 3164 | ntfs_inode_cache = kmem_cache_create(ntfs_inode_cache_name, |
3153 | sizeof(ntfs_inode), 0, | 3165 | sizeof(ntfs_inode), 0, |
3154 | SLAB_RECLAIM_ACCOUNT, NULL, NULL); | 3166 | SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL, NULL); |
3155 | if (!ntfs_inode_cache) { | 3167 | if (!ntfs_inode_cache) { |
3156 | printk(KERN_CRIT "NTFS: Failed to create %s!\n", | 3168 | printk(KERN_CRIT "NTFS: Failed to create %s!\n", |
3157 | ntfs_inode_cache_name); | 3169 | ntfs_inode_cache_name); |
@@ -3160,7 +3172,7 @@ static int __init init_ntfs_fs(void) | |||
3160 | 3172 | ||
3161 | ntfs_big_inode_cache = kmem_cache_create(ntfs_big_inode_cache_name, | 3173 | ntfs_big_inode_cache = kmem_cache_create(ntfs_big_inode_cache_name, |
3162 | sizeof(big_ntfs_inode), 0, | 3174 | sizeof(big_ntfs_inode), 0, |
3163 | SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, | 3175 | SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, |
3164 | ntfs_big_inode_init_once, NULL); | 3176 | ntfs_big_inode_init_once, NULL); |
3165 | if (!ntfs_big_inode_cache) { | 3177 | if (!ntfs_big_inode_cache) { |
3166 | printk(KERN_CRIT "NTFS: Failed to create %s!\n", | 3178 | printk(KERN_CRIT "NTFS: Failed to create %s!\n", |
@@ -3234,7 +3246,7 @@ static void __exit exit_ntfs_fs(void) | |||
3234 | } | 3246 | } |
3235 | 3247 | ||
3236 | MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); | 3248 | MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); |
3237 | MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2005 Anton Altaparmakov"); | 3249 | MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2006 Anton Altaparmakov"); |
3238 | MODULE_VERSION(NTFS_VERSION); | 3250 | MODULE_VERSION(NTFS_VERSION); |
3239 | MODULE_LICENSE("GPL"); | 3251 | MODULE_LICENSE("GPL"); |
3240 | #ifdef DEBUG | 3252 | #ifdef DEBUG |