ldlm_resource.c

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

C
1,062
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2002, 2003 Cluster File Systems, Inc. *   Author: Phil Schwan <phil@clusterfs.com> *   Author: Peter Braam <braam@clusterfs.com> * *   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. */#define DEBUG_SUBSYSTEM S_LDLM#ifdef __KERNEL__# include <lustre_dlm.h>#else# include <liblustre.h>#endif#include <obd_class.h>#include "ldlm_internal.h"cfs_mem_cache_t *ldlm_resource_slab, *ldlm_lock_slab;atomic_t ldlm_srv_namespace_nr = ATOMIC_INIT(0);atomic_t ldlm_cli_namespace_nr = ATOMIC_INIT(0);struct semaphore ldlm_srv_namespace_lock;struct list_head ldlm_srv_namespace_list =         CFS_LIST_HEAD_INIT(ldlm_srv_namespace_list);struct semaphore ldlm_cli_namespace_lock;struct list_head ldlm_cli_namespace_list =         CFS_LIST_HEAD_INIT(ldlm_cli_namespace_list);cfs_proc_dir_entry_t *ldlm_type_proc_dir = NULL;cfs_proc_dir_entry_t *ldlm_ns_proc_dir = NULL;cfs_proc_dir_entry_t *ldlm_svc_proc_dir = NULL;#ifdef LPROCFSstatic int ldlm_proc_dump_ns(struct file *file, const char *buffer,                             unsigned long count, void *data){        ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE);        ldlm_dump_all_namespaces(LDLM_NAMESPACE_CLIENT, D_DLMTRACE);        RETURN(count);}int ldlm_proc_setup(void){        int rc;        struct lprocfs_vars list[] = {                { "dump_namespaces", NULL, ldlm_proc_dump_ns, NULL },                { NULL }};        ENTRY;        LASSERT(ldlm_ns_proc_dir == NULL);        ldlm_type_proc_dir = lprocfs_register(OBD_LDLM_DEVICENAME,                                              proc_lustre_root,                                              NULL, NULL);        if (IS_ERR(ldlm_type_proc_dir)) {                CERROR("LProcFS failed in ldlm-init\n");                rc = PTR_ERR(ldlm_type_proc_dir);                GOTO(err, rc);        }        ldlm_ns_proc_dir = lprocfs_register("namespaces",                                            ldlm_type_proc_dir,                                            NULL, NULL);        if (IS_ERR(ldlm_ns_proc_dir)) {                CERROR("LProcFS failed in ldlm-init\n");                rc = PTR_ERR(ldlm_ns_proc_dir);                GOTO(err_type, rc);        }        ldlm_svc_proc_dir = lprocfs_register("services",                                            ldlm_type_proc_dir,                                            NULL, NULL);        if (IS_ERR(ldlm_svc_proc_dir)) {                CERROR("LProcFS failed in ldlm-init\n");                rc = PTR_ERR(ldlm_svc_proc_dir);                GOTO(err_ns, rc);        }        rc = lprocfs_add_vars(ldlm_type_proc_dir, list, NULL);        RETURN(0);err_ns:        lprocfs_remove(&ldlm_ns_proc_dir);err_type:        lprocfs_remove(&ldlm_type_proc_dir);err:        ldlm_svc_proc_dir = NULL;        RETURN(rc);}void ldlm_proc_cleanup(void){        if (ldlm_svc_proc_dir)                 lprocfs_remove(&ldlm_svc_proc_dir);        if (ldlm_ns_proc_dir)                 lprocfs_remove(&ldlm_ns_proc_dir);        if (ldlm_type_proc_dir)                lprocfs_remove(&ldlm_type_proc_dir);}static int lprocfs_rd_lru_size(char *page, char **start, off_t off,                               int count, int *eof, void *data){        struct ldlm_namespace *ns = data;        __u32 *nr = &ns->ns_max_unused;        if (ns_connect_lru_resize(ns))                nr = &ns->ns_nr_unused;        return lprocfs_rd_uint(page, start, off, count, eof, nr);}static int lprocfs_wr_lru_size(struct file *file, const char *buffer,                               unsigned long count, void *data){        struct ldlm_namespace *ns = data;        char dummy[MAX_STRING_SIZE + 1], *end;        unsigned long tmp;        int lru_resize;        dummy[MAX_STRING_SIZE] = '\0';        if (copy_from_user(dummy, buffer, MAX_STRING_SIZE))                return -EFAULT;        if (count == 6 && memcmp(dummy, "clear", 5) == 0) {                CDEBUG(D_DLMTRACE,                       "dropping all unused locks from namespace %s\n",                       ns->ns_name);                if (ns_connect_lru_resize(ns)) {                        int canceled, unused  = ns->ns_nr_unused;                                                /* Try to cancel all @ns_nr_unused locks. */                        canceled = ldlm_cancel_lru(ns, unused, LDLM_SYNC,                                                    LDLM_CANCEL_PASSED);                        if (canceled < unused) {                                CERROR("not all requested locks are canceled, "                                       "requested: %d, canceled: %d\n", unused,                                        canceled);                                return -EINVAL;                        }                } else {                        tmp = ns->ns_max_unused;                        ns->ns_max_unused = 0;                        ldlm_cancel_lru(ns, 0, LDLM_SYNC, LDLM_CANCEL_PASSED);                        ns->ns_max_unused = tmp;                }                return count;        }        tmp = simple_strtoul(dummy, &end, 0);        if (dummy == end) {                CERROR("invalid value written\n");                return -EINVAL;        }        lru_resize = (tmp == 0);                if (ns_connect_lru_resize(ns)) {                if (!lru_resize)                        ns->ns_max_unused = (unsigned int)tmp;                                        if (tmp > ns->ns_nr_unused)                        tmp = ns->ns_nr_unused;                tmp = ns->ns_nr_unused - tmp;                                CDEBUG(D_DLMTRACE, "changing namespace %s unused locks from %u to %u\n",                        ns->ns_name, ns->ns_nr_unused, (unsigned int)tmp);                ldlm_cancel_lru(ns, (unsigned int)tmp, LDLM_ASYNC, LDLM_CANCEL_PASSED);                                if (!lru_resize) {                        CDEBUG(D_DLMTRACE, "disable lru_resize for namespace %s\n",                                ns->ns_name);                        ns->ns_connect_flags &= ~OBD_CONNECT_LRU_RESIZE;                }        } else {                CDEBUG(D_DLMTRACE, "changing namespace %s max_unused from %u to %u\n",                       ns->ns_name, ns->ns_max_unused, (unsigned int)tmp);                ns->ns_max_unused = (unsigned int)tmp;                ldlm_cancel_lru(ns, 0, LDLM_ASYNC, LDLM_CANCEL_PASSED);                                /* Make sure that originally lru resize was supported before                  * turning it on here. */                if (lru_resize &&                     (ns->ns_orig_connect_flags & OBD_CONNECT_LRU_RESIZE)) {                        CDEBUG(D_DLMTRACE, "enable lru_resize for namespace %s\n",                                ns->ns_name);                        ns->ns_connect_flags |= OBD_CONNECT_LRU_RESIZE;                }        }        return count;}void ldlm_proc_namespace(struct ldlm_namespace *ns){        struct lprocfs_vars lock_vars[2];        char lock_name[MAX_STRING_SIZE + 1];        LASSERT(ns != NULL);        LASSERT(ns->ns_name != NULL);        lock_name[MAX_STRING_SIZE] = '\0';        memset(lock_vars, 0, sizeof(lock_vars));        lock_vars[0].name = lock_name;        snprintf(lock_name, MAX_STRING_SIZE, "%s/resource_count", ns->ns_name);        lock_vars[0].data = &ns->ns_refcount;        lock_vars[0].read_fptr = lprocfs_rd_atomic;        lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);        snprintf(lock_name, MAX_STRING_SIZE, "%s/lock_count", ns->ns_name);        lock_vars[0].data = &ns->ns_locks;        lock_vars[0].read_fptr = lprocfs_rd_atomic;        lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);        if (ns_is_client(ns)) {                snprintf(lock_name, MAX_STRING_SIZE, "%s/lock_unused_count",                         ns->ns_name);                lock_vars[0].data = &ns->ns_nr_unused;                lock_vars[0].read_fptr = lprocfs_rd_uint;                lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);                snprintf(lock_name, MAX_STRING_SIZE, "%s/lru_size",                         ns->ns_name);                lock_vars[0].data = ns;                lock_vars[0].read_fptr = lprocfs_rd_lru_size;                lock_vars[0].write_fptr = lprocfs_wr_lru_size;                lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);                                snprintf(lock_name, MAX_STRING_SIZE, "%s/shrink_thumb",                         ns->ns_name);                lock_vars[0].data = ns;                lock_vars[0].read_fptr = lprocfs_rd_uint;                lock_vars[0].write_fptr = lprocfs_wr_uint;                lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);                                snprintf(lock_name, MAX_STRING_SIZE, "%s/lru_max_age",                         ns->ns_name);                lock_vars[0].data = &ns->ns_max_age;                lock_vars[0].read_fptr = lprocfs_rd_uint;                lock_vars[0].write_fptr = lprocfs_wr_uint;                lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);        } else {                snprintf(lock_name, MAX_STRING_SIZE, "%s/max_nolock_bytes",                         ns->ns_name);                lock_vars[0].data = &ns->ns_max_nolock_size;                lock_vars[0].read_fptr = lprocfs_rd_uint;                lock_vars[0].write_fptr = lprocfs_wr_uint;                lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);                snprintf(lock_name, MAX_STRING_SIZE, "%s/contention_seconds",                         ns->ns_name);                lock_vars[0].data = &ns->ns_contention_time;                lock_vars[0].read_fptr = lprocfs_rd_uint;                lock_vars[0].write_fptr = lprocfs_wr_uint;                lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);                snprintf(lock_name, MAX_STRING_SIZE, "%s/contended_locks",                         ns->ns_name);                lock_vars[0].data = &ns->ns_contended_locks;                lock_vars[0].read_fptr = lprocfs_rd_uint;                lock_vars[0].write_fptr = lprocfs_wr_uint;                lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);        }}#undef MAX_STRING_SIZE#else#define ldlm_proc_namespace(ns) do {} while (0)#endif /* LPROCFS */struct ldlm_namespace *ldlm_namespace_new(char *name, ldlm_side_t client,                                           ldlm_appetite_t apt){        struct ldlm_namespace *ns = NULL;        struct list_head *bucket;        int rc, idx, namelen;        ENTRY;        rc = ldlm_get_ref();        if (rc) {                CERROR("ldlm_get_ref failed: %d\n", rc);                RETURN(NULL);        }        OBD_ALLOC_PTR(ns);        if (!ns)                GOTO(out_ref, NULL);        OBD_VMALLOC(ns->ns_hash, sizeof(*ns->ns_hash) * RES_HASH_SIZE);        if (!ns->ns_hash)                GOTO(out_ns, NULL);        namelen = strlen(name);        OBD_ALLOC(ns->ns_name, namelen + 1);        if (!ns->ns_name)                GOTO(out_hash, NULL);        ns->ns_shrink_thumb = LDLM_LOCK_SHRINK_THUMB;        ns->ns_appetite = apt;        strcpy(ns->ns_name, name);        CFS_INIT_LIST_HEAD(&ns->ns_root_list);        ns->ns_refcount = 0;        ns->ns_client = client;        spin_lock_init(&ns->ns_hash_lock);        atomic_set(&ns->ns_locks, 0);        ns->ns_resources = 0;        cfs_waitq_init(&ns->ns_waitq);        ns->ns_max_nolock_size = NS_DEFAULT_MAX_NOLOCK_BYTES;        ns->ns_contention_time = NS_DEFAULT_CONTENTION_SECONDS;        ns->ns_contended_locks = NS_DEFAULT_CONTENDED_LOCKS;        for (bucket = ns->ns_hash + RES_HASH_SIZE - 1; bucket >= ns->ns_hash;             bucket--)                CFS_INIT_LIST_HEAD(bucket);        CFS_INIT_LIST_HEAD(&ns->ns_unused_list);        ns->ns_nr_unused = 0;        ns->ns_max_unused = LDLM_DEFAULT_LRU_SIZE;        ns->ns_max_age = LDLM_DEFAULT_MAX_ALIVE;        spin_lock_init(&ns->ns_unused_lock);        ns->ns_orig_connect_flags = 0;        ns->ns_connect_flags = 0;        ldlm_proc_namespace(ns);        idx = atomic_read(ldlm_namespace_nr(client));                rc = ldlm_pool_init(&ns->ns_pool, ns, idx, client);        if (rc) {                CERROR("Can't initialize lock pool, rc %d\n", rc);                GOTO(out_proc, rc);        }

⌨️ 快捷键说明

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