Whamcloud - gitweb
Make the MDS filesystem interface code be a separate module. This allows
authoradilger <adilger>
Wed, 29 May 2002 10:31:09 +0000 (10:31 +0000)
committeradilger <adilger>
Wed, 29 May 2002 10:31:09 +0000 (10:31 +0000)
us to load MDS even if the extN module is not building properly.

lustre/include/linux/lustre_mds.h
lustre/mds/Makefile.am
lustre/mds/handler.c
lustre/mds/mds_ext2.c
lustre/mds/mds_ext3.c
lustre/mds/mds_extN.c

index e7f942b..ffd84d1 100644 (file)
@@ -147,13 +147,17 @@ int mdc_rename(struct ptlrpc_client *, struct ptlrpc_connection *,
                struct ptlrpc_request **);
 int mdc_create_client(char *uuid, struct ptlrpc_client *cl);
 
+extern int mds_client_add(struct mds_obd *mds, struct mds_client_data *mcd,
+                          int cl_off);
+
+/* mds/mds_fs.c */
 struct mds_fs_operations {
         void   *(* fs_start)(struct inode *inode, int op);
         int     (* fs_commit)(struct inode *inode, void *handle);
         int     (* fs_setattr)(struct dentry *dentry, void *handle,
                                struct iattr *iattr);
         int     (* fs_set_objid)(struct inode *inode, void *handle, obd_id id);
-        void    (* fs_get_objid)(struct inode *inode, obd_id *id);
+        int     (* fs_get_objid)(struct inode *inode, obd_id *id);
         ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count,
                                 loff_t *offset);
         void    (* fs_delete_inode)(struct inode *inode);
@@ -162,15 +166,10 @@ struct mds_fs_operations {
         int     (* fs_set_last_rcvd)(struct mds_obd *mds, void *handle);
 };
 
-#define MDS_FSOP_UNLINK         1
-#define MDS_FSOP_RMDIR          2
-#define MDS_FSOP_RENAME         3
-#define MDS_FSOP_CREATE         4
-#define MDS_FSOP_MKDIR          5
-#define MDS_FSOP_SYMLINK        6
-#define MDS_FSOP_MKNOD          7
-#define MDS_FSOP_SETATTR        8
-#define MDS_FSOP_LINK           9
+extern int mds_register_fs_type(struct mds_fs_operations *op, const char *name);
+extern void mds_unregister_fs_type(const char *name);
+extern int mds_fs_setup(struct mds_obd *mds, struct vfsmount *mnt);
+extern void mds_fs_cleanup(struct mds_obd *mds);
 
 static inline void *mds_fs_start(struct mds_obd *mds, struct inode *inode,
                                  int op)
@@ -203,10 +202,10 @@ static inline int mds_fs_set_objid(struct mds_obd *mds, struct inode *inode,
         return mds->mds_fsops->fs_set_objid(inode, handle, id);
 }
 
-static inline void mds_fs_get_objid(struct mds_obd *mds, struct inode *inode,
+static inline int mds_fs_get_objid(struct mds_obd *mds, struct inode *inode,
                                     __u64 *id)
 {
-        mds->mds_fsops->fs_get_objid(inode, id);
+        return mds->mds_fsops->fs_get_objid(inode, id);
 }
 
 static inline ssize_t mds_fs_readpage(struct mds_obd *mds, struct file *file,
@@ -230,9 +229,15 @@ static inline ssize_t mds_fs_journal_data(struct mds_obd *mds,
         return mds->mds_fsops->fs_journal_data(file);
 }
 
-extern struct mds_fs_operations mds_ext2_fs_ops;
-extern struct mds_fs_operations mds_ext3_fs_ops;
-extern struct mds_fs_operations mds_extN_fs_ops;
+#define MDS_FSOP_UNLINK         1
+#define MDS_FSOP_RMDIR          2
+#define MDS_FSOP_RENAME         3
+#define MDS_FSOP_CREATE         4
+#define MDS_FSOP_MKDIR          5
+#define MDS_FSOP_SYMLINK        6
+#define MDS_FSOP_MKNOD          7
+#define MDS_FSOP_SETATTR        8
+#define MDS_FSOP_LINK           9
 
 #endif /* __KERNEL__ */
 
index 2885bf4..8c94e54 100644 (file)
@@ -6,8 +6,8 @@
 DEFS:= 
 
 MODULE = mds
-modulefs_DATA = mds.o
-EXTRA_PROGRAMS = mds
+modulefs_DATA = mds.o mds_ext2.o mds_ext3.o mds_extN.o
+EXTRA_PROGRAMS = mds mds_ext2 mds_ext3 mds_extN
 
 LINX=mds_updates.c simple.c
 mds_updates.c: 
@@ -16,7 +16,7 @@ mds_updates.c:
 simple.c: 
        test -e simple.c || ln -sf $(top_srcdir)/lib/simple.c
 
-mds_SOURCES = handler.c mds_reint.c mds_ext2.c mds_ext3.c $(LINX)
+mds_SOURCES = handler.c mds_reint.c mds_fs.c $(LINX)
 
 dist-hook:
        list='$(LINX)'; for f in $$list; do rm -f $(distdir)/$$f; done
index 95c897c..5098093 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/lustre_mds.h>
 
+static
 int mds_sendpage(struct ptlrpc_request *req, struct file *file, __u64 offset)
 {
         int rc = 0;
@@ -135,110 +136,7 @@ struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid,
         return result;
 }
 
-#define MDS_MAX_CLIENTS 1024
-#define MDS_MAX_CLIENT_WORDS (MDS_MAX_CLIENTS / sizeof(unsigned long))
-
-static unsigned long last_rcvd_slots[MDS_MAX_CLIENT_WORDS];
-
-/* Add client data to the MDS.  The in-memory storage will be a hash at some
- * point.  We use a bitmap to locate a free space in the last_rcvd file if
- * cl_off is -1 (i.e. a new client).  Otherwise, we have just read the data
- * from the last_rcvd file and we know its offset.
- */
-int mds_client_add(struct mds_obd *mds, struct mds_client_data *mcd, int cl_off)
-{
-        struct mds_client_info *mci;
-
-        OBD_ALLOC(mci, sizeof(*mci));
-        if (!mci) {
-                CERROR("no memory for MDS client info\n");
-                RETURN(-ENOMEM);
-        }
-        INIT_LIST_HEAD(&mci->mci_open_head);
-
-        CDEBUG(D_INFO, "client at offset %d with UUID '%s' added\n",
-               cl_off, mcd->mcd_uuid);
-
-        if (cl_off == -1) {
-                unsigned long *word;
-                int bit;
-
-        repeat:
-                word = last_rcvd_slots;
-                while(*word == ~0UL)
-                        ++word;
-                if (word - last_rcvd_slots >= MDS_MAX_CLIENT_WORDS) {
-                        CERROR("no room in client MDS bitmap - fix code\n");
-                        return -ENOMEM;
-                }
-                bit = ffz(*word);
-                if (test_and_set_bit(bit, word)) {
-                        CERROR("found bit %d set for word %d - fix code\n",
-                               bit, word - last_rcvd_slots);
-                        goto repeat;
-                }
-                cl_off = word - last_rcvd_slots + bit;
-        } else {
-                if (test_and_set_bit(cl_off, last_rcvd_slots)) {
-                        CERROR("bit %d already set in bitmap - bad bad\n",
-                               cl_off);
-                        LBUG();
-                }
-        }
-
-        mci->mci_mcd = mcd;
-        mci->mci_off = cl_off;
-
-        /* For now we just put the clients in a list, not a hashed list */
-        list_add_tail(&mci->mci_list, &mds->mds_client_info);
-
-        mds->mds_client_count++;
-
-        return 0;
-}
-
-void mds_client_del(struct mds_obd *mds, struct mds_client_info *mci)
-{
-        unsigned long *word;
-        int bit;
-
-        word = last_rcvd_slots + mci->mci_off / sizeof(unsigned long);
-        bit = mci->mci_off % sizeof(unsigned long);
-
-        if (!test_and_clear_bit(bit, word)) {
-                CERROR("bit %d already clear in word %d - bad bad\n",
-                       bit, word - last_rcvd_slots);
-                LBUG();
-        }
-
-        --mds->mds_client_count;
-        list_del(&mci->mci_list);
-        OBD_FREE(mci->mci_mcd, sizeof(*mci->mci_mcd));
-        OBD_FREE(mci, sizeof (*mci));
-}
-
-int mds_client_free_all(struct mds_obd *mds)
-{
-        struct list_head *p, *n;
-
-        list_for_each_safe(p, n, &mds->mds_client_info) {
-                struct mds_client_info *mci;
-
-                mci = list_entry(p, struct mds_client_info, mci_list);
-                mds_client_del(mds, mci);
-        }
-
-        return 0;
-}
-
-int mds_server_free_data(struct mds_obd *mds)
-{
-        OBD_FREE(mds->mds_server_data, sizeof(*mds->mds_server_data));
-        mds->mds_server_data = NULL;
-
-        return 0;
-}
-
+static
 int mds_connect(struct ptlrpc_request *req)
 {
         struct mds_body *body;
@@ -295,6 +193,7 @@ int mds_connect(struct ptlrpc_request *req)
         RETURN(0);
 }
 
+static
 int mds_getattr(struct ptlrpc_request *req)
 {
         struct dentry *de;
@@ -335,7 +234,7 @@ int mds_getattr(struct ptlrpc_request *req)
 
                 if (rc < 0) {
                         req->rq_status = rc;
-                        CERROR("readlink failed: %d\n", req->rq_status);
+                        CERROR("readlink failed: %d\n", rc);
                         GOTO(out, 0);
                 }
         }
@@ -351,13 +250,21 @@ int mds_getattr(struct ptlrpc_request *req)
         body->size = inode->i_size;
         body->mode = inode->i_mode;
         body->nlink = inode->i_nlink;
-        body->valid = ~0;
-        mds_fs_get_objid(mds, inode, &body->objid);
+        if (S_ISREG(inode->i_mode)) {
+                rc = mds_fs_get_objid(mds, inode, &body->objid);
+                if (rc < 0) {
+                        req->rq_status = rc;
+                        CERROR("readlink failed: %d\n", rc);
+                        GOTO(out, 0);
+                }
+        }
+        body->valid = ~0; /* FIXME: should be more selective */
  out:
         l_dput(de);
         RETURN(0);
 }
 
+static
 int mds_open(struct ptlrpc_request *req)
 {
         struct mds_obd *mds = &req->rq_obd->u.mds;
@@ -432,6 +339,7 @@ int mds_open(struct ptlrpc_request *req)
         RETURN(0);
 }
 
+static
 int mds_close(struct ptlrpc_request *req)
 {
         struct dentry *de;
@@ -616,246 +524,12 @@ out:
         return 0;
 }
 
-/* This will be a hash table at some point. */
-int mds_init_client_data(struct mds_obd *mds)
-{
-        INIT_LIST_HEAD(&mds->mds_client_info);
-        return 0;
-}
-
-#define LAST_RCVD "last_rcvd"
-
-int mds_read_last_rcvd(struct mds_obd *mds, struct file *f)
-{
-        struct mds_server_data *msd;
-        struct mds_client_data *mcd = NULL;
-        loff_t fsize = f->f_dentry->d_inode->i_size;
-        loff_t off = 0;
-        int cl_off;
-        __u64 last_rcvd = 0;
-        __u64 last_mount;
-        int rc = 0;
-
-        OBD_ALLOC(msd, sizeof(*msd));
-        if (!msd)
-                RETURN(-ENOMEM);
-        rc = lustre_fread(f, (char *)msd, sizeof(*msd), &off);
-
-        mds->mds_server_data = msd;
-        if (rc == 0) {
-                CERROR("empty MDS %s, new MDS?\n", LAST_RCVD);
-                RETURN(0);
-        } else if (rc != sizeof(*msd)) {
-                CERROR("error reading MDS %s: rc = %d\n", LAST_RCVD, rc);
-                if (rc > 0) {
-                        rc = -EIO;
-                }
-                GOTO(err_msd, rc);
-        }
-
-        /*
-         * When we do a clean MDS shutdown, we save the last_rcvd into
-         * the header.  If we find clients with higher last_rcvd values
-         * then those clients may need recovery done.
-         */
-        last_rcvd = le64_to_cpu(msd->msd_last_rcvd);
-        mds->mds_last_rcvd = last_rcvd;
-        CDEBUG(D_INODE, "got %Lu for server last_rcvd value\n",
-               (unsigned long long)last_rcvd);
-
-        last_mount = le64_to_cpu(msd->msd_mount_count);
-        mds->mds_mount_count = last_mount;
-        CDEBUG(D_INODE, "got %Lu for server last_mount value\n",
-               (unsigned long long)last_mount);
-
-        for (off = MDS_LR_CLIENT, cl_off = 0, rc = sizeof(*mcd);
-             off <= fsize - sizeof(*mcd) && rc == sizeof(*mcd);
-             off = MDS_LR_CLIENT + ++cl_off * MDS_LR_SIZE) {
-                if (!mcd)
-                        OBD_ALLOC(mcd, sizeof(*mcd));
-                if (!mcd)
-                        GOTO(err_msd, rc = -ENOMEM);
-
-                rc = lustre_fread(f, (char *)mcd, sizeof(*mcd), &off);
-                if (rc != sizeof(*mcd)) {
-                        CERROR("error reading MDS %s offset %d: rc = %d\n",
-                               LAST_RCVD, cl_off, rc);
-                        if (rc > 0)
-                                rc = -EIO;
-                        break;
-                }
-
-                last_rcvd = le64_to_cpu(mcd->mcd_last_rcvd);
-                last_mount = le64_to_cpu(mcd->mcd_mount_count);
-
-                if (last_rcvd &&
-                    last_mount - mcd->mcd_mount_count < MDS_MOUNT_RECOV) {
-                        rc = mds_client_add(mds, mcd, cl_off);
-                        if (rc) {
-                                rc = 0;
-                                break;
-                        }
-                        mcd = NULL;
-                } else {
-                        CDEBUG(D_INFO,
-                               "client at offset %d with UUID '%s' ignored\n",
-                               cl_off, mcd->mcd_uuid);
-                }
-
-                if (last_rcvd > mds->mds_last_rcvd) {
-                        CDEBUG(D_OTHER,
-                               "client at offset %d has last_rcvd = %Lu\n",
-                               cl_off, (unsigned long long)last_rcvd);
-                        mds->mds_last_rcvd = last_rcvd;
-                }
-        }
-        CDEBUG(D_INODE, "got %Lu for highest last_rcvd value, %d clients\n",
-               (unsigned long long)mds->mds_last_rcvd, mds->mds_client_count);
-
-        /* After recovery, there can be no local uncommitted transactions */
-        mds->mds_last_committed = mds->mds_last_rcvd;
-
-        return 0;
-
-err_msd:
-        mds_server_free_data(mds);
-        return rc;
-}
-
-static int mds_prep(struct obd_device *obddev)
-{
-        struct obd_run_ctxt saved;
-        struct mds_obd *mds = &obddev->u.mds;
-        struct super_operations *s_ops;
-        struct dentry *dentry;
-        struct file *f;
-        int rc;
-
-        push_ctxt(&saved, &mds->mds_ctxt);
-        dentry = simple_mkdir(current->fs->pwd, "ROOT", 0700);
-        if (IS_ERR(dentry)) {
-                rc = PTR_ERR(dentry);
-                CERROR("cannot create ROOT directory: rc = %d\n", rc);
-                GOTO(err_pop, rc);
-        }
-        /* XXX probably want to hold on to this later... */
-        dput(dentry);
-        f = filp_open("ROOT", O_RDONLY, 0);
-        if (IS_ERR(f)) {
-                rc = PTR_ERR(f);
-                CERROR("cannot open ROOT: rc = %d\n", rc);
-                LBUG();
-                GOTO(err_pop, rc);
-        }
-
-        mds->mds_rootfid.id = f->f_dentry->d_inode->i_ino;
-        mds->mds_rootfid.generation = f->f_dentry->d_inode->i_generation;
-        mds->mds_rootfid.f_type = S_IFDIR;
-
-        rc = filp_close(f, 0);
-        if (rc) {
-                CERROR("cannot close ROOT: rc = %d\n", rc);
-                LBUG();
-        }
-
-        dentry = simple_mkdir(current->fs->pwd, "FH", 0700);
-        if (IS_ERR(dentry)) {
-                rc = PTR_ERR(dentry);
-                CERROR("cannot create FH directory: rc = %d\n", rc);
-                GOTO(err_pop, rc);
-        }
-        /* XXX probably want to hold on to this later... */
-        dput(dentry);
-
-        rc = mds_init_client_data(mds);
-        if (rc)
-                GOTO(err_pop, rc);
-
-        f = filp_open(LAST_RCVD, O_RDWR | O_CREAT, 0644);
-        if (IS_ERR(f)) {
-                rc = PTR_ERR(f);
-                CERROR("cannot open/create %s file: rc = %d\n", LAST_RCVD, rc);
-                GOTO(err_pop, rc = PTR_ERR(f));
-        }
-        if (!S_ISREG(f->f_dentry->d_inode->i_mode)) {
-                CERROR("%s is not a regular file!: mode = %o\n", LAST_RCVD,
-                       f->f_dentry->d_inode->i_mode);
-                GOTO(err_pop, rc = -ENOENT);
-        }
-
-        rc = mds_fs_journal_data(mds, f);
-        if (rc) {
-                CERROR("cannot journal data on %s: rc = %d\n", LAST_RCVD, rc);
-                GOTO(err_filp, rc);
-        }
-
-        rc = mds_read_last_rcvd(mds, f);
-        if (rc) {
-                CERROR("cannot read %s: rc = %d\n", LAST_RCVD, rc);
-                GOTO(err_client, rc);
-        }
-        mds->mds_rcvd_filp = f;
-        pop_ctxt(&saved);
-
-        /*
-         * Replace the client filesystem delete_inode method with our own,
-         * so that we can clear the object ID before the inode is deleted.
-         * The fs_delete_inode method will call cl_delete_inode for us.
-         *
-         * We need to do this for the MDS superblock only, hence we install
-         * a modified copy of the original superblock method table.
-         *
-         * We still assume that there is only a single MDS client filesystem
-         * type, as we don't have access to the mds struct in delete_inode
-         * and store the client delete_inode method in a global table.  This
-         * will only become a problem when multiple MDSs are running on a
-         * single host with different client filesystems.
-         */
-        OBD_ALLOC(s_ops, sizeof(*s_ops));
-        if (!s_ops)
-                GOTO(err_filp, rc = -ENOMEM);
-
-        memcpy(s_ops, mds->mds_sb->s_op, sizeof(*s_ops));
-        mds->mds_fsops->cl_delete_inode = s_ops->delete_inode;
-        s_ops->delete_inode = mds->mds_fsops->fs_delete_inode;
-        mds->mds_sb->s_op = s_ops;
-
-        mds->mds_service = ptlrpc_init_svc(128 * 1024,
-                                           MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL,
-                                           "self", mds_handle);
-
-        if (!mds->mds_service) {
-                CERROR("failed to start service\n");
-                GOTO(err_filp, rc = -EINVAL);
-        }
-
-        rc = ptlrpc_start_thread(obddev, mds->mds_service, "lustre_mds");
-        if (rc) {
-                CERROR("cannot start thread: rc = %d\n", rc);
-                GOTO(err_svc, rc);
-        }
-
-        RETURN(0);
-
-err_svc:
-        rpc_unregister_service(mds->mds_service);
-        OBD_FREE(mds->mds_service, sizeof(*mds->mds_service));
-err_client:
-        mds_client_free_all(mds);
-err_filp:
-        if (filp_close(f, 0))
-                CERROR("can't close %s after error\n", LAST_RCVD);
-err_pop:
-        pop_ctxt(&saved);
-
-        return rc;
-}
-
 /* Update the server data on disk.  This stores the new mount_count and
  * also the last_rcvd value to disk.  If we don't have a clean shutdown,
  * then the server last_rcvd value may be less than that of the clients.
  * This will alert us that we may need to do client recovery.
  */
+static
 int mds_update_server_data(struct mds_obd *mds)
 {
         struct obd_run_ctxt saved;
@@ -899,8 +573,6 @@ static int mds_recover(struct obd_device *obddev)
         return rc;
 }
 
-static int mds_cleanup(struct obd_device *obddev);
-
 /* mount the file system (secretly) */
 static int mds_setup(struct obd_device *obddev, obd_count len, void *buf)
 {
@@ -910,69 +582,72 @@ static int mds_setup(struct obd_device *obddev, obd_count len, void *buf)
         int rc = 0;
         ENTRY;
 
+        MOD_INC_USE_COUNT;
 #ifdef CONFIG_DEV_RDONLY
         dev_clear_rdonly(2);
 #endif
         if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2)
-                RETURN(-EINVAL);
+                GOTO(err_dec, rc = -EINVAL);
 
         mds->mds_fstype = strdup(data->ioc_inlbuf2);
 
-        if (!strcmp(mds->mds_fstype, "extN"))
-                mds->mds_fsops = &mds_extN_fs_ops;
-        else if (!strcmp(mds->mds_fstype, "ext3"))
-                mds->mds_fsops = &mds_ext3_fs_ops;
-        else if (!strcmp(mds->mds_fstype, "ext2"))
-                mds->mds_fsops = &mds_ext2_fs_ops;
-        else {
-                CERROR("unsupported MDS filesystem type %s\n", mds->mds_fstype);
-                GOTO(err_kfree, rc = -EPERM);
-        }
-
-        MOD_INC_USE_COUNT;
         mnt = do_kern_mount(mds->mds_fstype, 0, data->ioc_inlbuf1, NULL);
         if (IS_ERR(mnt)) {
                 rc = PTR_ERR(mnt);
                 CERROR("do_kern_mount failed: rc = %d\n", rc);
-                GOTO(err_dec, rc);
+                GOTO(err_kfree, rc);
         }
 
         mds->mds_sb = mnt->mnt_root->d_inode->i_sb;
         if (!mds->mds_sb)
                 GOTO(err_put, rc = -ENODEV);
 
-        mds->mds_vfsmnt = mnt;
-        mds->mds_ctxt.pwdmnt = mnt;
-        mds->mds_ctxt.pwd = mnt->mnt_root;
-        mds->mds_ctxt.fs = KERNEL_DS;
-
-        rc = mds_prep(obddev);
-        if (rc)
+        rc = mds_fs_setup(mds, mnt);
+        if (rc) {
+                CERROR("MDS filesystem method init failed: rc = %d\n", rc);
                 GOTO(err_put, rc);
+        }
 
-        rc = mds_recover(obddev);
+        mds->mds_service = ptlrpc_init_svc(128 * 1024,
+                                           MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL,                                           "self", mds_handle);
+        if (!mds->mds_service) {
+                CERROR("failed to start service\n");
+                GOTO(err_fs, rc = -EINVAL);
+        }
+
+        rc = ptlrpc_start_thread(obddev, mds->mds_service, "lustre_mds");
         if (rc) {
-                mds_cleanup(obddev);
-                RETURN(rc);
+                CERROR("cannot start thread: rc = %d\n", rc);
+                GOTO(err_svc, rc);
         }
 
+        rc = mds_recover(obddev);
+        if (rc)
+                GOTO(err_thread, rc);
+
         RETURN(0);
 
+err_thread:
+        ptlrpc_stop_all_threads(mds->mds_service);
+err_svc:
+        rpc_unregister_service(mds->mds_service);
+        OBD_FREE(mds->mds_service, sizeof(*mds->mds_service));
+err_fs:
+        mds_fs_cleanup(mds);
 err_put:
         unlock_kernel();
         mntput(mds->mds_vfsmnt);
         mds->mds_sb = 0;
         lock_kernel();
-err_dec:
-        MOD_DEC_USE_COUNT;
 err_kfree:
         kfree(mds->mds_fstype);
+err_dec:
+        MOD_DEC_USE_COUNT;
         return rc;
 }
 
 static int mds_cleanup(struct obd_device * obddev)
 {
-        struct super_operations *s_ops = NULL;
         struct super_block *sb;
         struct mds_obd *mds = &obddev->u.mds;
 
@@ -995,9 +670,7 @@ static int mds_cleanup(struct obd_device * obddev)
         if (!mds->mds_sb)
                 RETURN(0);
 
-        mds_client_free_all(mds);
         mds_update_server_data(mds);
-        mds_server_free_data(mds);
 
         if (mds->mds_rcvd_filp) {
                 int rc = filp_close(mds->mds_rcvd_filp, 0);
@@ -1006,7 +679,6 @@ static int mds_cleanup(struct obd_device * obddev)
                 if (rc)
                         CERROR("last_rcvd file won't close, rc=%d\n", rc);
         }
-        s_ops = sb->s_op;
 
         unlock_kernel();
         mntput(mds->mds_vfsmnt);
@@ -1016,7 +688,7 @@ static int mds_cleanup(struct obd_device * obddev)
 #ifdef CONFIG_DEV_RDONLY
         dev_clear_rdonly(2);
 #endif
-        OBD_FREE(s_ops, sizeof(*s_ops));
+        mds_fs_cleanup(mds);
 
         MOD_DEC_USE_COUNT;
         RETURN(0);
index dcc887a..b760102 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/ext2_fs.h>
 #include <linux/lustre_mds.h>
+#include <linux/module.h>
 
 static void *mds_ext2_start(struct inode *inode, int nblocks)
 {
@@ -67,9 +68,11 @@ static int mds_ext2_set_objid(struct inode *inode, void *handle, obd_id id)
         return 0;
 }
 
-static void mds_ext2_get_objid(struct inode *inode, obd_id *id)
+static int mds_ext2_get_objid(struct inode *inode, obd_id *id)
 {
         *id = le64_to_cpu(inode->u.ext2_i.i_data[0]);
+
+        return 0;
 }
 
 static ssize_t mds_ext2_readpage(struct file *file, char *buf, size_t count,
@@ -81,7 +84,7 @@ static ssize_t mds_ext2_readpage(struct file *file, char *buf, size_t count,
                 return generic_file_read(file, buf, count, offset);
 }
 
-struct mds_fs_operations mds_ext2_fs_ops;
+static struct mds_fs_operations mds_ext2_fs_ops;
 
 static void mds_ext2_delete_inode(struct inode *inode)
 {
@@ -104,7 +107,7 @@ static int mds_ext2_journal_data(struct file *filp)
         return 0;
 }
 
-struct mds_fs_operations mds_ext2_fs_ops = {
+static struct mds_fs_operations mds_ext2_fs_ops = {
         fs_start:       mds_ext2_start,
         fs_commit:      mds_ext2_stop,
         fs_setattr:     mds_ext2_setattr,
@@ -116,3 +119,20 @@ struct mds_fs_operations mds_ext2_fs_ops = {
         fs_journal_data:mds_ext2_journal_data,
         fs_set_last_rcvd:mds_ext2_set_last_rcvd,
 };
+
+static int __init mds_ext2_init(void)
+{
+        return mds_register_fs_type(&mds_ext2_fs_ops, "ext2");
+}
+
+static void __exit mds_ext2_exit(void)
+{
+        mds_unregister_fs_type("ext2");
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <adilger@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre MDS ext2 Filesystem Helper v0.1");
+MODULE_LICENSE("GPL");
+
+module_init(mds_ext2_init);
+module_exit(mds_ext2_exit);
index c2b5edc..5607345 100644 (file)
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
-#include <linux/extN_fs.h>
 #include <linux/lustre_mds.h>
+#include <linux/module.h>
+
+static struct mds_fs_operations mds_ext3_fs_ops;
+static kmem_cache_t *jcb_cache;
+static int jcb_cache_count;
+
+struct mds_cb_data {
+        struct journal_callback cb_jcb;
+        struct mds_obd *cb_mds;
+        __u64 cb_last_rcvd;
+};
 
 /*
  * We don't currently need any additional blocks for rmdir and
@@ -36,19 +46,29 @@ static void *mds_ext3_start(struct inode *inode, int op)
         switch(op) {
         case MDS_FSOP_RMDIR:
         case MDS_FSOP_UNLINK:
-                nblocks += EXT3_DELETE_TRANS_BLOCKS; break;
+                nblocks += EXT3_DELETE_TRANS_BLOCKS;
+                break;
         case MDS_FSOP_RENAME:
+                /* We may be modifying two directories */
                 nblocks += EXT3_DATA_TRANS_BLOCKS;
+        case MDS_FSOP_SYMLINK:
+                /* Possible new block + block bitmap + GDT for long symlink */
+                nblocks += 3;
         case MDS_FSOP_CREATE:
-                // FIXME: when we store oa_id in an EA we need more blocks
-                // nblocks += 0;
         case MDS_FSOP_MKDIR:
-        case MDS_FSOP_SYMLINK:
-                /* Create new directory or symlink (more data blocks) */
-                nblocks += 2;
         case MDS_FSOP_MKNOD:
-                /* Change parent directory + setattr on new inode */
-                nblocks += EXT3_DATA_TRANS_BLOCKS + 3;
+                /* New inode + block bitmap + GDT for new file */
+                nblocks += 3;
+        case MDS_FSOP_LINK:
+                /* Change parent directory */
+                nblocks += EXT3_DATA_TRANS_BLOCKS;
+                break;
+        case MDS_FSOP_SETATTR:
+                /* Setattr on inode */
+                nblocks += 1;
+                break;
+        default: CERROR("unknown transaction start op %d\n", op);
+                 LBUG();
         }
 
         return journal_start(EXT3_JOURNAL(inode), nblocks);
@@ -107,9 +127,11 @@ static int mds_ext3_set_objid(struct inode *inode, void *handle, obd_id id)
         return 0;
 }
 
-static void mds_ext3_get_objid(struct inode *inode, obd_id *id)
+static int mds_ext3_get_objid(struct inode *inode, obd_id *id)
 {
         *id = le64_to_cpu(EXT3_I(inode)->i_data[0]);
+
+        return 0;
 }
 
 static ssize_t mds_ext3_readpage(struct file *file, char *buf, size_t count,
@@ -139,36 +161,6 @@ static ssize_t mds_ext3_readpage(struct file *file, char *buf, size_t count,
         return rc;
 }
 
-static ssize_t mds_extN_readpage(struct file *file, char *buf, size_t count,
-                                 loff_t *offset)
-{
-        struct inode *inode = file->f_dentry->d_inode;
-        int rc = 0;
-
-        if (S_ISREG(inode->i_mode))
-                rc = file->f_op->read(file, buf, count, offset);
-        else {
-                struct buffer_head *bh;
-
-                /* FIXME: this assumes the blocksize == count, but the calling
-                 *        function will detect this as an error for now */
-                bh = extN_bread(NULL, inode,
-                                *offset >> inode->i_sb->s_blocksize_bits,
-                                0, &rc);
-
-                if (bh) {
-                        memcpy(buf, bh->b_data, inode->i_blksize);
-                        brelse(bh);
-                        rc = inode->i_blksize;
-                }
-        }
-
-        return rc;
-}
-
-struct mds_fs_operations mds_ext3_fs_ops;
-struct mds_fs_operations mds_extN_fs_ops;
-
 static void mds_ext3_delete_inode(struct inode *inode)
 {
         if (S_ISREG(inode->i_mode)) {
@@ -191,34 +183,6 @@ static void mds_ext3_delete_inode(struct inode *inode)
                 mds_ext3_fs_ops.cl_delete_inode(inode);
 }
 
-static void mds_extN_delete_inode(struct inode *inode)
-{
-        if (S_ISREG(inode->i_mode)) {
-                void *handle = mds_ext3_start(inode, MDS_FSOP_UNLINK);
-
-                if (IS_ERR(handle)) {
-                        CERROR("unable to start transaction");
-                        EXIT;
-                        return;
-                }
-                if (mds_ext3_set_objid(inode, handle, 0))
-                        CERROR("error clearing objid on %ld\n", inode->i_ino);
-
-                if (mds_extN_fs_ops.cl_delete_inode)
-                        mds_extN_fs_ops.cl_delete_inode(inode);
-
-                if (mds_ext3_commit(inode, handle))
-                        CERROR("error closing handle on %ld\n", inode->i_ino);
-        } else
-                mds_extN_fs_ops.cl_delete_inode(inode);
-}
-
-struct mds_cb_data {
-        struct journal_callback cb_jcb;
-        struct mds_obd *cb_mds;
-        __u64 cb_last_rcvd;
-};
-
 static void mds_ext3_callback_status(struct journal_callback *jcb, int error)
 {
         struct mds_cb_data *mcb = (struct mds_cb_data *)jcb;
@@ -228,7 +192,8 @@ static void mds_ext3_callback_status(struct journal_callback *jcb, int error)
         if (!error && mcb->cb_last_rcvd > mcb->cb_mds->mds_last_committed)
                 mcb->cb_mds->mds_last_committed = mcb->cb_last_rcvd;
 
-        OBD_FREE(mcb, sizeof(*mcb));
+        kmem_cache_free(jcb_cache, mcb);
+        --jcb_cache_count;
 }
 
 #ifdef HAVE_JOURNAL_CALLBACK
@@ -242,10 +207,11 @@ static int mds_ext3_set_last_rcvd(struct mds_obd *mds, void *handle)
 {
         struct mds_cb_data *mcb;
 
-        OBD_ALLOC(mcb, sizeof(*mcb));
+        mcb = kmem_cache_alloc(jcb_cache, GFP_NOFS);
         if (!mcb)
                 RETURN(-ENOMEM);
 
+        ++jcb_cache_count;
         mcb->cb_mds = mds;
         mcb->cb_last_rcvd = mds->mds_last_rcvd;
 
@@ -284,7 +250,7 @@ static int mds_ext3_journal_data(struct file *filp)
         return 0;
 }
 
-struct mds_fs_operations mds_ext3_fs_ops = {
+static struct mds_fs_operations mds_ext3_fs_ops = {
         fs_start:       mds_ext3_start,
         fs_commit:      mds_ext3_commit,
         fs_setattr:     mds_ext3_setattr,
@@ -297,15 +263,42 @@ struct mds_fs_operations mds_ext3_fs_ops = {
         fs_set_last_rcvd:mds_ext3_set_last_rcvd,
 };
 
-struct mds_fs_operations mds_extN_fs_ops = {
-        fs_start:       mds_ext3_start,
-        fs_commit:      mds_ext3_commit,
-        fs_setattr:     mds_ext3_setattr,
-        fs_set_objid:   mds_ext3_set_objid,
-        fs_get_objid:   mds_ext3_get_objid,
-        fs_readpage:    mds_extN_readpage,
-        fs_delete_inode:mds_extN_delete_inode,
-        cl_delete_inode:clear_inode,
-        fs_journal_data:mds_ext3_journal_data,
-        fs_set_last_rcvd:mds_ext3_set_last_rcvd,
-};
+static int __init mds_ext3_init(void)
+{
+        int rc;
+
+        jcb_cache = kmem_cache_create("mds_ext3_jcb",
+                                      sizeof(struct mds_cb_data), 0,
+                                      SLAB_POISON, NULL, NULL);
+        if (!jcb_cache) {
+                CERROR("error allocating MDS journal callback cache\n");
+                GOTO(out, rc = -ENOMEM);
+        }
+
+        rc = mds_register_fs_type(&mds_ext3_fs_ops, "ext3");
+
+        if (rc)
+                kmem_cache_destroy(jcb_cache);
+out:
+        return rc;
+}
+
+static void __exit mds_ext3_exit(void)
+{
+        int rc;
+
+        mds_unregister_fs_type("ext3");
+        rc = kmem_cache_destroy(jcb_cache);
+
+        if (rc || jcb_cache_count) {
+                CERROR("can't free MDS callback cache: count %d, rc = %d\n",
+                       jcb_cache_count, rc);
+        }
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <adilger@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre MDS ext3 Filesystem Helper v0.1");
+MODULE_LICENSE("GPL");
+
+module_init(mds_ext3_init);
+module_exit(mds_ext3_exit);
index a0eb20b..ee11330 100644 (file)
@@ -21,8 +21,9 @@
 #include <linux/extN_jbd.h>
 #include <linux/extN_xattr.h>
 #include <linux/lustre_mds.h>
+#include <linux/module.h>
 
-struct mds_fs_operations mds_extN_fs_ops;
+static struct mds_fs_operations mds_extN_fs_ops;
 static kmem_cache_t *jcb_cache;
 static int jcb_cache_count;
 
@@ -44,66 +45,6 @@ struct mds_objid {
 
 #define XATTR_MDS_MO_MAGIC              0x4711
 
-int mds_extN_init(struct mds_obd *mds)
-{
-        int rc;
-
-        /*
-         * Replace the client filesystem delete_inode method with our own,
-         * so that we can clear the object ID before the inode is deleted.
-         * The fs_delete_inode method will call cl_delete_inode for us.
-         *
-         * We need to do this for the MDS superblock only, hence we install
-         * a modified copy of the original superblock method table.
-         *
-         * We still assume that there is only a single MDS client filesystem
-         * type, as we don't have access to the mds struct in delete_inode
-         * and store the client delete_inode method in a global table.  This
-         * will only become a problem when multiple MDSs are running on a
-         * single host with different client filesystems.
-         */
-        OBD_ALLOC(mds->mds_sop, sizeof(*mds->mds_sop));
-        if (!mds->mds_sop)
-                GOTO(out, rc = -ENOMEM);
-
-        memcpy(mds->mds_sop, mds->mds_sb->s_op, sizeof(*mds->mds_sop));
-        mds_extN_fs_ops.cl_delete_inode = mds->mds_sop->delete_inode;
-        mds->mds_sop->delete_inode = mds_extN_fs_ops.fs_delete_inode;
-        mds->mds_sb->s_op = mds->mds_sop;
-
-        //rc = extN_xattr_register();
-        jcb_cache = kmem_cache_create("mds_extN_jcb",
-                                      sizeof(struct mds_cb_data), 0,
-                                      SLAB_POISON, NULL, NULL);
-        if (!jcb_cache) {
-                CERROR("error allocating MDS journal callback cache\n");
-                GOTO(out_sop, rc = -ENOMEM);
-        }
-
-        return 0;
-
-out_sop:
-        OBD_FREE(mds->mds_sop, sizeof(*mds->mds_sop));
-out:
-        return rc;
-}
-
-int mds_extN_exit(struct mds_obd *mds)
-{
-        int rc;
-
-        rc = kmem_cache_destroy(jcb_cache);
-
-        if (rc || jcb_cache_count) {
-                CERROR("can't free MDS callback cache: count %d, rc = %d\n",
-                       jcb_cache_count, rc);
-        }
-
-        //rc = extN_xattr_unregister();
-        OBD_FREE(mds->mds_sop, sizeof(*mds->mds_sop));
-        return rc;
-}
-
 /*
  * We don't currently need any additional blocks for rmdir and
  * unlink transactions because we are storing the OST oa_id inside
@@ -340,17 +281,57 @@ static int mds_extN_journal_data(struct file *filp)
         return 0;
 }
 
-struct mds_fs_operations mds_extN_fs_ops = {
-        fs_init:        mds_extN_init,
-        fs_exit:        mds_extN_exit,
-        fs_start:       mds_extN_start,
-        fs_commit:      mds_extN_commit,
-        fs_setattr:     mds_extN_setattr,
-        fs_set_objid:   mds_extN_set_objid,
-        fs_get_objid:   mds_extN_get_objid,
-        fs_readpage:    mds_extN_readpage,
-        fs_delete_inode:mds_extN_delete_inode,
-        cl_delete_inode:clear_inode,
-        fs_journal_data:mds_extN_journal_data,
-        fs_set_last_rcvd:mds_extN_set_last_rcvd,
+static struct mds_fs_operations mds_extN_fs_ops = {
+        fs_start:               mds_extN_start,
+        fs_commit:              mds_extN_commit,
+        fs_setattr:             mds_extN_setattr,
+        fs_set_objid:           mds_extN_set_objid,
+        fs_get_objid:           mds_extN_get_objid,
+        fs_readpage:            mds_extN_readpage,
+        fs_delete_inode:        mds_extN_delete_inode,
+        cl_delete_inode:        clear_inode,
+        fs_journal_data:        mds_extN_journal_data,
+        fs_set_last_rcvd:       mds_extN_set_last_rcvd,
 };
+
+static int __init mds_extN_init(void)
+{
+        int rc;
+
+        //rc = extN_xattr_register();
+        jcb_cache = kmem_cache_create("mds_extN_jcb",
+                                      sizeof(struct mds_cb_data), 0,
+                                      SLAB_POISON, NULL, NULL);
+        if (!jcb_cache) {
+                CERROR("error allocating MDS journal callback cache\n");
+                GOTO(out, rc = -ENOMEM);
+        }
+        rc = mds_register_fs_type(&mds_extN_fs_ops, "extN");
+
+        if (rc)
+                kmem_cache_destroy(jcb_cache);
+out:
+        return rc;
+}
+
+static void __exit mds_extN_exit(void)
+{
+        int rc;
+
+        mds_unregister_fs_type("extN");
+        rc = kmem_cache_destroy(jcb_cache);
+
+        if (rc || jcb_cache_count) {
+                CERROR("can't free MDS callback cache: count %d, rc = %d\n",
+                       jcb_cache_count, rc);
+        }
+
+        //rc = extN_xattr_unregister();
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <adilger@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre MDS extN Filesystem Helper v0.1");
+MODULE_LICENSE("GPL");
+
+module_init(mds_extN_init);
+module_exit(mds_extN_exit);