From: lincent Date: Wed, 24 Aug 2005 17:58:35 +0000 (+0000) Subject: new mgs llog mechanism X-Git-Tag: v1_8_0_110~486^4~175^2~3 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=2164f3296c130d55bec4f303b69f353d1dbb7da7;p=fs%2Flustre-release.git new mgs llog mechanism --- diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index cb5e1fc..d26fd50 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -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 { diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 40a25c3..2c07f21 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -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); diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index 4c59819..9f6f78c 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -38,124 +38,235 @@ #include #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); } diff --git a/lustre/obdclass/llog_lvfs.c b/lustre/obdclass/llog_lvfs.c index d061501..39c2613 100644 --- a/lustre/obdclass/llog_lvfs.c +++ b/lustre/obdclass/llog_lvfs.c @@ -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;