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 + -
显示快捷键?