vserver 1.9.5.x5
[linux-2.6.git] / fs / ntfs / super.c
index 2c93c59..212a3d0 100644 (file)
 #include <linux/moduleparam.h>
 #include <linux/smp_lock.h>
 
-#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 <aia21@cantab.net>");
 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);