Whamcloud - gitweb
b=6274
[fs/lustre-release.git] / lustre / smfs / super.c
index eb3ab6b..f2ab435 100644 (file)
@@ -1,6 +1,9 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
+ *  lustre/smfs/super.c
+ *  Lustre filesystem abstraction routines
+ *
  *  Copyright (C) 2004 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
@@ -17,7 +20,6 @@
  *   You should have received a copy of the GNU General Public License
  *   along with Lustre; if not, write to the Free Software
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #define DEBUG_SUBSYSTEM S_SM
 #include <linux/lustre_smfs.h>
 #include "smfs_internal.h"
 
-static char *smfs_options(char *data, char **devstr, char **namestr,
-                          int *kml, int *cache, char **opts
-                          int *iopen_nopriv)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static struct super_block *smfs_read_super(struct super_block *sb
+                                           void *data, int silent)
 {
-        char *pos;
-        struct option *opt_value = NULL;
-
-        while (!(get_opt(&opt_value, &pos))) {
-                if (!strcmp(opt_value->opt, "dev")) {
-                        if (devstr != NULL)
-                                *devstr = opt_value->value;
-                } else if (!strcmp(opt_value->opt, "type")) {
-                        if (namestr != NULL)
-                                *namestr = opt_value->value;
-                } else if (!strcmp(opt_value->opt, "kml")) {
-                        if (kml)
-                                *kml = 1;
-                } else if (!strcmp(opt_value->opt, "cache")) {
-                        if (cache)
-                                *cache = 1;
-                } else if (!strcmp(opt_value->opt, "options")) {
-                        if (opts != NULL)
-                                *opts = opt_value->value;
-                } else if (!strcmp(opt_value->opt, "iopen_nopriv")) {
-                        if (iopen_nopriv != NULL)
-                                *iopen_nopriv = 1;
-                } else {
-                        break;
-                }
-        }
-        return pos;
-}
+        int err;
 
-struct vfsmount *get_vfsmount(struct super_block *sb)
-{
-        struct vfsmount *rootmnt, *mnt, *ret = NULL;
-        struct list_head *end, *list;
+        err = smfs_fill_super(sb, data, silent);
+        if (err)
+                return NULL;
 
-        rootmnt = mntget(current->fs->rootmnt);
-        end = list = &rootmnt->mnt_list;
-        do {
-                mnt = list_entry(list, struct vfsmount, mnt_list);
-                if (mnt->mnt_sb == sb) {
-                        ret = mnt;
-                        break;
-                }
-                list = list->next;
-        } while (end != list);
-        
-        mntput(current->fs->rootmnt);
-        return ret;
+        return sb;
 }
 
-struct super_block *smfs_get_sb_by_path(char *path, int len)
-{
-        struct super_block *sb;
-        struct nameidata nd;
-        int error = 0;
-
-        ENTRY;
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        if (path_init(path, LOOKUP_FOLLOW, &nd)) {
+static struct file_system_type smfs_type = {
+        .owner       = THIS_MODULE,
+        .name        = "smfs",
+        .read_super  = smfs_read_super,
+};
 #else
-        if (path_lookup(path, LOOKUP_FOLLOW, &nd)) {
-#endif
-                error = path_walk(path, &nd);
-                if (error) {
-                        path_release(&nd);
-                        RETURN(NULL);
-                }
-        } else {
-                RETURN(NULL);
-        }
-
-        /* FIXME-WANGDI: add some check code here. */
-        sb = nd.dentry->d_sb;
-        path_release(&nd);
-        RETURN(sb);
-}
-
-static int smfs_init_fsfilt_ops(struct super_block *sb)
+struct super_block *smfs_get_super(struct file_system_type *fs_type,
+                                   int flags, const char *dev_name,
+                                   void *data)
 {
-        ENTRY;
-        if (!S2SMI(sb)->sm_cache_fsfilt) {
-                S2SMI(sb)->sm_cache_fsfilt =
-                        fsfilt_get_ops(S2SMI(sb)->cache_fs_type);
-                if (!S2SMI(sb)->sm_cache_fsfilt) {
-                        CERROR("Can not get %s fsfilt ops needed by kml\n",
-                               S2SMI(sb)->cache_fs_type);
-                        RETURN(-EINVAL);
-                }
-        }
-        if (!S2SMI(sb)->sm_fsfilt) {
-                S2SMI(sb)->sm_fsfilt =
-                        fsfilt_get_ops(S2SMI(sb)->fs_type);
-                if (!S2SMI(sb)->sm_fsfilt) {
-                        CERROR("Can not get %s fsfilt ops needed by kml\n",
-                               S2SMI(sb)->fs_type);
-                        RETURN(-EINVAL);
-                }
-        }
-        RETURN(0);
+        return get_sb_nodev(fs_type, flags, data, smfs_fill_super);
 }
 
-void smfs_cleanup_fsfilt_ops(struct super_block *sb)
+void smfs_kill_super(struct super_block *sb)
 {
-        if (S2SMI(sb)->sm_cache_fsfilt)
-                fsfilt_put_ops(S2SMI(sb)->sm_cache_fsfilt);
-        if (S2SMI(sb)->sm_fsfilt)
-                fsfilt_put_ops(S2SMI(sb)->sm_fsfilt);
+        kill_anon_super(sb);
 }
 
-static int sm_mount_cache(struct super_block *sb, char *devstr, 
-                          char *typestr, char *opts, int iopen_nopriv)
-{
-        struct smfs_super_info *smb;
-        int err = 0, typelen;
-        struct vfsmount *mnt;
-        unsigned long page;
-
-        ENTRY;
-
-        typelen = strlen(typestr);
-       
-        page = __get_free_page(GFP_KERNEL);
-        if (!page)
-                GOTO(err_out, err = -ENOMEM);
-
-        memset((void *)page, 0, PAGE_SIZE);
-        
-        if (iopen_nopriv)
-                sprintf((char *)page, "iopen_nopriv");
-
-        if (opts && strlen(opts)) {
-                int n = strlen((char *)page);
-                sprintf((char *)page + n, ",%s", opts);
-        }
-        
-        printk("smfs: mounting %s at %s\n", typestr, devstr);
-
-        mnt = do_kern_mount(typestr, 0, devstr, (void *)page);
-        free_page(page);
-
-        if (IS_ERR(mnt)) {
-                CERROR("do_kern_mount failed: rc = %ld\n", PTR_ERR(mnt));
-                GOTO(err_out, err = PTR_ERR(mnt));
-        }
-        smb = S2SMI(sb);
-        smb->smsi_sb = mnt->mnt_sb;
-        smb->smsi_mnt = mnt;
-
-        smfs_init_sm_ops(smb);
-
-        OBD_ALLOC(smb->cache_fs_type, strlen(typestr) + 1);
-        memcpy(smb->cache_fs_type, typestr, strlen(typestr));
-
-        OBD_ALLOC(smb->fs_type, strlen(SMFS_TYPE) + 1);
-        memcpy(smb->fs_type, SMFS_TYPE, strlen(SMFS_TYPE));
-
-        duplicate_sb(sb, mnt->mnt_sb);
-        sm_set_sb_ops(mnt->mnt_sb, sb);
-        err = smfs_init_fsfilt_ops(sb);
-err_out:
-        return err;
-}
+static struct file_system_type smfs_type = {
+        .owner       = THIS_MODULE,
+        .name        = "smfs",
+        .get_sb      = smfs_get_super,
+        .kill_sb     = smfs_kill_super,
+};
+#endif
 
-static int sm_umount_cache(struct super_block *sb)
+static int cleanup_smfs(void)
 {
-        struct smfs_super_info *smb = S2SMI(sb);
-
-        mntput(smb->smsi_mnt);
-        smfs_cleanup_sm_ops(smb);
-        smfs_cleanup_fsfilt_ops(sb);
+        int err = 0;
 
-        if (smb->cache_fs_type)
-                OBD_FREE(smb->cache_fs_type, strlen(smb->cache_fs_type) + 1);
-        
-        if (smb->fs_type)
-                OBD_FREE(smb->fs_type, strlen(smb->fs_type) + 1);
-        
+        err = unregister_filesystem(&smfs_type);
+        if (err)
+                CERROR("unregister_filesystem() failed, rc = %d\n", err);
         return 0;
 }
 
-void smfs_put_super(struct super_block *sb)
+static int init_smfs(void)
 {
-        if (SMFS_CACHE_HOOK(S2SMI(sb)))
-                cache_space_hook_exit(sb);
-        
-        if (SMFS_DO_REC(S2SMI(sb)))
-                smfs_rec_cleanup(sb);
+        int err;
         
-        if (sb)
-                sm_umount_cache(sb);
-        return;
+        err = register_filesystem(&smfs_type);
+        if (err)
+                CERROR("register_filesystem() failed, rc = %d\n", err);
+        return err;
 }
 
-static int smfs_fill_super(struct super_block *sb,
-                           void *data, int silent)
+static int __init smfs_init(void)
 {
-        ino_t root_ino;
-        char *cache_data;
-
-        int iopen_nopriv = 0;
-        struct inode *root_inode = NULL;
-        int err = 0, do_rec = 0, cache_hook = 0;
-        char *devstr = NULL, *typestr = NULL, *opts = NULL;
-
-        ENTRY;
-
-        CDEBUG(D_SUPER, "mount opts: %s\n", data ?
-               (char *)data : "(none)");
+        int err;
 
-        init_option(data);
-        
-        /* read and validate passed options. */
-        cache_data = smfs_options(data, &devstr, &typestr,
-                                  &do_rec, &cache_hook, &opts,
-                                  &iopen_nopriv);
-        
-        if (*cache_data)
-                CWARN("smfs_fill_super(): options parsing stoped at "
-                      "option %s\n", cache_data);
-        
-        if (!typestr || !devstr) {
-                CERROR("mount options name and dev mandatory\n");
-                GOTO(out_err, err = -EINVAL);
+        if ( (err = init_smfs_psdev()) ) {
+                printk("Error initializing smfs_psdev, %d\n", err);
+                return -EINVAL;
         }
 
-        err = sm_mount_cache(sb, devstr, typestr, opts, 
-                             iopen_nopriv);
-                             
-        if (err) {
-                CERROR("Can not mount %s as %s, rc = %d\n", devstr, 
-                        typestr, err);
-                GOTO(out_err, err);
+        if ( (err = init_smfs()) ) {
+                printk("Error initializing smfs, %d\n", err);
+                return -EINVAL;
         }
 
-        if (do_rec)
-                smfs_rec_init(sb);
-
-        if (cache_hook)
-                cache_space_hook_init(sb);
-
-        dget(S2CSB(sb)->s_root);
-        root_ino = S2CSB(sb)->s_root->d_inode->i_ino;
-        root_inode = iget(sb, root_ino);
-
-        CDEBUG(D_SUPER, "readinode %p, root ino %ld, root inode at %p\n",
-               sb->s_op->read_inode, root_ino, root_inode);
-
-        sb->s_root = d_alloc_root(root_inode);
-
-        if (!sb->s_root) {
-                sm_umount_cache(sb);
-                GOTO(out_err, err = -EINVAL);
+        if ( (err = init_smfs_proc_sys()) ) {
+                printk("Error initializing smfs proc sys, %d\n", err);
+                return -EINVAL;
         }
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
-               (ulong)sb, (ulong)&sb->u.generic_sbp);
-#else
-        CDEBUG(D_SUPER, "sb %lx, &sb->s_fs_info: %lx\n",
-               (ulong)sb, (ulong)&sb->s_fs_info);
-#endif
-
-out_err:
-        cleanup_option();
-        return err;
-}
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static struct super_block *smfs_read_super(struct super_block *sb,
-                                           void *data, int silent)
-{
-        int err;
-
-        err = smfs_fill_super(sb, data, silent);
-        if (err)
-                return NULL;
-        
-        return sb;
-}
-#else
-struct super_block *smfs_get_sb(struct file_system_type *fs_type,
-                                int flags, const char *dev_name,
-                                void *data)
-{
-        return get_sb_nodev(fs_type, flags, data, smfs_fill_super);
+        return 0;
 }
-#endif
 
-static struct file_system_type smfs_type = {
-        .owner       = THIS_MODULE,
-        .name        = "smfs",
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        .read_super  = smfs_read_super,
-#else
-        .get_sb      = smfs_get_sb,
-        .kill_sb     = kill_anon_super,
-#endif
-};
-
-int init_smfs(void)
+static void __exit smfs_cleanup(void)
 {
-        int err;
-
-        err = register_filesystem(&smfs_type);
-        if (err) {
-                CERROR("register_filesystem() failed, "
-                       "rc = %d\n", err);
-        }
-        return err;
+        cleanup_smfs();
+        smfs_cleanup_psdev();
 }
 
-int cleanup_smfs(void)
-{
-        int err = 0;
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("Smfs file system filters v0.01");
+MODULE_LICENSE("GPL");
 
-        err = unregister_filesystem(&smfs_type);
-        if (err) {
-                CERROR("unregister_filesystem() failed, "
-                       "rc = %d\n", err);
-        }
-        return 0;
-}
+module_init(smfs_init);
+module_exit(smfs_cleanup);