ldlm_lib.c

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

C
1,701
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (c) 2003 Cluster File Systems, Inc. * *   This file is part of the Lustre file system, http://www.lustre.org *   Lustre is a trademark of Cluster File Systems, Inc. * *   You may have signed or agreed to another license before downloading *   this software.  If so, you are bound by the terms and conditions *   of that agreement, and the following does not apply to you.  See the *   LICENSE file included with this distribution for more information. * *   If you did not agree to a different license, then this copy of Lustre *   is open source software; you can redistribute it and/or modify it *   under the terms of version 2 of the GNU General Public License as *   published by the Free Software Foundation. * *   In either case, Lustre is distributed in the hope that it will be *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   license text for more details. */#ifndef EXPORT_SYMTAB# define EXPORT_SYMTAB#endif#define DEBUG_SUBSYSTEM S_LDLM#ifdef __KERNEL__# include <libcfs/libcfs.h>#else# include <liblustre.h>#endif#include <obd.h>#include <lustre_mds.h>#include <lustre_dlm.h>#include <lustre_net.h>#include "ldlm_internal.h"/* @priority: if non-zero, move the selected to the list head * @create: if zero, only search in existed connections */static int import_set_conn(struct obd_import *imp, struct obd_uuid *uuid,                           int priority, int create){        struct ptlrpc_connection *ptlrpc_conn;        struct obd_import_conn *imp_conn = NULL, *item;        int rc = 0;        ENTRY;        if (!create && !priority) {                CDEBUG(D_HA, "Nothing to do\n");                RETURN(-EINVAL);        }        ptlrpc_conn = ptlrpc_uuid_to_connection(uuid);        if (!ptlrpc_conn) {                CDEBUG(D_HA, "can't find connection %s\n", uuid->uuid);                RETURN (-ENOENT);        }        if (create) {                OBD_ALLOC(imp_conn, sizeof(*imp_conn));                if (!imp_conn) {                        GOTO(out_put, rc = -ENOMEM);                }        }        spin_lock(&imp->imp_lock);        list_for_each_entry(item, &imp->imp_conn_list, oic_item) {                if (obd_uuid_equals(uuid, &item->oic_uuid)) {                        if (priority) {                                list_del(&item->oic_item);                                list_add(&item->oic_item, &imp->imp_conn_list);                                item->oic_last_attempt = 0;                        }                        CDEBUG(D_HA, "imp %p@%s: found existing conn %s%s\n",                               imp, imp->imp_obd->obd_name, uuid->uuid,                               (priority ? ", moved to head" : ""));                        spin_unlock(&imp->imp_lock);                        GOTO(out_free, rc = 0);                }        }        /* not found */        if (create) {                imp_conn->oic_conn = ptlrpc_conn;                imp_conn->oic_uuid = *uuid;                item->oic_last_attempt = 0;                if (priority)                        list_add(&imp_conn->oic_item, &imp->imp_conn_list);                else                        list_add_tail(&imp_conn->oic_item, &imp->imp_conn_list);                CDEBUG(D_HA, "imp %p@%s: add connection %s at %s\n",                       imp, imp->imp_obd->obd_name, uuid->uuid,                       (priority ? "head" : "tail"));        } else {                spin_unlock(&imp->imp_lock);                GOTO(out_free, rc = -ENOENT);        }        spin_unlock(&imp->imp_lock);        RETURN(0);out_free:        if (imp_conn)                OBD_FREE(imp_conn, sizeof(*imp_conn));out_put:        ptlrpc_put_connection(ptlrpc_conn);        RETURN(rc);}int import_set_conn_priority(struct obd_import *imp, struct obd_uuid *uuid){        return import_set_conn(imp, uuid, 1, 0);}int client_import_add_conn(struct obd_import *imp, struct obd_uuid *uuid,                           int priority){        return import_set_conn(imp, uuid, priority, 1);}int client_import_del_conn(struct obd_import *imp, struct obd_uuid *uuid){        struct obd_import_conn *imp_conn;        struct obd_export *dlmexp;        int rc = -ENOENT;        ENTRY;        spin_lock(&imp->imp_lock);        if (list_empty(&imp->imp_conn_list)) {                LASSERT(!imp->imp_connection);                GOTO(out, rc);        }        list_for_each_entry(imp_conn, &imp->imp_conn_list, oic_item) {                if (!obd_uuid_equals(uuid, &imp_conn->oic_uuid))                        continue;                LASSERT(imp_conn->oic_conn);                /* is current conn? */                if (imp_conn == imp->imp_conn_current) {                        LASSERT(imp_conn->oic_conn == imp->imp_connection);                        if (imp->imp_state != LUSTRE_IMP_CLOSED &&                            imp->imp_state != LUSTRE_IMP_DISCON) {                                CERROR("can't remove current connection\n");                                GOTO(out, rc = -EBUSY);                        }                        ptlrpc_put_connection(imp->imp_connection);                        imp->imp_connection = NULL;                        dlmexp = class_conn2export(&imp->imp_dlm_handle);                        if (dlmexp && dlmexp->exp_connection) {                                LASSERT(dlmexp->exp_connection ==                                        imp_conn->oic_conn);                                ptlrpc_put_connection(dlmexp->exp_connection);                                dlmexp->exp_connection = NULL;                        }                }                list_del(&imp_conn->oic_item);                ptlrpc_put_connection(imp_conn->oic_conn);                OBD_FREE(imp_conn, sizeof(*imp_conn));                CDEBUG(D_HA, "imp %p@%s: remove connection %s\n",                       imp, imp->imp_obd->obd_name, uuid->uuid);                rc = 0;                break;        }out:        spin_unlock(&imp->imp_lock);        if (rc == -ENOENT)                CERROR("connection %s not found\n", uuid->uuid);        RETURN(rc);}/* configure an RPC client OBD device * * lcfg parameters: * 1 - client UUID * 2 - server UUID * 3 - inactive-on-startup */int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf){        struct lustre_cfg* lcfg = buf;        struct client_obd *cli = &obddev->u.cli;        struct obd_import *imp;        struct obd_uuid server_uuid;        int rq_portal, rp_portal, connect_op;        char *name = obddev->obd_type->typ_name;        int rc;        ENTRY;        /* In a more perfect world, we would hang a ptlrpc_client off of         * obd_type and just use the values from there. */        if (!strcmp(name, LUSTRE_OSC_NAME)) {#ifdef __KERNEL__                /* Can be removed in Lustre 1.8, for compatibility only */                rq_portal = OST_IO_PORTAL;#else                rq_portal = OST_REQUEST_PORTAL;#endif                rp_portal = OSC_REPLY_PORTAL;                connect_op = OST_CONNECT;        } else if (!strcmp(name, LUSTRE_MDC_NAME)) {                rq_portal = MDS_REQUEST_PORTAL;                rp_portal = MDC_REPLY_PORTAL;                connect_op = MDS_CONNECT;        } else if (!strcmp(name, LUSTRE_MGC_NAME)) {                rq_portal = MGS_REQUEST_PORTAL;                rp_portal = MGC_REPLY_PORTAL;                connect_op = MGS_CONNECT;        } else {                CERROR("unknown client OBD type \"%s\", can't setup\n",                       name);                RETURN(-EINVAL);        }        if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {                CERROR("requires a TARGET UUID\n");                RETURN(-EINVAL);        }        if (LUSTRE_CFG_BUFLEN(lcfg, 1) > 37) {                CERROR("client UUID must be less than 38 characters\n");                RETURN(-EINVAL);        }        if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1) {                CERROR("setup requires a SERVER UUID\n");                RETURN(-EINVAL);        }        if (LUSTRE_CFG_BUFLEN(lcfg, 2) > 37) {                CERROR("target UUID must be less than 38 characters\n");                RETURN(-EINVAL);        }        sema_init(&cli->cl_sem, 1);        sema_init(&cli->cl_mgc_sem, 1);        cli->cl_conn_count = 0;        memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),               min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),                     sizeof(server_uuid)));        cli->cl_dirty = 0;        cli->cl_avail_grant = 0;        /* FIXME: should limit this for the sum of all cl_dirty_max */        cli->cl_dirty_max = OSC_MAX_DIRTY_DEFAULT * 1024 * 1024;        if (cli->cl_dirty_max >> CFS_PAGE_SHIFT > num_physpages / 8)                cli->cl_dirty_max = num_physpages << (CFS_PAGE_SHIFT - 3);        CFS_INIT_LIST_HEAD(&cli->cl_cache_waiters);        CFS_INIT_LIST_HEAD(&cli->cl_loi_ready_list);        CFS_INIT_LIST_HEAD(&cli->cl_loi_write_list);        CFS_INIT_LIST_HEAD(&cli->cl_loi_read_list);        client_obd_list_lock_init(&cli->cl_loi_list_lock);        cli->cl_r_in_flight = 0;        cli->cl_w_in_flight = 0;        spin_lock_init(&cli->cl_read_rpc_hist.oh_lock);        spin_lock_init(&cli->cl_write_rpc_hist.oh_lock);        spin_lock_init(&cli->cl_read_page_hist.oh_lock);        spin_lock_init(&cli->cl_write_page_hist.oh_lock);        spin_lock_init(&cli->cl_read_offset_hist.oh_lock);        spin_lock_init(&cli->cl_write_offset_hist.oh_lock);        cfs_waitq_init(&cli->cl_destroy_waitq);        atomic_set(&cli->cl_destroy_in_flight, 0);#ifdef ENABLE_CHECKSUM        /* Turn on checksumming by default. */        cli->cl_checksum = 1;        /*         * The supported checksum types will be worked out at connect time         * Set cl_chksum* to CRC32 for now to avoid returning screwed info         * through procfs.         */        cli->cl_cksum_type = cli->cl_supp_cksum_types = OBD_CKSUM_CRC32;#endif        atomic_set(&cli->cl_resends, OSC_DEFAULT_RESENDS);        /* This value may be changed at connect time in           ptlrpc_connect_interpret. */        cli->cl_max_pages_per_rpc = min((int)PTLRPC_MAX_BRW_PAGES,                                        (int)(1024 * 1024 >> CFS_PAGE_SHIFT));        if (!strcmp(name, LUSTRE_MDC_NAME)) {                cli->cl_max_rpcs_in_flight = MDC_MAX_RIF_DEFAULT;        } else if (num_physpages >> (20 - CFS_PAGE_SHIFT) <= 128 /* MB */) {                cli->cl_max_rpcs_in_flight = 2;        } else if (num_physpages >> (20 - CFS_PAGE_SHIFT) <= 256 /* MB */) {                cli->cl_max_rpcs_in_flight = 3;        } else if (num_physpages >> (20 - CFS_PAGE_SHIFT) <= 512 /* MB */) {                cli->cl_max_rpcs_in_flight = 4;        } else {                cli->cl_max_rpcs_in_flight = OSC_MAX_RIF_DEFAULT;        }        rc = ldlm_get_ref();        if (rc) {                CERROR("ldlm_get_ref failed: %d\n", rc);                GOTO(err, rc);        }        ptlrpc_init_client(rq_portal, rp_portal, name,                           &obddev->obd_ldlm_client);        imp = class_new_import(obddev);        if (imp == NULL)                GOTO(err_ldlm, rc = -ENOENT);        imp->imp_client = &obddev->obd_ldlm_client;        imp->imp_connect_op = connect_op;        imp->imp_initial_recov = 1;        imp->imp_initial_recov_bk = 0;        CFS_INIT_LIST_HEAD(&imp->imp_pinger_chain);        memcpy(cli->cl_target_uuid.uuid, lustre_cfg_buf(lcfg, 1),               LUSTRE_CFG_BUFLEN(lcfg, 1));        class_import_put(imp);        rc = client_import_add_conn(imp, &server_uuid, 1);        if (rc) {                CERROR("can't add initial connection\n");                GOTO(err_import, rc);        }        cli->cl_import = imp;        /* cli->cl_max_mds_{easize,cookiesize} updated by mdc_init_ea_size() */        cli->cl_max_mds_easize = sizeof(struct lov_mds_md);        cli->cl_max_mds_cookiesize = sizeof(struct llog_cookie);        if (LUSTRE_CFG_BUFLEN(lcfg, 3) > 0) {                if (!strcmp(lustre_cfg_string(lcfg, 3), "inactive")) {                        CDEBUG(D_HA, "marking %s %s->%s as inactive\n",                               name, obddev->obd_name,                               cli->cl_target_uuid.uuid);                        spin_lock(&imp->imp_lock);                        imp->imp_invalid = 1;                        spin_unlock(&imp->imp_lock);                }        }        cli->cl_qchk_stat = CL_NOT_QUOTACHECKED;

⌨️ 快捷键说明

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