genops.c

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

C
1,319
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (c) 2001-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. * * These are the only exported functions, they provide some generic * infrastructure for managing object devices */#define DEBUG_SUBSYSTEM S_CLASS#ifndef __KERNEL__#include <liblustre.h>#endif#include <obd_ost.h>#include <obd_class.h>#include <lprocfs_status.h>#include <class_hash.h>extern struct list_head obd_types;spinlock_t obd_types_lock;cfs_mem_cache_t *obd_device_cachep;cfs_mem_cache_t *obdo_cachep;EXPORT_SYMBOL(obdo_cachep);cfs_mem_cache_t *import_cachep;struct list_head  obd_zombie_imports;struct list_head  obd_zombie_exports;spinlock_t        obd_zombie_impexp_lock;void            (*obd_zombie_impexp_notify)(void) = NULL;EXPORT_SYMBOL(obd_zombie_impexp_notify);int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c);/* * support functions: we could use inter-module communication, but this * is more portable to other OS's */static struct obd_device *obd_device_alloc(void){        struct obd_device *obd;        OBD_SLAB_ALLOC_PTR(obd, obd_device_cachep);        if (obd != NULL) {                obd->obd_magic = OBD_DEVICE_MAGIC;        }        return obd;}EXPORT_SYMBOL(obd_device_alloc);static void obd_device_free(struct obd_device *obd){        LASSERT(obd != NULL);        LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, "obd %p obd_magic %08x != %08x\n",                  obd, obd->obd_magic, OBD_DEVICE_MAGIC);        OBD_SLAB_FREE_PTR(obd, obd_device_cachep);}EXPORT_SYMBOL(obd_device_free);struct obd_type *class_search_type(const char *name){        struct list_head *tmp;        struct obd_type *type;        spin_lock(&obd_types_lock);        list_for_each(tmp, &obd_types) {                type = list_entry(tmp, struct obd_type, typ_chain);                if (strcmp(type->typ_name, name) == 0) {                        spin_unlock(&obd_types_lock);                        return type;                }        }        spin_unlock(&obd_types_lock);        return NULL;}struct obd_type *class_get_type(const char *name){        struct obd_type *type = class_search_type(name);#ifdef CONFIG_KMOD        if (!type) {                const char *modname = name;                if (strcmp(modname, LUSTRE_MDT_NAME) == 0)                         modname = LUSTRE_MDS_NAME;                if (!request_module(modname)) {                        CDEBUG(D_INFO, "Loaded module '%s'\n", modname);                        type = class_search_type(name);                } else {                        LCONSOLE_ERROR_MSG(0x158, "Can't load module '%s'\n",                                           modname);                }        }#endif        if (type) {                spin_lock(&type->obd_type_lock);                type->typ_refcnt++;                try_module_get(type->typ_ops->o_owner);                spin_unlock(&type->obd_type_lock);        }        return type;}void class_put_type(struct obd_type *type){        LASSERT(type);        spin_lock(&type->obd_type_lock);        type->typ_refcnt--;        module_put(type->typ_ops->o_owner);        spin_unlock(&type->obd_type_lock);}int class_register_type(struct obd_ops *ops, struct lprocfs_vars *vars,                        const char *name){        struct obd_type *type;        int rc = 0;        ENTRY;        LASSERT(strnlen(name, 1024) < 1024);    /* sanity check */        if (class_search_type(name)) {                CDEBUG(D_IOCTL, "Type %s already registered\n", name);                RETURN(-EEXIST);        }        rc = -ENOMEM;        OBD_ALLOC(type, sizeof(*type));        if (type == NULL)                RETURN(rc);        OBD_ALLOC(type->typ_ops, sizeof(*type->typ_ops));        OBD_ALLOC(type->typ_name, strlen(name) + 1);        if (type->typ_ops == NULL || type->typ_name == NULL)                GOTO (failed, rc);        *(type->typ_ops) = *ops;        strcpy(type->typ_name, name);        spin_lock_init(&type->obd_type_lock);#ifdef LPROCFS        type->typ_procroot = lprocfs_register(type->typ_name, proc_lustre_root,                                              vars, type);        if (IS_ERR(type->typ_procroot)) {                rc = PTR_ERR(type->typ_procroot);                type->typ_procroot = NULL;                GOTO (failed, rc);        }#endif        spin_lock(&obd_types_lock);        list_add(&type->typ_chain, &obd_types);        spin_unlock(&obd_types_lock);        RETURN (0); failed:        if (type->typ_name != NULL)                OBD_FREE(type->typ_name, strlen(name) + 1);        if (type->typ_ops != NULL)                OBD_FREE (type->typ_ops, sizeof (*type->typ_ops));        OBD_FREE(type, sizeof(*type));        RETURN(rc);}int class_unregister_type(const char *name){        struct obd_type *type = class_search_type(name);        ENTRY;        if (!type) {                CERROR("unknown obd type\n");                RETURN(-EINVAL);        }        if (type->typ_refcnt) {                CERROR("type %s has refcount (%d)\n", name, type->typ_refcnt);                /* This is a bad situation, let's make the best of it */                /* Remove ops, but leave the name for debugging */                OBD_FREE(type->typ_ops, sizeof(*type->typ_ops));                RETURN(-EBUSY);        }        if (type->typ_procroot)                 lprocfs_remove(&type->typ_procroot);        spin_lock(&obd_types_lock);        list_del(&type->typ_chain);        spin_unlock(&obd_types_lock);        OBD_FREE(type->typ_name, strlen(name) + 1);        if (type->typ_ops != NULL)                OBD_FREE(type->typ_ops, sizeof(*type->typ_ops));        OBD_FREE(type, sizeof(*type));        RETURN(0);} /* class_unregister_type */struct obd_device *class_newdev(const char *type_name, const char *name){        struct obd_device *result = NULL;        struct obd_device *newdev;        struct obd_type *type = NULL;        int i;        int new_obd_minor = 0;        if (strlen(name) > MAX_OBD_NAME) {                CERROR("name/uuid must be < %u bytes long\n", MAX_OBD_NAME);                RETURN(ERR_PTR(-EINVAL));        }        type = class_get_type(type_name);        if (type == NULL){                CERROR("OBD: unknown type: %s\n", type_name);                RETURN(ERR_PTR(-ENODEV));        }        newdev = obd_device_alloc();        if (newdev == NULL) {                 class_put_type(type);                RETURN(ERR_PTR(-ENOMEM));        }        LASSERT(newdev->obd_magic == OBD_DEVICE_MAGIC);        spin_lock(&obd_dev_lock);        for (i = 0; i < class_devno_max(); i++) {                struct obd_device *obd = class_num2obd(i);                if (obd && obd->obd_name && (strcmp(name, obd->obd_name) == 0)){                        CERROR("Device %s already exists, won't add\n", name);                        if (result) {                                LASSERTF(result->obd_magic == OBD_DEVICE_MAGIC,                                         "%p obd_magic %08x != %08x\n", result,                                         result->obd_magic, OBD_DEVICE_MAGIC);                                LASSERTF(result->obd_minor == new_obd_minor,                                         "%p obd_minor %d != %d\n", result,                                         result->obd_minor, new_obd_minor);                                obd_devs[result->obd_minor] = NULL;                                result->obd_name[0]='\0';                        }                        result = ERR_PTR(-EEXIST);                        break;                }                if (!result && !obd) {                        result = newdev;                        result->obd_minor = i;                        new_obd_minor = i;                        result->obd_type = type;                        memcpy(result->obd_name, name, strlen(name));                        obd_devs[i] = result;                }        }        spin_unlock(&obd_dev_lock);                if (result == NULL && i >= class_devno_max()) {                CERROR("all %u OBD devices used, increase MAX_OBD_DEVICES\n",                       class_devno_max());                result = ERR_PTR(-EOVERFLOW);        }                if (IS_ERR(result)) {                obd_device_free(newdev);                class_put_type(type);        } else {                CDEBUG(D_IOCTL, "Adding new device %s (%p)\n",                       result->obd_name, result);        }        return result;}void class_release_dev(struct obd_device *obd){        struct obd_type *obd_type = obd->obd_type;        LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, "%p obd_magic %08x != %08x\n",                 obd, obd->obd_magic, OBD_DEVICE_MAGIC);        LASSERTF(obd == obd_devs[obd->obd_minor], "obd %p != obd_devs[%d] %p\n",                 obd, obd->obd_minor, obd_devs[obd->obd_minor]);        LASSERT(obd_type != NULL);        CDEBUG(D_INFO, "Release obd device %s obd_type name =%s\n",               obd->obd_name,obd->obd_type->typ_name);        spin_lock(&obd_dev_lock);        obd_devs[obd->obd_minor] = NULL;        spin_unlock(&obd_dev_lock);        obd_device_free(obd);        class_put_type(obd_type);}int class_name2dev(const char *name){        int i;        if (!name)                return -1;        spin_lock(&obd_dev_lock);        for (i = 0; i < class_devno_max(); i++) {                struct obd_device *obd = class_num2obd(i);                if (obd && obd->obd_name && strcmp(name, obd->obd_name) == 0) {                        /* Make sure we finished attaching before we give                           out any references */                        LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);                        if (obd->obd_attached) {                                spin_unlock(&obd_dev_lock);                                return i;                        }                        break;                }        }        spin_unlock(&obd_dev_lock);        return -1;}struct obd_device *class_name2obd(const char *name){        int dev = class_name2dev(name);        if (dev < 0 || dev > class_devno_max())                return NULL;        return class_num2obd(dev);}int class_uuid2dev(struct obd_uuid *uuid){        int i;        spin_lock(&obd_dev_lock);        for (i = 0; i < class_devno_max(); i++) {                struct obd_device *obd = class_num2obd(i);                if (obd && obd_uuid_equals(uuid, &obd->obd_uuid)) {                        LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);                        spin_unlock(&obd_dev_lock);                        return i;                }        }        spin_unlock(&obd_dev_lock);        return -1;}struct obd_device *class_uuid2obd(struct obd_uuid *uuid){        int dev = class_uuid2dev(uuid);        if (dev < 0)                return NULL;        return class_num2obd(dev);}struct obd_device *class_num2obd(int num){        struct obd_device *obd = NULL;        if (num < class_devno_max()) {                obd = obd_devs[num];                if (obd == NULL) {                        return NULL;                }                LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,                         "%p obd_magic %08x != %08x\n",                         obd, obd->obd_magic, OBD_DEVICE_MAGIC);                LASSERTF(obd->obd_minor == num,                         "%p obd_minor %0d != %0d\n",                         obd, obd->obd_minor, num);        }        return obd;}void class_obd_list(void){        char *status;        int i;        spin_lock(&obd_dev_lock);        for (i = 0; i < class_devno_max(); i++) {                struct obd_device *obd = class_num2obd(i);                if (obd == NULL)                        continue;                if (obd->obd_stopping)                        status = "ST";                else if (obd->obd_set_up)                        status = "UP";                else if (obd->obd_attached)                        status = "AT";                else                        status = "--";                LCONSOLE(D_CONFIG, "%3d %s %s %s %s %d\n",                         i, status, obd->obd_type->typ_name,                         obd->obd_name, obd->obd_uuid.uuid,                         atomic_read(&obd->obd_refcount));        }        spin_unlock(&obd_dev_lock);        return;}/* Search for a client OBD connected to tgt_uuid.  If grp_uuid is   specified, then only the client with that uuid is returned,   otherwise any client connected to the tgt is returned. */struct obd_device * class_find_client_obd(struct obd_uuid *tgt_uuid,                                          const char * typ_name,                                          struct obd_uuid *grp_uuid){        int i;        spin_lock(&obd_dev_lock);        for (i = 0; i < class_devno_max(); i++) {                struct obd_device *obd = class_num2obd(i);                if (obd == NULL)                        continue;                if ((strncmp(obd->obd_type->typ_name, typ_name,                             strlen(typ_name)) == 0)) {                        if (obd_uuid_equals(tgt_uuid,                                            &obd->u.cli.cl_target_uuid) &&                            ((grp_uuid)? obd_uuid_equals(grp_uuid,                                                         &obd->obd_uuid) : 1)) {                                spin_unlock(&obd_dev_lock);                                return obd;                        }

⌨️ 快捷键说明

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