minix: replace inode uid,gid,mode init with helper
[safe/jmp/linux-2.6] / fs / exofs / super.c
index fc88751..03149b9 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/vfs.h>
 #include <linux/random.h>
 #include <linux/exportfs.h>
+#include <linux/slab.h>
 
 #include "exofs.h"
 
@@ -301,6 +302,7 @@ static void exofs_put_super(struct super_block *sb)
        _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0],
                            sbi->layout.s_pid);
 
+       bdi_destroy(&sbi->bdi);
        exofs_free_sbi(sbi);
        sb->s_fs_info = NULL;
 }
@@ -308,6 +310,8 @@ static void exofs_put_super(struct super_block *sb)
 static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
                                    struct exofs_device_table *dt)
 {
+       u64 stripe_length;
+
        sbi->data_map.odm_num_comps   =
                                le32_to_cpu(dt->dt_data_map.cb_num_comps);
        sbi->data_map.odm_stripe_unit =
@@ -321,14 +325,63 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
        sbi->data_map.odm_raid_algorithm  =
                                le32_to_cpu(dt->dt_data_map.cb_raid_algorithm);
 
-/* FIXME: Hard coded mirror only for now. if not so do not mount */
-       if ((sbi->data_map.odm_num_comps != numdevs) ||
-           (sbi->data_map.odm_stripe_unit != EXOFS_BLKSIZE) ||
-           (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) ||
-           (sbi->data_map.odm_mirror_cnt != (numdevs - 1)))
+/* FIXME: Only raid0 for now. if not so, do not mount */
+       if (sbi->data_map.odm_num_comps != numdevs) {
+               EXOFS_ERR("odm_num_comps(%u) != numdevs(%u)\n",
+                         sbi->data_map.odm_num_comps, numdevs);
                return -EINVAL;
-       else
-               return 0;
+       }
+       if (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) {
+               EXOFS_ERR("Only RAID_0 for now\n");
+               return -EINVAL;
+       }
+       if (0 != (numdevs % (sbi->data_map.odm_mirror_cnt + 1))) {
+               EXOFS_ERR("Data Map wrong, numdevs=%d mirrors=%d\n",
+                         numdevs, sbi->data_map.odm_mirror_cnt);
+               return -EINVAL;
+       }
+
+       if (0 != (sbi->data_map.odm_stripe_unit & ~PAGE_MASK)) {
+               EXOFS_ERR("Stripe Unit(0x%llx)"
+                         " must be Multples of PAGE_SIZE(0x%lx)\n",
+                         _LLU(sbi->data_map.odm_stripe_unit), PAGE_SIZE);
+               return -EINVAL;
+       }
+
+       sbi->layout.stripe_unit = sbi->data_map.odm_stripe_unit;
+       sbi->layout.mirrors_p1 = sbi->data_map.odm_mirror_cnt + 1;
+
+       if (sbi->data_map.odm_group_width) {
+               sbi->layout.group_width = sbi->data_map.odm_group_width;
+               sbi->layout.group_depth = sbi->data_map.odm_group_depth;
+               if (!sbi->layout.group_depth) {
+                       EXOFS_ERR("group_depth == 0 && group_width != 0\n");
+                       return -EINVAL;
+               }
+               sbi->layout.group_count = sbi->data_map.odm_num_comps /
+                                               sbi->layout.mirrors_p1 /
+                                               sbi->data_map.odm_group_width;
+       } else {
+               if (sbi->data_map.odm_group_depth) {
+                       printk(KERN_NOTICE "Warning: group_depth ignored "
+                               "group_width == 0 && group_depth == %d\n",
+                               sbi->data_map.odm_group_depth);
+                       sbi->data_map.odm_group_depth = 0;
+               }
+               sbi->layout.group_width = sbi->data_map.odm_num_comps /
+                                                       sbi->layout.mirrors_p1;
+               sbi->layout.group_depth = -1;
+               sbi->layout.group_count = 1;
+       }
+
+       stripe_length = (u64)sbi->layout.group_width * sbi->layout.stripe_unit;
+       if (stripe_length >= (1ULL << 32)) {
+               EXOFS_ERR("Total Stripe length(0x%llx)"
+                         " >= 32bit is not supported\n", _LLU(stripe_length));
+               return -EINVAL;
+       }
+
+       return 0;
 }
 
 /* @odi is valid only as long as @fscb_dev is valid */
@@ -494,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        if (!sbi)
                return -ENOMEM;
 
+       ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY);
+       if (ret)
+               goto free_bdi;
+
        /* use mount options to fill superblock */
        od = osduld_path_lookup(opts->dev_name);
        if (IS_ERR(od)) {
@@ -502,6 +559,11 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        /* Default layout in case we do not have a device-table */
+       sbi->layout.stripe_unit = PAGE_SIZE;
+       sbi->layout.mirrors_p1 = 1;
+       sbi->layout.group_width = 1;
+       sbi->layout.group_depth = -1;
+       sbi->layout.group_count = 1;
        sbi->layout.s_ods[0] = od;
        sbi->layout.s_numdevs = 1;
        sbi->layout.s_pid = opts->pid;
@@ -555,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        /* set up operation vectors */
+       sb->s_bdi = &sbi->bdi;
        sb->s_fs_info = sbi;
        sb->s_op = &exofs_sops;
        sb->s_export_op = &exofs_export_ops;
@@ -586,6 +649,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 
 free_sbi:
+       bdi_destroy(&sbi->bdi);
+free_bdi:
        EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
                  opts->dev_name, sbi->layout.s_pid, ret);
        exofs_free_sbi(sbi);