X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fntfs%2Fsuper.c;h=212a3d0f207317f9aa07ec9d45bc770de396c19f;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=2c93c59186c7525a3748f0cfaa29680999b53e5a;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 2c93c5918..212a3d0f2 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -31,16 +31,23 @@ #include #include -#include "ntfs.h" #include "sysctl.h" #include "logfile.h" #include "quota.h" #include "dir.h" +#include "debug.h" #include "index.h" +#include "aops.h" +#include "malloc.h" +#include "ntfs.h" /* Number of mounted file systems which have compression enabled. */ static unsigned long ntfs_nr_compression_users; +/* A global default upcase table and a corresponding reference count. */ +static ntfschar *default_upcase = NULL; +static unsigned long ntfs_nr_upcase_users = 0; + /* Error constants/strings used in inode.c::ntfs_show_options(). */ typedef enum { /* One of these must be present, default is ON_ERRORS_CONTINUE. */ @@ -677,7 +684,7 @@ hotfix_primary_boot_sector: * @b: boot sector to parse * * Parse the ntfs boot sector @b and store all imporant information therein in - * the ntfs super block @vol. Return TRUE on success and FALSE on error. + * the ntfs super block @vol. Return TRUE on success and FALSE on error. */ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) { @@ -710,12 +717,12 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) vol->cluster_size_bits, vol->cluster_size_bits); if (vol->sector_size > vol->cluster_size) { ntfs_error(vol->sb, "Sector sizes above the cluster size are " - "not supported. Sorry."); + "not supported. Sorry."); return FALSE; } if (vol->sb->s_blocksize > vol->cluster_size) { ntfs_error(vol->sb, "Cluster sizes smaller than the device " - "sector size are not supported. Sorry."); + "sector size are not supported. Sorry."); return FALSE; } clusters_per_mft_record = b->clusters_per_mft_record; @@ -739,6 +746,18 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) vol->mft_record_size_mask); ntfs_debug("vol->mft_record_size_bits = %i (0x%x)", vol->mft_record_size_bits, vol->mft_record_size_bits); + /* + * We cannot support mft record sizes above the PAGE_CACHE_SIZE since + * we store $MFT/$DATA, the table of mft records in the page cache. + */ + if (vol->mft_record_size > PAGE_CACHE_SIZE) { + ntfs_error(vol->sb, "Mft record size %i (0x%x) exceeds the " + "page cache size on your system %lu (0x%lx). " + "This is not supported. Sorry.", + vol->mft_record_size, vol->mft_record_size, + PAGE_CACHE_SIZE, PAGE_CACHE_SIZE); + return FALSE; + } clusters_per_index_record = b->clusters_per_index_record; ntfs_debug("clusters_per_index_record = %i (0x%x)", clusters_per_index_record, clusters_per_index_record); @@ -769,7 +788,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) */ ll = sle64_to_cpu(b->number_of_sectors) >> sectors_per_cluster_bits; if ((u64)ll >= 1ULL << 32) { - ntfs_error(vol->sb, "Cannot handle 64-bit clusters. Sorry."); + ntfs_error(vol->sb, "Cannot handle 64-bit clusters. Sorry."); return FALSE; } vol->nr_clusters = ll; @@ -782,8 +801,8 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) if (sizeof(unsigned long) < 8) { if ((ll << vol->cluster_size_bits) >= (1ULL << 41)) { ntfs_error(vol->sb, "Volume size (%lluTiB) is too " - "large for this architecture. Maximum " - "supported is 2TiB. Sorry.", + "large for this architecture. " + "Maximum supported is 2TiB. Sorry.", (unsigned long long)ll >> (40 - vol->cluster_size_bits)); return FALSE; @@ -791,14 +810,14 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) } ll = sle64_to_cpu(b->mft_lcn); if (ll >= vol->nr_clusters) { - ntfs_error(vol->sb, "MFT LCN is beyond end of volume. Weird."); + ntfs_error(vol->sb, "MFT LCN is beyond end of volume. Weird."); return FALSE; } vol->mft_lcn = ll; ntfs_debug("vol->mft_lcn = 0x%llx", (long long)vol->mft_lcn); ll = sle64_to_cpu(b->mftmirr_lcn); if (ll >= vol->nr_clusters) { - ntfs_error(vol->sb, "MFTMirr LCN is beyond end of volume. " + ntfs_error(vol->sb, "MFTMirr LCN is beyond end of volume. " "Weird."); return FALSE; } @@ -827,12 +846,12 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) } /** - * setup_lcn_allocator - initialize the cluster allocator - * @vol: volume structure for which to setup the lcn allocator + * ntfs_setup_allocators - initialize the cluster and mft allocators + * @vol: volume structure for which to setup the allocators * - * Setup the cluster (lcn) allocator to the starting values. + * Setup the cluster (lcn) and mft allocators to the starting values. */ -static void setup_lcn_allocator(ntfs_volume *vol) +static void ntfs_setup_allocators(ntfs_volume *vol) { #ifdef NTFS_RW LCN mft_zone_size, mft_lcn; @@ -902,6 +921,11 @@ static void setup_lcn_allocator(ntfs_volume *vol) vol->data2_zone_pos = 0; ntfs_debug("vol->data2_zone_pos = 0x%llx", (unsigned long long)vol->data2_zone_pos); + + /* Set the mft data allocation position to mft record 24. */ + vol->mft_data_pos = 24; + ntfs_debug("vol->mft_data_pos = 0x%llx", + (unsigned long long)vol->mft_data_pos); #endif /* NTFS_RW */ } @@ -938,8 +962,8 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol) /* No VFS initiated operations allowed for $MFTMirr. */ tmp_ino->i_op = &ntfs_empty_inode_ops; tmp_ino->i_fop = &ntfs_empty_file_ops; - /* Put back our special address space operations. */ - tmp_ino->i_mapping->a_ops = &ntfs_mft_aops; + /* Put in our special address space operations. */ + tmp_ino->i_mapping->a_ops = &ntfs_mst_aops; tmp_ni = NTFS_I(tmp_ino); /* The $MFTMirr, like the $MFT is multi sector transfer protected. */ NInoSetMstProtected(tmp_ni); @@ -959,6 +983,10 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol) * @vol: ntfs super block describing device whose mft mirror to check * * Return TRUE on success or FALSE on error. + * + * Note, this function also results in the mft mirror runlist being completely + * mapped into memory. The mft mirror write code requires this and will BUG() + * should it find an unmapped runlist element. */ static BOOL check_mft_mirror(ntfs_volume *vol) { @@ -2155,7 +2183,7 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs) /** * The complete super operations. */ -struct super_operations ntfs_sops = { +static struct super_operations ntfs_sops = { .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */ .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */ .put_inode = ntfs_put_inode, /* VFS: Called just before @@ -2334,8 +2362,8 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) */ result = parse_ntfs_boot_sector(vol, (NTFS_BOOT_SECTOR*)bh->b_data); - /* Initialize the cluster allocator. */ - setup_lcn_allocator(vol); + /* Initialize the cluster and mft allocators. */ + ntfs_setup_allocators(vol); brelse(bh); @@ -2364,6 +2392,8 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) */ sb->s_maxbytes = MAX_LFS_FILESIZE; + sb->s_time_gran = 100; + /* * Now load the metadata required for the page cache and our address * space operations to function. We do this by setting up a specialised @@ -2573,10 +2603,6 @@ static void ntfs_big_inode_init_once(void *foo, kmem_cache_t *cachep, kmem_cache_t *ntfs_attr_ctx_cache; kmem_cache_t *ntfs_index_ctx_cache; -/* A global default upcase table and a corresponding reference count. */ -ntfschar *default_upcase = NULL; -unsigned long ntfs_nr_upcase_users = 0; - /* Driver wide semaphore. */ DECLARE_MUTEX(ntfs_lock); @@ -2734,6 +2760,7 @@ static void __exit exit_ntfs_fs(void) MODULE_AUTHOR("Anton Altaparmakov "); MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2004 Anton Altaparmakov"); +MODULE_VERSION(NTFS_VERSION); MODULE_LICENSE("GPL"); #ifdef DEBUG module_param(debug_msgs, bool, 0);