/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program 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 GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2010, 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* lustre/ldlm/ldlm_lock.c
*
* Author: Peter Braam <braam@clusterfs.com>
* Author: Phil Schwan <phil@clusterfs.com>
*/
#define DEBUG_SUBSYSTEM S_LDLM
# include <linux/libcfs/libcfs.h>
# include <linux/lustre_intent.h>
#include <obd_class.h>
#include "ldlm_internal.h"
/* lock types */
char *ldlm_lockname[] = {
[0] = "--",
[LCK_EX] = "EX",
[LCK_PW] = "PW",
[LCK_PR] = "PR",
[LCK_CW] = "CW",
[LCK_CR] = "CR",
[LCK_NL] = "NL",
[LCK_GROUP] = "GROUP",
[LCK_COS] = "COS",
};
EXPORT_SYMBOL(ldlm_lockname);
char *ldlm_typename[] = {
[LDLM_PLAIN] = "PLN",
[LDLM_EXTENT] = "EXT",
[LDLM_FLOCK] = "FLK",
[LDLM_IBITS] = "IBT",
};
EXPORT_SYMBOL(ldlm_typename);
static ldlm_policy_wire_to_local_t ldlm_policy_wire18_to_local[] = {
[LDLM_PLAIN - LDLM_MIN_TYPE] = ldlm_plain_policy_wire_to_local,
[LDLM_EXTENT - LDLM_MIN_TYPE] = ldlm_extent_policy_wire_to_local,
[LDLM_FLOCK - LDLM_MIN_TYPE] = ldlm_flock_policy_wire18_to_local,
[LDLM_IBITS - LDLM_MIN_TYPE] = ldlm_ibits_policy_wire_to_local,
};
static ldlm_policy_wire_to_local_t ldlm_policy_wire21_to_local[] = {
[LDLM_PLAIN - LDLM_MIN_TYPE] = ldlm_plain_policy_wire_to_local,
[LDLM_EXTENT - LDLM_MIN_TYPE] = ldlm_extent_policy_wire_to_local,
[LDLM_FLOCK - LDLM_MIN_TYPE] = ldlm_flock_policy_wire21_to_local,
[LDLM_IBITS - LDLM_MIN_TYPE] = ldlm_ibits_policy_wire_to_local,
};
static ldlm_policy_local_to_wire_t ldlm_policy_local_to_wire[] = {
[LDLM_PLAIN - LDLM_MIN_TYPE] = ldlm_plain_policy_local_to_wire,
[LDLM_EXTENT - LDLM_MIN_TYPE] = ldlm_extent_policy_local_to_wire,
[LDLM_FLOCK - LDLM_MIN_TYPE] = ldlm_flock_policy_local_to_wire,
[LDLM_IBITS - LDLM_MIN_TYPE] = ldlm_ibits_policy_local_to_wire,
};
/**
* Converts lock policy from local format to on the wire lock_desc format
*/
void ldlm_convert_policy_to_wire(ldlm_type_t type,
const ldlm_policy_data_t *lpolicy,
ldlm_wire_policy_data_t *wpolicy)
{
ldlm_policy_local_to_wire_t convert;
convert = ldlm_policy_local_to_wire[type - LDLM_MIN_TYPE];
convert(lpolicy, wpolicy);
}
/**
* Converts lock policy from on the wire lock_desc format to local format
*/
void ldlm_convert_policy_to_local(struct obd_export *exp, ldlm_type_t type,
const ldlm_wire_policy_data_t *wpolicy,
ldlm_policy_data_t *lpolicy)
{
ldlm_policy_wire_to_local_t convert;
int new_client;
/** some badness for 2.0.0 clients, but 2.0.0 isn't supported */
new_client = (exp_connect_flags(exp) & OBD_CONNECT_FULL20) != 0;
if (new_client)
convert = ldlm_policy_wire21_to_local[type - LDLM_MIN_TYPE];
else
convert = ldlm_policy_wire18_to_local[type - LDLM_MIN_TYPE];
convert(wpolicy, lpolicy);
}
char *ldlm_it2str(int it)
{
switch (it) {
case IT_OPEN:
return "open";
case IT_CREAT:
return "creat";
case (IT_OPEN | IT_CREAT):
return "open|creat";
case IT_READDIR:
return "readdir";
case IT_GETATTR:
return "getattr";
case IT_LOOKUP:
return "lookup";
case IT_UNLINK:
return "unlink";
case IT_GETXATTR:
return "getxattr";
case IT_LAYOUT:
return "layout";
default:
CERROR("Unknown intent %d\n", it);
return "UNKNOWN";
}
}
EXPORT_SYMBOL(ldlm_it2str);
extern struct kmem_cache *ldlm_lock_slab;
void ldlm_register_intent(struct ldlm_namespace *ns, ldlm_res_policy arg)
{
ns->ns_policy = arg;
}
EXPORT_SYMBOL(ldlm_register_intent);
/*
* REFCOUNTED LOCK OBJECTS
*/
/**
* Get a reference on a lock.
*
* Lock refcounts, during creation:
* - one special one for allocation, dec'd only once in destroy
* - one for being a lock that's in-use
* - one for the addref associated with a new lock
*/
struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock)
{
atomic_inc(&lock->l_refc);
return lock;
}
EXPORT_SYMBOL(ldlm_lock_get);
/**
* Release lock reference.
*
* Also frees the lock if it was last reference.
*/
void ldlm_lock_put(struct ldlm_lock *lock)
{
LASSERT(lock->l_resource != LP_POISON);
LASSERT(atomic_read(&lock->l_refc) > 0);
if (atomic_dec_and_test(&lock->l_refc)) {
struct ldlm_resource *res;
LDLM_DEBUG(lock,
"final lock_put on destroyed lock, freeing it.");
res = lock->l_resource;
LASSERT(lock->l_flags & LDLM_FL_DESTROYED);
LASSERT(list_empty(&lock->l_res_link));
LASSERT(list_empty(&lock->l_pending_chain));
lprocfs_counter_decr(ldlm_res_to_ns(res)->ns_stats,
LDLM_NSS_LOCKS);
lu_ref_del(&res->lr_reference, "lock", lock);
ldlm_resource_putref(res);
lock->l_resource = NULL;
if (lock->l_export) {
class_export_lock_put(lock->l_export, lock);
lock->l_export = NULL;
}
if (lock->l_lvb_data != NULL)
OBD_FREE(lock->l_lvb_data, lock->l_lvb_len);
ldlm_interval_free(ldlm_interval_detach(lock));
lu_ref_fini(&lock->l_reference);
OBD_FREE_RCU(lock, sizeof(*lock), &lock->l_handle);
}
}
EXPORT_SYMBOL(ldlm_lock_put);
/**
* Removes LDLM lock \a lock from LRU. Assumes LRU is already locked.
*/
int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock)
{
int rc = 0;
if (!list_empty(&lock->l_lru)) {
struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
list_del_init(&lock->l_lru);
if (lock->l_flags & LDLM_FL_SKIPPED)
lock->l_flags &= ~LDLM_FL_SKIPPED;
LASSERT(ns->ns_nr_unused > 0);
ns->ns_nr_unused--;
rc = 1;
}
return rc;
}
/**
* Removes LDLM lock \a lock from LRU. Obtains the LRU lock first.
*/
int ldlm_lock_remove_from_lru(struct ldlm_lock *lock)
{
struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
int rc;
if (lock->l_flags & LDLM_FL_NS_SRV) {
LASSERT(list_empty(&lock->l_lru));
return 0;
}
spin_lock(&ns->ns_lock);
rc = ldlm_lock_remove_from_lru_nolock(lock);
spin_unlock(&ns->ns_lock);
return rc;
}
/**
* Adds LDLM lock \a lock to namespace LRU. Assumes LRU is already locked.
*/
void ldlm_lock_add_to_lru_nolock(struct ldlm_lock *lock)
{
struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
lock->l_last_used = cfs_time_current();
LASSERT(list_empty(&lock->l_lru));
LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
list_add_tail(&lock->l_lru, &ns->ns_unused_list);
LASSERT(ns->ns_nr_unused >= 0);
ns->ns_nr_unused++;
}
/**
* Adds LDLM lock \a lock to namespace LRU. Obtains necessary LRU locks
* first.
*/
void ldlm_lock_add_to_lru(struct ldlm_lock *lock)
{
struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
spin_lock(&ns->ns_lock);
ldlm_lock_add_to_lru_nolock(lock);
spin_unlock(&ns->ns_lock);
}
/**
* Moves LDLM lock \a lock that is already in namespace LRU to the tail of
* the LRU. Performs necessary LRU locking
*/
void ldlm_lock_touch_in_lru(struct ldlm_lock *lock)
{
struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
if (lock->l_flags & LDLM_FL_NS_SRV) {
LASSERT(list_empty(&lock->l_lru));
return;
}
spin_lo
ldlm_lock.rar_V2
版权申诉
39 浏览量
2022-09-20
21:45:45
上传
评论
收藏 16KB RAR 举报
我虽横行却不霸道
- 粉丝: 76
- 资源: 1万+
最新资源
- 海信智能电视刷机数据 LED42K330X3D(0000) 生产用软件数据 务必确认机编一致 强制刷机 整机USB升级程序
- shujudaochuceshi
- learn-ruby.zip
- test111111111111111111
- face-detect.ipynb
- 以下是一些关于ACM(国际大学生程序设计竞赛)、NOI(全国青少年信息学奥林匹克竞赛)以及CSP(全国青少年信息学奥林匹克竞赛提
- 是一些电子设计竞赛(电赛)经验分享,包括备赛策略、项目管理、团队合作和比赛期间的注意事项
- 全能运行库修复工具DirectX Repair v4.1.0.30770
- las格式点云数据使用详解(附VS编译好的LAStools工具)
- KRPano插件一键解密大师1.4.0 (解压密码1234)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈