class_obd.c
来自「lustre 1.6.5 source code」· C语言 代码 · 共 636 行 · 第 1/2 页
C
636 行
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Object Devices Class Driver * * 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 EXPORT_SYMTAB# define EXPORT_SYMTAB#endif#ifndef __KERNEL__# include <liblustre.h>#endif#include <obd_support.h>#include <obd_class.h>#include <lustre_debug.h>#include <lprocfs_status.h>#include <lustre/lustre_build_version.h>#include <libcfs/list.h>#include "llog_internal.h"#ifndef __KERNEL__/* liblustre workaround */atomic_t libcfs_kmemory = {0};#endifstruct obd_device *obd_devs[MAX_OBD_DEVICES];struct list_head obd_types;spinlock_t obd_dev_lock = SPIN_LOCK_UNLOCKED;/* The following are visible and mutable through /proc/sys/lustre/. */unsigned int obd_debug_peer_on_timeout;unsigned int obd_dump_on_timeout;unsigned int obd_dump_on_eviction;unsigned int obd_timeout = OBD_TIMEOUT_DEFAULT; /* seconds */unsigned int ldlm_timeout = LDLM_TIMEOUT_DEFAULT; /* seconds */unsigned int obd_max_dirty_pages = 256;atomic_t obd_dirty_pages;cfs_waitq_t obd_race_waitq;int obd_race_state;#ifdef __KERNEL__unsigned int obd_print_fail_loc(void){ CWARN("obd_fail_loc = %x\n", obd_fail_loc); return obd_fail_loc;}void obd_set_fail_loc(unsigned int fl){ obd_fail_loc = fl;}/* opening /dev/obd */static int obd_class_open(unsigned long flags, void *args){ ENTRY; PORTAL_MODULE_USE; RETURN(0);}/* closing /dev/obd */static int obd_class_release(unsigned long flags, void *args){ ENTRY; PORTAL_MODULE_UNUSE; RETURN(0);}#endifstatic inline void obd_data2conn(struct lustre_handle *conn, struct obd_ioctl_data *data){ memset(conn, 0, sizeof *conn); conn->cookie = data->ioc_cookie;}static inline void obd_conn2data(struct obd_ioctl_data *data, struct lustre_handle *conn){ data->ioc_cookie = conn->cookie;}int class_resolve_dev_name(__u32 len, const char *name){ int rc; int dev; ENTRY; if (!len || !name) { CERROR("No name passed,!\n"); GOTO(out, rc = -EINVAL); } if (name[len - 1] != 0) { CERROR("Name not nul terminated!\n"); GOTO(out, rc = -EINVAL); } CDEBUG(D_IOCTL, "device name %s\n", name); dev = class_name2dev(name); if (dev == -1) { CDEBUG(D_IOCTL, "No device for name %s!\n", name); GOTO(out, rc = -EINVAL); } CDEBUG(D_IOCTL, "device name %s, dev %d\n", name, dev); rc = dev;out: RETURN(rc);}int class_handle_ioctl(unsigned int cmd, unsigned long arg){ char *buf = NULL; struct obd_ioctl_data *data; struct libcfs_debug_ioctl_data *debug_data; struct obd_device *obd = NULL; int err = 0, len = 0; ENTRY; /* only for debugging */ if (cmd == LIBCFS_IOC_DEBUG_MASK) { debug_data = (struct libcfs_debug_ioctl_data*)arg; libcfs_subsystem_debug = debug_data->subs; libcfs_debug = debug_data->debug; return 0; } CDEBUG(D_IOCTL, "cmd = %x\n", cmd); if (obd_ioctl_getdata(&buf, &len, (void *)arg)) { CERROR("OBD ioctl: data error\n"); GOTO(out, err = -EINVAL); } data = (struct obd_ioctl_data *)buf; switch (cmd) { case OBD_IOC_PROCESS_CFG: { struct lustre_cfg *lcfg; if (!data->ioc_plen1 || !data->ioc_pbuf1) { CERROR("No config buffer passed!\n"); GOTO(out, err = -EINVAL); } OBD_ALLOC(lcfg, data->ioc_plen1); if (lcfg == NULL) GOTO(out, err = -ENOMEM); err = copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1); if (!err) err = lustre_cfg_sanity_check(lcfg, data->ioc_plen1); if (!err) err = class_process_config(lcfg); OBD_FREE(lcfg, data->ioc_plen1); GOTO(out, err); } case OBD_GET_VERSION: if (!data->ioc_inlbuf1) { CERROR("No buffer passed in ioctl\n"); GOTO(out, err = -EINVAL); } if (strlen(BUILD_VERSION) + 1 > data->ioc_inllen1) { CERROR("ioctl buffer too small to hold version\n"); GOTO(out, err = -EINVAL); } memcpy(data->ioc_bulk, BUILD_VERSION, strlen(BUILD_VERSION) + 1); err = obd_ioctl_popdata((void *)arg, data, len); if (err) err = -EFAULT; GOTO(out, err); case OBD_IOC_NAME2DEV: { /* Resolve a device name. This does not change the * currently selected device. */ int dev; dev = class_resolve_dev_name(data->ioc_inllen1, data->ioc_inlbuf1); data->ioc_dev = dev; if (dev < 0) GOTO(out, err = -EINVAL); err = obd_ioctl_popdata((void *)arg, data, sizeof(*data)); if (err) err = -EFAULT; GOTO(out, err); } case OBD_IOC_UUID2DEV: { /* Resolve a device uuid. This does not change the * currently selected device. */ int dev; struct obd_uuid uuid; if (!data->ioc_inllen1 || !data->ioc_inlbuf1) { CERROR("No UUID passed!\n"); GOTO(out, err = -EINVAL); } if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) { CERROR("UUID not NUL terminated!\n"); GOTO(out, err = -EINVAL); } CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1); obd_str2uuid(&uuid, data->ioc_inlbuf1); dev = class_uuid2dev(&uuid); data->ioc_dev = dev; if (dev == -1) { CDEBUG(D_IOCTL, "No device for UUID %s!\n", data->ioc_inlbuf1); GOTO(out, err = -EINVAL); } CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1, dev); err = obd_ioctl_popdata((void *)arg, data, sizeof(*data)); if (err) err = -EFAULT; GOTO(out, err); } case OBD_IOC_CLOSE_UUID: { CDEBUG(D_IOCTL, "closing all connections to uuid %s (NOOP)\n", data->ioc_inlbuf1); GOTO(out, err = 0); } case OBD_IOC_GETDEVICE: { int index = data->ioc_count; char *status, *str; if (!data->ioc_inlbuf1) { CERROR("No buffer passed in ioctl\n"); GOTO(out, err = -EINVAL); } if (data->ioc_inllen1 < 128) { CERROR("ioctl buffer too small to hold version\n"); GOTO(out, err = -EINVAL); } obd = class_num2obd(index); if (!obd) GOTO(out, err = -ENOENT); if (obd->obd_stopping) status = "ST"; else if (obd->obd_set_up) status = "UP"; else if (obd->obd_attached) status = "AT"; else status = "--"; str = (char *)data->ioc_bulk; snprintf(str, len - sizeof(*data), "%3d %s %s %s %s %d", (int)index, status, obd->obd_type->typ_name, obd->obd_name, obd->obd_uuid.uuid, atomic_read(&obd->obd_refcount)); err = obd_ioctl_popdata((void *)arg, data, len); GOTO(out, err = 0); } } if (data->ioc_dev >= class_devno_max()) { CERROR("OBD ioctl: No device\n"); GOTO(out, err = -EINVAL); } obd = class_num2obd(data->ioc_dev); if (obd == NULL) { CERROR("OBD ioctl : No Device %d\n", data->ioc_dev); GOTO(out, err = -EINVAL); } LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC); if (!obd->obd_set_up || obd->obd_stopping) { CERROR("OBD ioctl: device not setup %d \n", data->ioc_dev); GOTO(out, err = -EINVAL); } switch(cmd) { case OBD_IOC_NO_TRANSNO: { if (!obd->obd_attached) { CERROR("Device %d not attached\n", obd->obd_minor);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?