linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / ocfs2 / super.c
index d17e33e..8dd3aaf 100644 (file)
 
 #include "buffer_head_io.h"
 
+/*
+ * Globals
+ */
+static spinlock_t ocfs2_globals_lock = SPIN_LOCK_UNLOCKED;
+
+static u32 osb_id;             /* Keeps track of next available OSB Id */
+
 static kmem_cache_t *ocfs2_inode_cachep = NULL;
 
 kmem_cache_t *ocfs2_lock_cache = NULL;
@@ -93,7 +100,7 @@ static int ocfs2_initialize_mem_caches(void);
 static void ocfs2_free_mem_caches(void);
 static void ocfs2_delete_osb(struct ocfs2_super *osb);
 
-static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf);
+static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf);
 
 static int ocfs2_sync_fs(struct super_block *sb, int wait);
 
@@ -635,9 +642,10 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 
        ocfs2_complete_mount_recovery(osb);
 
-       printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %d, slot %d) "
-              "with %s data mode.\n",
-              osb->dev_str, osb->node_num, osb->slot_num,
+       printk("ocfs2: Mounting device (%u,%u) on (node %d, slot %d) with %s "
+              "data mode.\n",
+              MAJOR(sb->s_dev), MINOR(sb->s_dev), osb->node_num,
+              osb->slot_num,
               osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :
               "ordered");
 
@@ -664,14 +672,12 @@ read_super_error:
        return status;
 }
 
-static int ocfs2_get_sb(struct file_system_type *fs_type,
-                       int flags,
-                       const char *dev_name,
-                       void *data,
-                       struct vfsmount *mnt)
+static struct super_block *ocfs2_get_sb(struct file_system_type *fs_type,
+                                       int flags,
+                                       const char *dev_name,
+                                       void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super,
-                          mnt);
+       return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super);
 }
 
 static struct file_system_type ocfs2_fs_type = {
@@ -792,6 +798,10 @@ static int __init ocfs2_init(void)
                goto leave;
        }
 
+       spin_lock(&ocfs2_globals_lock);
+       osb_id = 0;
+       spin_unlock(&ocfs2_globals_lock);
+
        ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL);
        if (!ocfs2_debugfs_root) {
                status = -EFAULT;
@@ -845,7 +855,7 @@ static void ocfs2_put_super(struct super_block *sb)
        mlog_exit_void();
 }
 
-static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
+static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf)
 {
        struct ocfs2_super *osb;
        u32 numbits, freebits;
@@ -854,9 +864,9 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct buffer_head *bh = NULL;
        struct inode *inode = NULL;
 
-       mlog_entry("(%p, %p)\n", dentry->d_sb, buf);
+       mlog_entry("(%p, %p)\n", sb, buf);
 
-       osb = OCFS2_SB(dentry->d_sb);
+       osb = OCFS2_SB(sb);
 
        inode = ocfs2_get_system_file_inode(osb,
                                            GLOBAL_BITMAP_SYSTEM_INODE,
@@ -879,7 +889,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
        freebits = numbits - le32_to_cpu(bm_lock->id1.bitmap1.i_used);
 
        buf->f_type = OCFS2_SUPER_MAGIC;
-       buf->f_bsize = dentry->d_sb->s_blocksize;
+       buf->f_bsize = sb->s_blocksize;
        buf->f_namelen = OCFS2_MAX_FILENAME_LEN;
        buf->f_blocks = ((sector_t) numbits) *
                        (osb->s_clustersize >> osb->sb->s_blocksize_bits);
@@ -940,18 +950,16 @@ static void ocfs2_inode_init_once(void *data,
 static int ocfs2_initialize_mem_caches(void)
 {
        ocfs2_inode_cachep = kmem_cache_create("ocfs2_inode_cache",
-                                      sizeof(struct ocfs2_inode_info),
-                                      0,
-                                      (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
-                                               SLAB_MEM_SPREAD),
-                                      ocfs2_inode_init_once, NULL);
+                                              sizeof(struct ocfs2_inode_info),
+                                              0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+                                              ocfs2_inode_init_once, NULL);
        if (!ocfs2_inode_cachep)
                return -ENOMEM;
 
        ocfs2_lock_cache = kmem_cache_create("ocfs2_lock",
                                             sizeof(struct ocfs2_journal_lock),
                                             0,
-                                            SLAB_HWCACHE_ALIGN,
+                                            SLAB_NO_REAP|SLAB_HWCACHE_ALIGN,
                                             NULL, NULL);
        if (!ocfs2_lock_cache)
                return -ENOMEM;
@@ -1008,7 +1016,7 @@ static int ocfs2_fill_local_node_info(struct ocfs2_super *osb)
                goto bail;
        }
 
-       mlog(0, "I am node %d\n", osb->node_num);
+       mlog(ML_NOTICE, "I am node %d\n", osb->node_num);
 
        status = 0;
 bail:
@@ -1179,8 +1187,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
 
        atomic_set(&osb->vol_state, VOLUME_DISMOUNTED);
 
-       printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %d)\n",
-              osb->dev_str, osb->node_num);
+       printk("ocfs2: Unmounting device (%u,%u) on (node %d)\n",
+              MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev), osb->node_num);
 
        ocfs2_delete_osb(osb);
        kfree(osb);
@@ -1200,6 +1208,8 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu
        if (osb->uuid_str == NULL)
                return -ENOMEM;
 
+       memcpy(osb->uuid, uuid, OCFS2_VOL_UUID_LEN);
+
        for (i = 0, ptr = osb->uuid_str; i < OCFS2_VOL_UUID_LEN; i++) {
                /* print with null */
                ret = snprintf(ptr, 3, "%02X", uuid[i]);
@@ -1297,6 +1307,13 @@ static int ocfs2_initialize_super(struct super_block *sb,
                goto bail;
        }
 
+       osb->uuid = kmalloc(OCFS2_VOL_UUID_LEN, GFP_KERNEL);
+       if (!osb->uuid) {
+               mlog(ML_ERROR, "unable to alloc uuid\n");
+               status = -ENOMEM;
+               goto bail;
+       }
+
        di = (struct ocfs2_dinode *)bh->b_data;
 
        osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
@@ -1306,7 +1323,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
                status = -EINVAL;
                goto bail;
        }
-       mlog(0, "max_slots for this device: %u\n", osb->max_slots);
+       mlog(ML_NOTICE, "max_slots for this device: %u\n", osb->max_slots);
 
        init_waitqueue_head(&osb->osb_wipe_event);
        osb->osb_orphan_wipes = kcalloc(osb->max_slots,
@@ -1397,7 +1414,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
                goto bail;
        }
 
-       memcpy(&uuid_net_key, di->id2.i_super.s_uuid, sizeof(uuid_net_key));
+       memcpy(&uuid_net_key, &osb->uuid[i], sizeof(osb->net_key));
        osb->net_key = le32_to_cpu(uuid_net_key);
 
        strncpy(osb->vol_label, di->id2.i_super.s_label, 63);
@@ -1409,9 +1426,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
        osb->fs_generation = le32_to_cpu(di->i_fs_generation);
        mlog(0, "vol_label: %s\n", osb->vol_label);
        mlog(0, "uuid: %s\n", osb->uuid_str);
-       mlog(0, "root_blkno=%llu, system_dir_blkno=%llu\n",
-            (unsigned long long)osb->root_blkno,
-            (unsigned long long)osb->system_dir_blkno);
+       mlog(0, "root_blkno=%"MLFu64", system_dir_blkno=%"MLFu64"\n",
+            osb->root_blkno, osb->system_dir_blkno);
 
        osb->osb_dlm_debug = ocfs2_new_dlm_debug();
        if (!osb->osb_dlm_debug) {
@@ -1442,13 +1458,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
 
        osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno;
 
-       /* We don't have a cluster lock on the bitmap here because
-        * we're only interested in static information and the extra
-        * complexity at mount time isn't worht it. Don't pass the
-        * inode in to the read function though as we don't want it to
-        * be put in the cache. */
        status = ocfs2_read_block(osb, osb->bitmap_blkno, &bitmap_bh, 0,
-                                 NULL);
+                                 inode);
        iput(inode);
        if (status < 0) {
                mlog_errno(status);
@@ -1457,9 +1468,10 @@ static int ocfs2_initialize_super(struct super_block *sb,
 
        di = (struct ocfs2_dinode *) bitmap_bh->b_data;
        osb->bitmap_cpg = le16_to_cpu(di->id2.i_chain.cl_cpg);
+       osb->num_clusters = le32_to_cpu(di->id1.bitmap1.i_total);
        brelse(bitmap_bh);
-       mlog(0, "cluster bitmap inode: %llu, clusters per group: %u\n",
-            (unsigned long long)osb->bitmap_blkno, osb->bitmap_cpg);
+       mlog(0, "cluster bitmap inode: %"MLFu64", clusters per group: %u\n",
+            osb->bitmap_blkno, osb->bitmap_cpg);
 
        status = ocfs2_init_slot_info(osb);
        if (status < 0) {
@@ -1467,6 +1479,18 @@ static int ocfs2_initialize_super(struct super_block *sb,
                goto bail;
        }
 
+       /*  Link this osb onto the global linked list of all osb structures. */
+       /*  The Global Link List is mainted for the whole driver . */
+       spin_lock(&ocfs2_globals_lock);
+       osb->osb_id = osb_id;
+       if (osb_id < OCFS2_MAX_OSB_ID)
+               osb_id++;
+       else {
+               mlog(ML_ERROR, "Too many volumes mounted\n");
+               status = -ENOMEM;
+       }
+       spin_unlock(&ocfs2_globals_lock);
+
 bail:
        mlog_exit(status);
        return status;
@@ -1505,9 +1529,8 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di,
                             OCFS2_MINOR_REV_LEVEL);
                } else if (bh->b_blocknr != le64_to_cpu(di->i_blkno)) {
                        mlog(ML_ERROR, "bad block number on superblock: "
-                            "found %llu, should be %llu\n",
-                            (unsigned long long)di->i_blkno,
-                            (unsigned long long)bh->b_blocknr);
+                            "found %"MLFu64", should be %llu\n",
+                            di->i_blkno, (unsigned long long)bh->b_blocknr);
                } else if (le32_to_cpu(di->id2.i_super.s_clustersize_bits) < 12 ||
                            le32_to_cpu(di->id2.i_super.s_clustersize_bits) > 20) {
                        mlog(ML_ERROR, "bad cluster size found: %u\n",