echo_client.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,511 行 · 第 1/4 页

C
1,511
字号
        einfo.ei_mode = mode;        einfo.ei_cb_bl = echo_ldlm_callback;        einfo.ei_cb_cp = ldlm_completion_ast;        einfo.ei_cb_gl = NULL;        einfo.ei_cbdata = eco;        oinfo.oi_policy = ecl->ecl_policy;        oinfo.oi_lockh = &ecl->ecl_lock_handle;        oinfo.oi_md = eco->eco_lsm;        rc = obd_enqueue(ec->ec_exp, &oinfo, &einfo, NULL);        if (rc != 0)                goto failed_1;        CDEBUG(D_INFO, "enqueue handle "LPX64"\n", ecl->ecl_lock_handle.cookie);        /* NB ecl takes object ref from echo_get_object() above */        spin_lock(&ec->ec_lock);        list_add(&ecl->ecl_exp_chain, &exp->exp_ec_data.eced_locks);        ulh->cookie = ecl->ecl_cookie = ec->ec_unique++;        spin_unlock(&ec->ec_lock);        oa->o_valid |= OBD_MD_FLHANDLE;        return 0; failed_1:        OBD_FREE (ecl, sizeof (*ecl)); failed_0:        echo_put_object (eco);        return (rc);}static intecho_client_cancel(struct obd_export *exp, struct obdo *oa){        struct obd_device      *obd = exp->exp_obd;        struct echo_client_obd *ec = &obd->u.echo_client;        struct lustre_handle   *ulh = &oa->o_handle;        struct ec_lock         *ecl = NULL;        int                     found = 0;        struct list_head       *el;        int                     rc;        if ((oa->o_valid & OBD_MD_FLHANDLE) == 0)                return -EINVAL;        spin_lock (&ec->ec_lock);        list_for_each (el, &exp->exp_ec_data.eced_locks) {                ecl = list_entry (el, struct ec_lock, ecl_exp_chain);                found = (ecl->ecl_cookie == ulh->cookie);                if (found) {                        list_del (&ecl->ecl_exp_chain);                        break;                }        }        spin_unlock (&ec->ec_lock);        if (!found)                return (-ENOENT);        rc = obd_cancel(ec->ec_exp, ecl->ecl_object->eco_lsm, ecl->ecl_mode,                        &ecl->ecl_lock_handle);        echo_put_object (ecl->ecl_object);        OBD_FREE (ecl, sizeof (*ecl));        return rc;}static intecho_client_iocontrol(unsigned int cmd, struct obd_export *exp,                      int len, void *karg, void *uarg){        struct obd_device      *obd;        struct echo_client_obd *ec;        struct ec_object       *eco;        struct obd_ioctl_data  *data = karg;        struct obd_trans_info   dummy_oti;        struct oti_req_ack_lock *ack_lock;        struct obdo            *oa;        int                     rw = OBD_BRW_READ;        int                     rc = 0;        int                     i;        ENTRY;        unlock_kernel();        memset(&dummy_oti, 0, sizeof(dummy_oti));        obd = exp->exp_obd;        ec = &obd->u.echo_client;        switch (cmd) {        case OBD_IOC_CREATE:                    /* may create echo object */                if (!capable (CAP_SYS_ADMIN))                        GOTO (out, rc = -EPERM);                rc = echo_create_object (obd, 1, &data->ioc_obdo1,                                         data->ioc_pbuf1, data->ioc_plen1,                                         &dummy_oti);                GOTO(out, rc);        case OBD_IOC_DESTROY:                if (!capable (CAP_SYS_ADMIN))                        GOTO (out, rc = -EPERM);                rc = echo_get_object (&eco, obd, &data->ioc_obdo1);                if (rc == 0) {                        oa = &data->ioc_obdo1;                        oa->o_gr = FILTER_GROUP_ECHO;                        oa->o_valid |= OBD_MD_FLGROUP;                        rc = obd_destroy(ec->ec_exp, oa, eco->eco_lsm,                                         &dummy_oti, NULL);                        if (rc == 0)                                eco->eco_deleted = 1;                        echo_put_object(eco);                }                GOTO(out, rc);        case OBD_IOC_GETATTR:                rc = echo_get_object (&eco, obd, &data->ioc_obdo1);                if (rc == 0) {                        struct obd_info oinfo = { { { 0 } } };                        oinfo.oi_md = eco->eco_lsm;                        oinfo.oi_oa = &data->ioc_obdo1;                        rc = obd_getattr(ec->ec_exp, &oinfo);                        echo_put_object(eco);                }                GOTO(out, rc);        case OBD_IOC_SETATTR:                if (!capable (CAP_SYS_ADMIN))                        GOTO (out, rc = -EPERM);                rc = echo_get_object (&eco, obd, &data->ioc_obdo1);                if (rc == 0) {                        struct obd_info oinfo = { { { 0 } } };                        oinfo.oi_oa = &data->ioc_obdo1;                        oinfo.oi_md = eco->eco_lsm;                        rc = obd_setattr(ec->ec_exp, &oinfo, NULL);                        echo_put_object(eco);                }                GOTO(out, rc);        case OBD_IOC_BRW_WRITE:                if (!capable (CAP_SYS_ADMIN))                        GOTO (out, rc = -EPERM);                rw = OBD_BRW_WRITE;                /* fall through */        case OBD_IOC_BRW_READ:                rc = echo_client_brw_ioctl(rw, exp, data);                GOTO(out, rc);        case ECHO_IOC_GET_STRIPE:                rc = echo_get_object(&eco, obd, &data->ioc_obdo1);                if (rc == 0) {                        rc = echo_copyout_lsm(eco->eco_lsm, data->ioc_pbuf1,                                              data->ioc_plen1);                        echo_put_object(eco);                }                GOTO(out, rc);        case ECHO_IOC_SET_STRIPE:                if (!capable (CAP_SYS_ADMIN))                        GOTO (out, rc = -EPERM);                if (data->ioc_pbuf1 == NULL) {  /* unset */                        rc = echo_get_object(&eco, obd, &data->ioc_obdo1);                        if (rc == 0) {                                eco->eco_deleted = 1;                                echo_put_object(eco);                        }                } else {                        rc = echo_create_object(obd, 0, &data->ioc_obdo1,                                                data->ioc_pbuf1,                                                data->ioc_plen1, &dummy_oti);                }                GOTO (out, rc);        case ECHO_IOC_ENQUEUE:                if (!capable (CAP_SYS_ADMIN))                        GOTO (out, rc = -EPERM);                rc = echo_client_enqueue(exp, &data->ioc_obdo1,                                         data->ioc_conn1, /* lock mode */                                   data->ioc_offset, data->ioc_count);/*extent*/                GOTO (out, rc);        case ECHO_IOC_CANCEL:                rc = echo_client_cancel(exp, &data->ioc_obdo1);                GOTO (out, rc);        default:                CERROR ("echo_ioctl(): unrecognised ioctl %#x\n", cmd);                GOTO (out, rc = -ENOTTY);        }        EXIT; out:        /* XXX this should be in a helper also called by target_send_reply */        for (ack_lock = dummy_oti.oti_ack_locks, i = 0; i < 4;              i++, ack_lock++) {                if (!ack_lock->mode)                        break;                ldlm_lock_decref(&ack_lock->lock, ack_lock->mode);        }        lock_kernel();        return rc;}static intecho_client_setup(struct obd_device *obddev, obd_count len, void *buf){        struct lustre_cfg* lcfg = buf;        struct echo_client_obd *ec = &obddev->u.echo_client;        struct obd_device *tgt;        struct lustre_handle conn = {0, };        struct obd_uuid echo_uuid = { "ECHO_UUID" };        struct obd_connect_data *ocd = NULL;        int rc;        ENTRY;        if (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {                CERROR("requires a TARGET OBD name\n");                RETURN(-EINVAL);        }        tgt = class_name2obd(lustre_cfg_string(lcfg, 1));        if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) {                CERROR("device not attached or not set up (%s)\n",                       lustre_cfg_string(lcfg, 1));                RETURN(-EINVAL);        }        spin_lock_init (&ec->ec_lock);        CFS_INIT_LIST_HEAD (&ec->ec_objects);        ec->ec_unique = 0;        OBD_ALLOC(ocd, sizeof(*ocd));        if (ocd == NULL) {                CERROR("Can't alloc ocd connecting to %s\n",                       lustre_cfg_string(lcfg, 1));                return -ENOMEM;        }        ocd->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_REQPORTAL;        ocd->ocd_version = LUSTRE_VERSION_CODE;        rc = obd_connect(&conn, tgt, &echo_uuid, ocd, NULL);        OBD_FREE(ocd, sizeof(*ocd));        if (rc != 0) {                CERROR("fail to connect to device %s\n",                       lustre_cfg_string(lcfg, 1));                return (rc);        }        ec->ec_exp = class_conn2export(&conn);        RETURN(rc);}static int echo_client_cleanup(struct obd_device *obddev){        struct list_head       *el;        struct ec_object       *eco;        struct echo_client_obd *ec = &obddev->u.echo_client;        int rc;        ENTRY;        if (!list_empty(&obddev->obd_exports)) {                CERROR("still has clients!\n");                RETURN(-EBUSY);        }        /* XXX assuming sole access */        while (!list_empty(&ec->ec_objects)) {                el = ec->ec_objects.next;                eco = list_entry(el, struct ec_object, eco_obj_chain);                LASSERT(eco->eco_refcount == 0);                eco->eco_refcount = 1;                eco->eco_deleted = 1;                echo_put_object(eco);        }        rc = obd_disconnect(ec->ec_exp);        if (rc != 0)                CERROR("fail to disconnect device: %d\n", rc);        RETURN(rc);}static int echo_client_connect(struct lustre_handle *conn,                               struct obd_device *src, struct obd_uuid *cluuid,                               struct obd_connect_data *data, void *localdata){        struct obd_export *exp;        int                rc;        ENTRY;        rc = class_connect(conn, src, cluuid);        if (rc == 0) {                exp = class_conn2export(conn);                CFS_INIT_LIST_HEAD(&exp->exp_ec_data.eced_locks);                class_export_put(exp);        }        RETURN (rc);}static int echo_client_disconnect(struct obd_export *exp){        struct obd_device      *obd;        struct echo_client_obd *ec;        struct ec_lock         *ecl;        int                     rc;        ENTRY;        if (exp == NULL)                GOTO(out, rc = -EINVAL);        obd = exp->exp_obd;        ec = &obd->u.echo_client;        /* no more contention on export's lock list */        while (!list_empty (&exp->exp_ec_data.eced_locks)) {                ecl = list_entry (exp->exp_ec_data.eced_locks.next,                                  struct ec_lock, ecl_exp_chain);                list_del (&ecl->ecl_exp_chain);                rc = obd_cancel(ec->ec_exp, ecl->ecl_object->eco_lsm,                                 ecl->ecl_mode, &ecl->ecl_lock_handle);                CDEBUG (D_INFO, "Cancel lock on object "LPX64" on disconnect "                        "(%d)\n", ecl->ecl_object->eco_id, rc);                echo_put_object (ecl->ecl_object);                OBD_FREE (ecl, sizeof (*ecl));        }        rc = class_disconnect(exp);        GOTO(out, rc); out:        return rc;}static struct obd_ops echo_obd_ops = {        .o_owner       = THIS_MODULE,        .o_setup       = echo_client_setup,        .o_cleanup     = echo_client_cleanup,        .o_iocontrol   = echo_client_iocontrol,        .o_connect     = echo_client_connect,        .o_disconnect  = echo_client_disconnect};int echo_client_init(void){        struct lprocfs_static_vars lvars = { 0 };        lprocfs_echo_init_vars(&lvars);        return class_register_type(&echo_obd_ops, lvars.module_vars,                                   LUSTRE_ECHO_CLIENT_NAME);}void echo_client_exit(void){        class_unregister_type(LUSTRE_ECHO_CLIENT_NAME);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?