Whamcloud - gitweb
new mgs llog mechanism
authorlincent <lincent>
Wed, 24 Aug 2005 17:58:35 +0000 (17:58 +0000)
committerlincent <lincent>
Wed, 24 Aug 2005 17:58:35 +0000 (17:58 +0000)
lustre/include/linux/obd.h
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_llog.c
lustre/obdclass/llog_lvfs.c

index cb5e1fc..d26fd50 100644 (file)
@@ -321,7 +321,8 @@ struct mgs_obd {
         struct dentry                   *mgs_configs_dir;
         spinlock_t                       mgs_llogs_lock;
         struct list_head                 mgs_open_llogs;
-        struct llog_handle              *mgs_cfg_llh;
+        spinlock_t                       mgs_llhs_lock;
+        struct list_head                 mgs_update_llhs;
 };
 
 struct mds_obd {
index 40a25c3..2c07f21 100644 (file)
@@ -200,6 +200,7 @@ static int mgs_setup(struct obd_device *obd, obd_count len, void *buf)
         }
 
         INIT_LIST_HEAD(&mgs->mgs_open_llogs);
+        INIT_LIST_HEAD(&mgs->mgs_update_llhs);
 
         rc = llog_start_commit_thread();
         if (rc < 0)
@@ -401,6 +402,9 @@ static int mgs_lvfs_open_llog(__u64 id, struct dentry *dentry , void *data)
          
         list_for_each_entry_safe(mollog, n, llog_list, mol_list) {
                 if (mollog->mol_id == id) {
+                        spin_lock(&mollog->mol_lock);
+                        mollog->mol_ref++;
+                        spin_unlock(&mollog->mol_lock);
                         dget(dentry);
                         return 0;
                 }
@@ -415,6 +419,8 @@ static int mgs_lvfs_open_llog(__u64 id, struct dentry *dentry , void *data)
         mollog->mol_id = id;
         mollog->mol_dentry = dentry;
         mollog->mol_update = 0;
+        mollog->mol_ref = 1;
+        spin_lock_init(&mollog->mol_lock);
 
         spin_lock(&mgs->mgs_llogs_lock);
         list_add(&mollog->mol_list, &mgs->mgs_open_llogs);
index 4c59819..9f6f78c 100644 (file)
 #include <linux/lustre_fsfilt.h>
 #include "mgs_internal.h"
 
+static struct mgs_update_llh* mgs_get_update_handle(struct obd_device *obd,
+                                                    char *fsname, char *name)
+{
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct mgs_update_llh *mul, *l;
+        struct list_head *update_llh_list = &mgs->mgs_update_llhs;
+
+        list_for_each_entry_safe(mul, l, update_llh_list, mul_list) {
+                if (!strcmp(mul->mul_name, name) &&
+                    !strcmp(mul->mul_fsname, fsname))
+                        return mul;
+        }
+        return NULL;
+}
+
+static int mgs_new_update_handle(struct obd_device *obd,
+                                 struct mgs_update_llh *mul,
+                                 char  *fsname, char *name)
+{
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct list_head *update_llh_list = &mgs->mgs_update_llhs;
+        int rc = 0;
+
+        if(mgs_get_update_handle(obd, fsname, name))
+                GOTO(out, rc = -EBUSY);
+
+        OBD_ALLOC(mul, sizeof(*mul));
+        if (!mul) {
+                CERROR("Can not allocate memory for update_llh.\n");
+                GOTO(out, rc = -ENOMEM);
+        }
+        strncpy(mul->mul_name, name, sizeof mul->mul_name);
+        strncpy(mul->mul_fsname, fsname, sizeof mul->mul_fsname);
+
+        spin_lock(&mgs->mgs_llh_lock);
+        /*seach again, in case of race.*/
+        if (mgs_get_update_handle(obd, fsname, name))
+                 spin_unlock(&mgs->mgs_llh_lock);
+                 GOTO(out_free, rc = -EBUSY);
+        }
+        list_add(&mul->mul_list, &mgs->mgs_update_llhs);
+        spin_unlock(&mgs->mgs_llh_lock);
+
+out:
+        return rc;
+
+out_free:
+        OBD_FREE(mul, sizeof(*mul));
+        goto out;
+}
+
+static void mgs_free_update_handle(struct obd_device *obd,
+                                   struct mgs_update_llh *mul)
+{
+        struct mgs_obd *mgs = &obd->u.mgs;
+        
+        spin_lock(&mgs->mgs_llh_lock);
+        list_del(&mul->mul_list);
+        spin_unlock(&mgs->mgs_llh_lock);
+      
+        return;
+}
+
 static int mgs_start_record(struct obd_device *obd, 
                             struct obd_ioctl_data *data)
 {
         static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
         struct mgs_obd *mgs = &obd->u.mgs;
-                struct lvfs_run_ctxt saved;
-                struct llog_handle **llog_handle;
-                char *name = data->ioc_inlbuf1;
-                char *fsname = data->ioc_inlbuf2;
-                int rc = 0;
-
-                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
-                                 llog_handle, NULL, fsname, name);
-                if (rc == 0)
-                        llog_init_handle(llog_handle, LLOG_F_IS_PLAIN, 
-                                         &cfg_uuid);
-                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        struct lvfs_run_ctxt saved;
+        struct mgs_update_llh *mul;
+        struct llog_handle **llh_res;
+        char *name = data->ioc_inlbuf1;
+        char *fsname = data->ioc_inlbuf2;
+        int rc = 0;
 
+        rc = mgs_new_update_handle(obd, mul, fsname, name);
+        if (rc)
                 RETURN(rc);
+
+        llh_res = &mul->mul_llh;
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+        rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
+                         llh_res, NULL, fsname, name);
+        if (rc == 0)
+                llog_init_handle(*llh_res, LLOG_F_IS_PLAIN, 
+                                 &cfg_uuid);
+
+        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+        RETURN(rc);
 }
 
-int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
-                  void *karg, void *uarg)
+static int mgs_end_record(struct obd_device *obd, 
+                          struct obd_ioctl_data *data)
 {
         static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
-        struct obd_device *obd = exp->exp_obd;
         struct mgs_obd *mgs = &obd->u.mgs;
-        struct obd_ioctl_data *data = karg;
         struct lvfs_run_ctxt saved;
+        struct mgs_update_llh *mul;
+        char *name = data->ioc_inlbuf1;
+        char *fsname = data->ioc_inlbuf2;
         int rc = 0;
 
-        ENTRY;
-        CDEBUG(D_IOCTL, "handling ioctl cmd %#x\n", cmd);
+        mul = mgs_get_update_handle(obd, fsname, name);
+        if (!mul) {
+                CERROR("Can not get update handle for %s:%s \n",
+                       fsname, name);
+                return -EINVAL;
+        }
 
-        switch (cmd) {
-        case OBD_IOC_RECORD: {
-                char *name = data->ioc_inlbuf1;
-                char *fsname = data->ioc_inlbuf2;
-                if (mgs->mgs_cfg_llh)
-                        RETURN(-EBUSY);
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        rc = llog_close(mul->mul_llh);
+        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 
-                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
-                                 &mgs->mgs_cfg_llh, fsname, name);
-                if (rc == 0)
-                        llog_init_handle(mgs->mgs_cfg_llh, LLOG_F_IS_PLAIN,
-                                         &cfg_uuid);
-                else
-                        mgs->mgs_cfg_llh = NULL;
-                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        RETURN(rc);
+}
+
+static int mgs_clear_record(struct obd_device *obd, 
+                            struct obd_ioctl_data *data)
+{
+        static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct lvfs_run_ctxt saved;
+        struct mgs_update_llh *mul;
+        struct llog_handel **llh_res;
+        char *name = data->ioc_inlbuf1;
+        char *fsname = data->ioc_inlbuf2;
+        int rc = 0;
 
+        rc = mgs_new_update_handle(obd, mul, fsname, name);
+        if (rc)
                 RETURN(rc);
+
+        llh_res = &mul->mul_llh;
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
+                         llh_res, NULL, name);
+        if (rc == 0) {
+                llog_init_handle(mul->mul_llh, LLOG_F_IS_PLAIN, NULL);
+                rc = llog_destroy(mul->mul_llh);
+                llog_free_handle(mul->mul_llh);
         }
+        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 
-        case OBD_IOC_ENDRECORD: {
-                if (!mgs->mgs_cfg_llh)
-                        RETURN(-EBADF);
+        mgs_free_update_handle(obd, mul);
 
-                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                rc = llog_close(mgs->mgs_cfg_llh);
-                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        RETURN(rc);
+}
 
-                mgs->mgs_cfg_llh = NULL;
-                RETURN(rc);
+static int mgs_do_record(struct obd_device *obd,
+                         struct obd_ioctl_data *data,
+                         int from_user)
+{
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct mgs_update_llh *mul;
+        char *name = data->ioc_inlbuf1;
+        char *fsname = data->ioc_inlbuf2;
+        char *cfg_buf;
+        struct llog_rec_hdr rec;
+        int rc = 0;
+        
+        mul = mgs_get_update_handle(obd, fsname, name);
+        if (!mul) {
+                CERROR("Can not get update handle for %s:%s \n",
+                       fsname, name);
+                return -EINVAL;
         }
 
-        case OBD_IOC_CLEAR_LOG: {
-                char *name = data->ioc_inlbuf1;
-                if (mgs->mgs_cfg_llh)
-                        RETURN(-EBUSY);
-
-                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
-                                 &mgs->mgs_cfg_llh, NULL, name);
-                if (rc == 0) {
-                        llog_init_handle(mgs->mgs_cfg_llh, LLOG_F_IS_PLAIN,
-                                         NULL);
-
-                        rc = llog_destroy(mgs->mgs_cfg_llh);
-                        llog_free_handle(mgs->mgs_cfg_llh);
-                }
-                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        rec.lrh_len = llog_data_len(data->ioc_plen1);
 
-                mgs->mgs_cfg_llh = NULL;
-                RETURN(rc);
+        if (data->ioc_type == LUSTRE_CFG_TYPE) {
+                rec.lrh_type = OBD_CFG_REC;
+        } else {
+                CERROR("unknown cfg record type:%d \n", data->ioc_type);
+                RETURN(-EINVAL);
         }
 
-        case OBD_IOC_DORECORD: {
-                char *cfg_buf;
-                struct llog_rec_hdr rec;
-                if (!mgs->mgs_cfg_llh)
-                        RETURN(-EBADF);
-
-                rec.lrh_len = llog_data_len(data->ioc_plen1);
-
-                if (data->ioc_type == LUSTRE_CFG_TYPE) {
-                        rec.lrh_type = OBD_CFG_REC;
-                } else {
-                        CERROR("unknown cfg record type:%d \n", data->ioc_type);
-                        RETURN(-EINVAL);
-                }
-
+        if (from_user) {
                 OBD_ALLOC(cfg_buf, data->ioc_plen1);
                 if (cfg_buf == NULL)
-                        RETURN(-EINVAL);
+                        RETURN(-ENOMEM);
                 rc = copy_from_user(cfg_buf, data->ioc_pbuf1, data->ioc_plen1);
                 if (rc) {
                         OBD_FREE(cfg_buf, data->ioc_plen1);
                         RETURN(rc);
                 }
+        } else
+                cfg_buf = data->ioc_bulk;
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        rc = llog_write_rec(mul->mul_llh, &rec, NULL, 0, cfg_buf, -1);
+        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+        OBD_FREE(cfg_buf, data->ioc_plen1);
+        RETURN(rc);
+}
 
-                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                rc = llog_write_rec(mgs->mgs_cfg_llh, &rec, NULL, 0,
-                                    cfg_buf, -1);
-                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
+                  void *karg, void *uarg)
+{
+        static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
+        struct obd_device *obd = exp->exp_obd;
+        struct mgs_obd *mgs = &obd->u.mgs;
+        struct obd_ioctl_data *data = karg;
+        struct lvfs_run_ctxt saved;
+        int rc = 0;
+
+        ENTRY;
+        CDEBUG(D_IOCTL, "handling ioctl cmd %#x\n", cmd);
+
+        switch (cmd) {
+        case OBD_IOC_RECORD: {
+                rc = mgs_start_record(obd, data);
+                RETURN(rc);
+        }
+
+        case OBD_IOC_ENDRECORD: {
+                rc = mgs_end_record(obd, data);
+                RETURN(rc);
+        }
+
+        case OBD_IOC_CLEAR_LOG: {
+                rc = mgs_clear_record(obd, data);
+                RETURN(rc);
+        }
 
-                OBD_FREE(cfg_buf, data->ioc_plen1);
+        case OBD_IOC_DORECORD: {
+                rc = mgs_do_record(obd, data, 1);
                 RETURN(rc);
         }
 
index d061501..39c2613 100644 (file)
@@ -507,16 +507,17 @@ static int llog_lvfs_create(struct llog_ctxt *ctxt, struct llog_handle **res,
                 handle->lgh_id = *logid;
 
         } else if (name) {
-                handle->lgh_file = llog_filp_open(fsname, 
-                                                      name, open_flags, 0644);
+                handle->lgh_file = llog_filp_open(fsname, name, open_flags, 0644);
 
                 if (IS_ERR(handle->lgh_file))
                         GOTO(cleanup, rc = PTR_ERR(handle->lgh_file));
+
                 rc = obd_lvfs_open_llog(ctxt->loc_exp, 
                                    handle->lgh_file->f_dentry->d_inode->i_ino,
                                    handle->lgh_file->f_dentry);
                 if (rc)
                         GOTO(cleanup, rc);
+
                 handle->lgh_id.lgl_ogr = 1;
                 handle->lgh_id.lgl_oid =
                         handle->lgh_file->f_dentry->d_inode->i_ino;