aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/super.c
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-02-03 07:02:56 -0500
committerAnton Altaparmakov <aia21@cantab.net>2005-05-05 05:53:01 -0400
commitc002f42543e155dd2b5b5039ea2637ab26c82513 (patch)
treeea408493d2e0e9096166ab39a8657689c15c7dfa /fs/ntfs/super.c
parentf40661be038ce6ed9ef6a8b80307a9153bd95769 (diff)
NTFS: - Add disable_sparse mount option together with a per volume sparse
enable bit which is set appropriately and a per inode sparse disable bit which is preset on some system file inodes as appropriate. - Enforce that sparse support is disabled on NTFS volumes pre 3.0. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/super.c')
-rw-r--r--fs/ntfs/super.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 0ad0c51e9eb9..b676cf6fd93c 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. 2 * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
3 * 3 *
4 * Copyright (c) 2001-2004 Anton Altaparmakov 4 * Copyright (c) 2001-2005 Anton Altaparmakov
5 * Copyright (c) 2001,2002 Richard Russon 5 * Copyright (c) 2001,2002 Richard Russon
6 * 6 *
7 * This program/include file is free software; you can redistribute it and/or 7 * This program/include file is free software; you can redistribute it and/or
@@ -41,7 +41,7 @@
41#include "malloc.h" 41#include "malloc.h"
42#include "ntfs.h" 42#include "ntfs.h"
43 43
44/* Number of mounted file systems which have compression enabled. */ 44/* Number of mounted filesystems which have compression enabled. */
45static unsigned long ntfs_nr_compression_users; 45static unsigned long ntfs_nr_compression_users;
46 46
47/* A global default upcase table and a corresponding reference count. */ 47/* A global default upcase table and a corresponding reference count. */
@@ -102,7 +102,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt)
102 gid_t gid = (gid_t)-1; 102 gid_t gid = (gid_t)-1;
103 mode_t fmask = (mode_t)-1, dmask = (mode_t)-1; 103 mode_t fmask = (mode_t)-1, dmask = (mode_t)-1;
104 int mft_zone_multiplier = -1, on_errors = -1; 104 int mft_zone_multiplier = -1, on_errors = -1;
105 int show_sys_files = -1, case_sensitive = -1; 105 int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1;
106 struct nls_table *nls_map = NULL, *old_nls; 106 struct nls_table *nls_map = NULL, *old_nls;
107 107
108 /* I am lazy... (-8 */ 108 /* I am lazy... (-8 */
@@ -162,6 +162,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt)
162 else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE) 162 else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE)
163 else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files) 163 else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files)
164 else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive) 164 else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive)
165 else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse)
165 else NTFS_GETOPT_OPTIONS_ARRAY("errors", on_errors, 166 else NTFS_GETOPT_OPTIONS_ARRAY("errors", on_errors,
166 on_errors_arr) 167 on_errors_arr)
167 else if (!strcmp(p, "posix") || !strcmp(p, "show_inodes")) 168 else if (!strcmp(p, "posix") || !strcmp(p, "show_inodes"))
@@ -291,6 +292,21 @@ no_mount_options:
291 else 292 else
292 NVolClearCaseSensitive(vol); 293 NVolClearCaseSensitive(vol);
293 } 294 }
295 if (disable_sparse != -1) {
296 if (disable_sparse)
297 NVolClearSparseEnabled(vol);
298 else {
299 if (!NVolSparseEnabled(vol) &&
300 vol->major_ver && vol->major_ver < 3)
301 ntfs_warning(vol->sb, "Not enabling sparse "
302 "support due to NTFS volume "
303 "version %i.%i (need at least "
304 "version 3.0).", vol->major_ver,
305 vol->minor_ver);
306 else
307 NVolSetSparseEnabled(vol);
308 }
309 }
294 return TRUE; 310 return TRUE;
295needs_arg: 311needs_arg:
296 ntfs_error(vol->sb, "The %s option requires an argument.", p); 312 ntfs_error(vol->sb, "The %s option requires an argument.", p);
@@ -967,6 +983,7 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol)
967 tmp_ni = NTFS_I(tmp_ino); 983 tmp_ni = NTFS_I(tmp_ino);
968 /* The $MFTMirr, like the $MFT is multi sector transfer protected. */ 984 /* The $MFTMirr, like the $MFT is multi sector transfer protected. */
969 NInoSetMstProtected(tmp_ni); 985 NInoSetMstProtected(tmp_ni);
986 NInoSetSparseDisabled(tmp_ni);
970 /* 987 /*
971 * Set up our little cheat allowing us to reuse the async read io 988 * Set up our little cheat allowing us to reuse the async read io
972 * completion handler for directories. 989 * completion handler for directories.
@@ -1122,6 +1139,7 @@ static BOOL load_and_check_logfile(ntfs_volume *vol)
1122 /* ntfs_check_logfile() will have displayed error output. */ 1139 /* ntfs_check_logfile() will have displayed error output. */
1123 return FALSE; 1140 return FALSE;
1124 } 1141 }
1142 NInoSetSparseDisabled(NTFS_I(tmp_ino));
1125 vol->logfile_ino = tmp_ino; 1143 vol->logfile_ino = tmp_ino;
1126 ntfs_debug("Done."); 1144 ntfs_debug("Done.");
1127 return TRUE; 1145 return TRUE;
@@ -1220,6 +1238,7 @@ static BOOL load_and_init_attrdef(ntfs_volume *vol)
1220 iput(ino); 1238 iput(ino);
1221 goto failed; 1239 goto failed;
1222 } 1240 }
1241 NInoSetSparseDisabled(NTFS_I(ino));
1223 /* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */ 1242 /* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */
1224 i_size = i_size_read(ino); 1243 i_size = i_size_read(ino);
1225 if (i_size <= 0 || i_size > 0x7fffffff) 1244 if (i_size <= 0 || i_size > 0x7fffffff)
@@ -1439,6 +1458,7 @@ static BOOL load_system_files(ntfs_volume *vol)
1439 iput(vol->lcnbmp_ino); 1458 iput(vol->lcnbmp_ino);
1440 goto bitmap_failed; 1459 goto bitmap_failed;
1441 } 1460 }
1461 NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino));
1442 if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) { 1462 if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) {
1443 iput(vol->lcnbmp_ino); 1463 iput(vol->lcnbmp_ino);
1444bitmap_failed: 1464bitmap_failed:
@@ -1490,6 +1510,12 @@ get_ctx_vol_failed:
1490 unmap_mft_record(NTFS_I(vol->vol_ino)); 1510 unmap_mft_record(NTFS_I(vol->vol_ino));
1491 printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver, 1511 printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver,
1492 vol->minor_ver); 1512 vol->minor_ver);
1513 if (vol->major_ver < 3 && NVolSparseEnabled(vol)) {
1514 ntfs_warning(vol->sb, "Disabling sparse support due to NTFS "
1515 "volume version %i.%i (need at least version "
1516 "3.0).", vol->major_ver, vol->minor_ver);
1517 NVolClearSparseEnabled(vol);
1518 }
1493#ifdef NTFS_RW 1519#ifdef NTFS_RW
1494 /* Make sure that no unsupported volume flags are set. */ 1520 /* Make sure that no unsupported volume flags are set. */
1495 if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { 1521 if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
@@ -2033,7 +2059,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
2033/** 2059/**
2034 * __get_nr_free_mft_records - return the number of free inodes on a volume 2060 * __get_nr_free_mft_records - return the number of free inodes on a volume
2035 * @vol: ntfs volume for which to obtain free inode count 2061 * @vol: ntfs volume for which to obtain free inode count
2036 * @nr_free: number of mft records in file system 2062 * @nr_free: number of mft records in filesystem
2037 * @max_index: maximum number of pages containing set bits 2063 * @max_index: maximum number of pages containing set bits
2038 * 2064 *
2039 * Calculate the number of free mft records (inodes) on the mounted NTFS 2065 * Calculate the number of free mft records (inodes) on the mounted NTFS
@@ -2138,13 +2164,13 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
2138 /* Optimal transfer block size. */ 2164 /* Optimal transfer block size. */
2139 sfs->f_bsize = PAGE_CACHE_SIZE; 2165 sfs->f_bsize = PAGE_CACHE_SIZE;
2140 /* 2166 /*
2141 * Total data blocks in file system in units of f_bsize and since 2167 * Total data blocks in filesystem in units of f_bsize and since
2142 * inodes are also stored in data blocs ($MFT is a file) this is just 2168 * inodes are also stored in data blocs ($MFT is a file) this is just
2143 * the total clusters. 2169 * the total clusters.
2144 */ 2170 */
2145 sfs->f_blocks = vol->nr_clusters << vol->cluster_size_bits >> 2171 sfs->f_blocks = vol->nr_clusters << vol->cluster_size_bits >>
2146 PAGE_CACHE_SHIFT; 2172 PAGE_CACHE_SHIFT;
2147 /* Free data blocks in file system in units of f_bsize. */ 2173 /* Free data blocks in filesystem in units of f_bsize. */
2148 size = get_nr_free_clusters(vol) << vol->cluster_size_bits >> 2174 size = get_nr_free_clusters(vol) << vol->cluster_size_bits >>
2149 PAGE_CACHE_SHIFT; 2175 PAGE_CACHE_SHIFT;
2150 if (size < 0LL) 2176 if (size < 0LL)
@@ -2163,7 +2189,7 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
2163 max_index = ((((mft_ni->initialized_size >> vol->mft_record_size_bits) 2189 max_index = ((((mft_ni->initialized_size >> vol->mft_record_size_bits)
2164 + 7) >> 3) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 2190 + 7) >> 3) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
2165 read_unlock_irqrestore(&mft_ni->size_lock, flags); 2191 read_unlock_irqrestore(&mft_ni->size_lock, flags);
2166 /* Number of inodes in file system (at this point in time). */ 2192 /* Number of inodes in filesystem (at this point in time). */
2167 sfs->f_files = size; 2193 sfs->f_files = size;
2168 /* Free inodes in fs (based on current total count). */ 2194 /* Free inodes in fs (based on current total count). */
2169 sfs->f_ffree = __get_nr_free_mft_records(vol, size, max_index); 2195 sfs->f_ffree = __get_nr_free_mft_records(vol, size, max_index);
@@ -2172,8 +2198,8 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
2172 * File system id. This is extremely *nix flavour dependent and even 2198 * File system id. This is extremely *nix flavour dependent and even
2173 * within Linux itself all fs do their own thing. I interpret this to 2199 * within Linux itself all fs do their own thing. I interpret this to
2174 * mean a unique id associated with the mounted fs and not the id 2200 * mean a unique id associated with the mounted fs and not the id
2175 * associated with the file system driver, the latter is already given 2201 * associated with the filesystem driver, the latter is already given
2176 * by the file system type in sfs->f_type. Thus we use the 64-bit 2202 * by the filesystem type in sfs->f_type. Thus we use the 64-bit
2177 * volume serial number splitting it into two 32-bit parts. We enter 2203 * volume serial number splitting it into two 32-bit parts. We enter
2178 * the least significant 32-bits in f_fsid[0] and the most significant 2204 * the least significant 32-bits in f_fsid[0] and the most significant
2179 * 32-bits in f_fsid[1]. 2205 * 32-bits in f_fsid[1].
@@ -2259,18 +2285,18 @@ static struct export_operations ntfs_export_ops = {
2259}; 2285};
2260 2286
2261/** 2287/**
2262 * ntfs_fill_super - mount an ntfs files system 2288 * ntfs_fill_super - mount an ntfs filesystem
2263 * @sb: super block of ntfs file system to mount 2289 * @sb: super block of ntfs filesystem to mount
2264 * @opt: string containing the mount options 2290 * @opt: string containing the mount options
2265 * @silent: silence error output 2291 * @silent: silence error output
2266 * 2292 *
2267 * ntfs_fill_super() is called by the VFS to mount the device described by @sb 2293 * ntfs_fill_super() is called by the VFS to mount the device described by @sb
2268 * with the mount otions in @data with the NTFS file system. 2294 * with the mount otions in @data with the NTFS filesystem.
2269 * 2295 *
2270 * If @silent is true, remain silent even if errors are detected. This is used 2296 * If @silent is true, remain silent even if errors are detected. This is used
2271 * during bootup, when the kernel tries to mount the root file system with all 2297 * during bootup, when the kernel tries to mount the root filesystem with all
2272 * registered file systems one after the other until one succeeds. This implies 2298 * registered filesystems one after the other until one succeeds. This implies
2273 * that all file systems except the correct one will quite correctly and 2299 * that all filesystems except the correct one will quite correctly and
2274 * expectedly return an error, but nobody wants to see error messages when in 2300 * expectedly return an error, but nobody wants to see error messages when in
2275 * fact this is what is supposed to happen. 2301 * fact this is what is supposed to happen.
2276 * 2302 *
@@ -2330,6 +2356,9 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2330 2356
2331 unlock_kernel(); 2357 unlock_kernel();
2332 2358
2359 /* By default, enable sparse support. */
2360 NVolSetSparseEnabled(vol);
2361
2333 /* Important to get the mount options dealt with now. */ 2362 /* Important to get the mount options dealt with now. */
2334 if (!parse_options(vol, (char*)opt)) 2363 if (!parse_options(vol, (char*)opt))
2335 goto err_out_now; 2364 goto err_out_now;
@@ -2711,7 +2740,7 @@ static int __init init_ntfs_fs(void)
2711 ntfs_debug("NTFS driver registered successfully."); 2740 ntfs_debug("NTFS driver registered successfully.");
2712 return 0; /* Success! */ 2741 return 0; /* Success! */
2713 } 2742 }
2714 printk(KERN_CRIT "NTFS: Failed to register NTFS file system driver!\n"); 2743 printk(KERN_CRIT "NTFS: Failed to register NTFS filesystem driver!\n");
2715 2744
2716sysctl_err_out: 2745sysctl_err_out:
2717 kmem_cache_destroy(ntfs_big_inode_cache); 2746 kmem_cache_destroy(ntfs_big_inode_cache);
@@ -2725,7 +2754,7 @@ actx_err_out:
2725 kmem_cache_destroy(ntfs_index_ctx_cache); 2754 kmem_cache_destroy(ntfs_index_ctx_cache);
2726ictx_err_out: 2755ictx_err_out:
2727 if (!err) { 2756 if (!err) {
2728 printk(KERN_CRIT "NTFS: Aborting NTFS file system driver " 2757 printk(KERN_CRIT "NTFS: Aborting NTFS filesystem driver "
2729 "registration...\n"); 2758 "registration...\n");
2730 err = -ENOMEM; 2759 err = -ENOMEM;
2731 } 2760 }
@@ -2765,7 +2794,7 @@ static void __exit exit_ntfs_fs(void)
2765} 2794}
2766 2795
2767MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); 2796MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>");
2768MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2004 Anton Altaparmakov"); 2797MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2005 Anton Altaparmakov");
2769MODULE_VERSION(NTFS_VERSION); 2798MODULE_VERSION(NTFS_VERSION);
2770MODULE_LICENSE("GPL"); 2799MODULE_LICENSE("GPL");
2771#ifdef DEBUG 2800#ifdef DEBUG