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