lock ordering. Update mdd code to use new locking interface.
b=16450
Description: simplify cmm_device freeing logic.
Details : Call cmm_device_free() in the failure path of cmm_device_alloc().
+Severity : normal
+Bugzilla : 16450
+Description: Add lockdep support to dt_object_operations locking interface.
+Details : Augment ->do_{read,write}_lock() prototypes with a `role' parameter
+ indicating lock ordering. Update mdd code to use new locking
+ interface.
+
--------------------------------------------------------------------------------
2007-08-10 Cluster File Systems, Inc. <info@clusterfs.com>
__u32 dah_mode;
};
-/*
+/**
* Per-dt-object operations.
*/
struct dt_object_operations {
void (*do_read_lock)(const struct lu_env *env,
- struct dt_object *dt);
+ struct dt_object *dt, unsigned role);
void (*do_write_lock)(const struct lu_env *env,
- struct dt_object *dt);
+ struct dt_object *dt, unsigned role);
void (*do_read_unlock)(const struct lu_env *env,
struct dt_object *dt);
void (*do_write_unlock)(const struct lu_env *env,
struct dt_object *dt);
- /*
+ /**
* Note: following ->do_{x,}attr_{set,get}() operations are very
* similar to ->moo_{x,}attr_{set,get}() operations in struct
* md_object_operations (see md_object.h). These operations are not in
struct dynlock_handle *dlh;
int rc;
- dlh = mdd_pdo_read_lock(env, mdd_obj, name);
+ dlh = mdd_pdo_read_lock(env, mdd_obj, name, MOR_TGT_PARENT);
if (unlikely(dlh == NULL))
return -ENOMEM;
rc = __mdd_lookup(env, pobj, lname, fid, mask);
{
struct dt_it *it;
struct dt_object *obj;
- struct dt_it_ops *iops;
+ const struct dt_it_ops *iops;
int result;
ENTRY;
if (check_perm)
rc = mdd_permission_internal_locked(env, pobj, NULL,
- MAY_WRITE | MAY_EXEC);
+ MAY_WRITE | MAY_EXEC,
+ MOR_TGT_PARENT);
if (!rc && check_nlink)
rc = __mdd_may_link(env, pobj);
RETURN(-EPERM);
rc = mdd_permission_internal_locked(env, pobj, NULL,
- MAY_WRITE | MAY_EXEC);
+ MAY_WRITE | MAY_EXEC,
+ MOR_TGT_PARENT);
if (rc)
RETURN(rc);
if (check_perm) {
rc = mdd_permission_internal_locked(env, pobj, NULL,
- MAY_WRITE | MAY_EXEC);
+ MAY_WRITE | MAY_EXEC,
+ MOR_TGT_PARENT);
if (rc)
RETURN(rc);
}
if (rc == 0) {
if (is_dir) {
- mdd_write_lock(env, pobj);
+ mdd_write_lock(env, pobj, MOR_TGT_PARENT);
__mdd_ref_add(env, pobj, handle);
mdd_write_unlock(env, pobj);
}
if (name != NULL && name[0] == '.' && name[1] == 0)
is_dot = 1;
- mdd_write_lock(env, pobj);
+ mdd_write_lock(env, pobj, MOR_TGT_PARENT);
__mdd_ref_del(env, pobj, handle, is_dot);
mdd_write_unlock(env, pobj);
}
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
- dlh = mdd_pdo_write_lock(env, mdd_tobj, name);
+ dlh = mdd_pdo_write_lock(env, mdd_tobj, name, MOR_TGT_CHILD);
if (dlh == NULL)
GOTO(out_trans, rc = -ENOMEM);
- mdd_write_lock(env, mdd_sobj);
+ mdd_write_lock(env, mdd_sobj, MOR_TGT_CHILD);
rc = mdd_link_sanity_check(env, mdd_tobj, lname, mdd_sobj);
if (rc)
RETURN(PTR_ERR(handle));
- dlh = mdd_pdo_write_lock(env, mdd_pobj, name);
+ dlh = mdd_pdo_write_lock(env, mdd_pobj, name, MOR_TGT_PARENT);
if (dlh == NULL)
GOTO(out_trans, rc = -ENOMEM);
- mdd_write_lock(env, mdd_cobj);
+ mdd_write_lock(env, mdd_cobj, MOR_TGT_CHILD);
is_dir = S_ISDIR(ma->ma_attr.la_mode);
rc = mdd_unlink_sanity_check(env, mdd_pobj, mdd_cobj, ma);
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
- dlh = mdd_pdo_write_lock(env, mdd_obj, name);
+ dlh = mdd_pdo_write_lock(env, mdd_obj, name, MOR_TGT_PARENT);
if (dlh == NULL)
GOTO(out_trans, rc = -ENOMEM);
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
- dlh = mdd_pdo_write_lock(env, mdd_obj, name);
+ dlh = mdd_pdo_write_lock(env, mdd_obj, name, MOR_TGT_PARENT);
if (dlh == NULL)
GOTO(out_trans, rc = -ENOMEM);
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
- dlh = mdd_pdo_write_lock(env, mdd_tpobj, name);
+ dlh = mdd_pdo_write_lock(env, mdd_tpobj, name, MOR_TGT_PARENT);
if (dlh == NULL)
GOTO(out_trans, rc = -ENOMEM);
if (tobj)
- mdd_write_lock(env, mdd_tobj);
+ mdd_write_lock(env, mdd_tobj, MOR_TGT_CHILD);
rc = mdd_rt_sanity_check(env, mdd_tpobj, mdd_tobj, ma);
if (rc)
if (unlikely(lname->ln_namelen > m->mdd_dt_conf.ddp_max_name_len))
RETURN(-ENAMETOOLONG);
- rc = mdd_permission_internal_locked(env, mdd_obj, NULL, mask);
+ rc = mdd_permission_internal_locked(env, mdd_obj, NULL, mask,
+ MOR_TGT_PARENT);
if (rc)
RETURN(rc);
* EXEC permission have been checked
* when lookup before create already.
*/
- rc = mdd_permission_internal_locked(env, obj, NULL, MAY_WRITE);
+ rc = mdd_permission_internal_locked(env, obj, NULL, MAY_WRITE,
+ MOR_TGT_PARENT);
if (rc)
RETURN(rc);
}
ma_acl->ma_need = MA_ACL_DEF;
ma_acl->ma_valid = 0;
- mdd_read_lock(env, mdd_pobj);
+ mdd_read_lock(env, mdd_pobj, MOR_TGT_PARENT);
rc = mdd_def_acl_get(env, mdd_pobj, ma_acl);
mdd_read_unlock(env, mdd_pobj);
if (rc)
if (IS_ERR(handle))
GOTO(out_free, rc = PTR_ERR(handle));
- dlh = mdd_pdo_write_lock(env, mdd_pobj, name);
+ dlh = mdd_pdo_write_lock(env, mdd_pobj, name, MOR_TGT_PARENT);
if (dlh == NULL)
GOTO(out_trans, rc = -ENOMEM);
- mdd_write_lock(env, son);
+ mdd_write_lock(env, son, MOR_TGT_CHILD);
rc = mdd_object_create_internal(env, mdd_pobj, son, ma, handle);
if (rc) {
mdd_write_unlock(env, son);
}
if (rc2 == 0) {
- mdd_write_lock(env, son);
+ mdd_write_lock(env, son, MOR_TGT_CHILD);
__mdd_ref_del(env, son, handle, 0);
if (initialized && S_ISDIR(attr->la_mode))
__mdd_ref_del(env, son, handle, 1);
/* Get locks in determined order */
if (rc == MDD_RN_SAME) {
- sdlh = mdd_pdo_write_lock(env, mdd_spobj, sname);
+ sdlh = mdd_pdo_write_lock(env, mdd_spobj,
+ sname, MOR_SRC_PARENT);
/* check hashes to determine do we need one lock or two */
if (mdd_name2hash(sname) != mdd_name2hash(tname))
- tdlh = mdd_pdo_write_lock(env, mdd_tpobj, tname);
+ tdlh = mdd_pdo_write_lock(env, mdd_tpobj, tname,
+ MOR_TGT_PARENT);
else
tdlh = sdlh;
} else if (rc == MDD_RN_SRCTGT) {
- sdlh = mdd_pdo_write_lock(env, mdd_spobj, sname);
- tdlh = mdd_pdo_write_lock(env, mdd_tpobj, tname);
+ sdlh = mdd_pdo_write_lock(env, mdd_spobj, sname,MOR_SRC_PARENT);
+ tdlh = mdd_pdo_write_lock(env, mdd_tpobj, tname,MOR_TGT_PARENT);
} else {
- tdlh = mdd_pdo_write_lock(env, mdd_tpobj, tname);
- sdlh = mdd_pdo_write_lock(env, mdd_spobj, sname);
+ tdlh = mdd_pdo_write_lock(env, mdd_tpobj, tname,MOR_SRC_PARENT);
+ sdlh = mdd_pdo_write_lock(env, mdd_spobj, sname,MOR_TGT_PARENT);
}
if (sdlh == NULL || tdlh == NULL)
GOTO(cleanup, rc = -ENOMEM);
* it must be local one.
*/
if (tobj && mdd_object_exists(mdd_tobj)) {
- mdd_write_lock(env, mdd_tobj);
+ mdd_write_lock(env, mdd_tobj, MOR_TGT_CHILD);
__mdd_ref_del(env, mdd_tobj, handle, 0);
/* Remove dot reference. */
#define LUSTRE_IMMUTABLE_FL LDISKFS_IMMUTABLE_FL
#define LUSTRE_DIRSYNC_FL LDISKFS_DIRSYNC_FL
+enum mdd_object_role {
+ MOR_SRC_PARENT,
+ MOR_SRC_CHILD,
+ MOR_TGT_PARENT,
+ MOR_TGT_CHILD
+};
+
struct mdd_object {
struct md_object mod_obj;
/* open count */
__u32 mod_valid;
unsigned long mod_flags;
struct dynlock mod_pdlock;
+#ifdef CONFIG_LOCKDEP
+ struct lockdep_map mod_dep_map_pdlock;
+#endif
};
struct orph_key {
int mdd_lmm_get_locked(const struct lu_env *env, struct mdd_object *mdd_obj,
struct md_attr *ma);
/* mdd_lock.c */
-void mdd_write_lock(const struct lu_env *env, struct mdd_object *obj);
-void mdd_read_lock(const struct lu_env *env, struct mdd_object *obj);
+void mdd_write_lock(const struct lu_env *env, struct mdd_object *obj,
+ enum mdd_object_role role);
+void mdd_read_lock(const struct lu_env *env, struct mdd_object *obj,
+ enum mdd_object_role role);
void mdd_write_unlock(const struct lu_env *env, struct mdd_object *obj);
void mdd_read_unlock(const struct lu_env *env, struct mdd_object *obj);
unsigned long mdd_name2hash(const char *name);
struct dynlock_handle *mdd_pdo_write_lock(const struct lu_env *env,
struct mdd_object *obj,
- const char *name);
+ const char *name,
+ enum mdd_object_role role);
struct dynlock_handle *mdd_pdo_read_lock(const struct lu_env *env,
struct mdd_object *obj,
- const char *name);
+ const char *name,
+ enum mdd_object_role role);
void mdd_pdo_write_unlock(const struct lu_env *env, struct mdd_object *obj,
struct dynlock_handle *dlh);
void mdd_pdo_read_unlock(const struct lu_env *env, struct mdd_object *obj,
int __mdd_acl_init(const struct lu_env *env, struct mdd_object *obj,
struct lu_buf *buf, __u32 *mode, struct thandle *handle);
int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj,
- struct lu_attr *la, int mask, int needlock);
+ struct lu_attr *la, int mask, int role);
int mdd_permission(const struct lu_env *env,
struct md_object *pobj, struct md_object *cobj,
struct md_attr *ma, int mask);
struct mdd_object *obj,
struct lu_attr *la, int mask)
{
- return __mdd_permission_internal(env, obj, la, mask, 0);
+ return __mdd_permission_internal(env, obj, la, mask, -1);
}
static inline int mdd_permission_internal_locked(const struct lu_env *env,
struct mdd_object *obj,
- struct lu_attr *la, int mask)
+ struct lu_attr *la, int mask,
+ enum mdd_object_role role)
{
- return __mdd_permission_internal(env, obj, la, mask, 1);
+ return __mdd_permission_internal(env, obj, la, mask, role);
}
/* mdd inline func for calling osd_dt_object ops */
#include <lustre_ver.h>
#include "mdd_internal.h"
-void mdd_write_lock(const struct lu_env *env, struct mdd_object *obj)
+
+#ifdef CONFIG_LOCKDEP
+static struct lock_class_key mdd_pdirop_key;
+
+#define RETIP ((unsigned long)__builtin_return_address(0))
+
+static void mdd_lockdep_init(struct mdd_object *obj)
+{
+ lockdep_init_map(&obj->mod_dep_map_pdlock, "pdir", &mdd_pdirop_key);
+}
+
+static void mdd_lockdep_pd_acquire(struct mdd_object *obj,
+ enum mdd_object_role role)
+{
+ lock_acquire(&obj->mod_dep_map_pdlock, role, 0, 1, 2, RETIP);
+}
+
+static void mdd_lockdep_pd_release(struct mdd_object *obj)
+{
+ lock_release(&obj->mod_dep_map_pdlock, 0, RETIP);
+}
+
+#else /* !CONFIG_LOCKDEP */
+
+static void mdd_lockdep_init(struct mdd_object *obj)
+{}
+static void mdd_lockdep_pd_acquire(struct mdd_object *obj,
+ enum mdd_object_role role)
+{}
+static void mdd_lockdep_pd_release(struct mdd_object *obj)
+{}
+
+#endif /* !CONFIG_LOCKDEP */
+
+void mdd_write_lock(const struct lu_env *env, struct mdd_object *obj,
+ enum mdd_object_role role)
{
struct dt_object *next = mdd_object_child(obj);
- next->do_ops->do_write_lock(env, next);
+ next->do_ops->do_write_lock(env, next, role);
}
-void mdd_read_lock(const struct lu_env *env, struct mdd_object *obj)
+void mdd_read_lock(const struct lu_env *env, struct mdd_object *obj,
+ enum mdd_object_role role)
{
struct dt_object *next = mdd_object_child(obj);
- next->do_ops->do_read_lock(env, next);
+
+ next->do_ops->do_read_lock(env, next, role);
}
void mdd_write_unlock(const struct lu_env *env, struct mdd_object *obj)
void mdd_pdlock_init(struct mdd_object *obj)
{
dynlock_init(&obj->mod_pdlock);
-
+ mdd_lockdep_init(obj);
}
unsigned long mdd_name2hash(const char *name)
struct dynlock_handle *mdd_pdo_write_lock(const struct lu_env *env,
struct mdd_object *obj,
- const char *name)
+ const char *name,
+ enum mdd_object_role role)
{
+ struct dynlock_handle *handle;
unsigned long value = mdd_name2hash(name);
- return dynlock_lock(&obj->mod_pdlock, value, DLT_WRITE, GFP_NOFS);
+
+ handle = dynlock_lock(&obj->mod_pdlock, value, DLT_WRITE, GFP_NOFS);
+ if (handle != NULL)
+ mdd_lockdep_pd_acquire(obj, role);
+ return handle;
}
struct dynlock_handle *mdd_pdo_read_lock(const struct lu_env *env,
struct mdd_object *obj,
- const char *name)
+ const char *name,
+ enum mdd_object_role role)
{
+ struct dynlock_handle *handle;
unsigned long value = mdd_name2hash(name);
- return dynlock_lock(&obj->mod_pdlock, value, DLT_READ, GFP_NOFS);
+ handle = dynlock_lock(&obj->mod_pdlock, value, DLT_READ, GFP_NOFS);
+ if (handle != NULL)
+ mdd_lockdep_pd_acquire(obj, role);
+ return handle;
}
void mdd_pdo_write_unlock(const struct lu_env *env, struct mdd_object *obj,
struct dynlock_handle *dlh)
{
+ mdd_lockdep_pd_release(obj);
return dynlock_unlock(&obj->mod_pdlock, dlh);
}
void mdd_pdo_read_unlock(const struct lu_env *env, struct mdd_object *obj,
struct dynlock_handle *dlh)
{
+ mdd_lockdep_pd_release(obj);
return dynlock_unlock(&obj->mod_pdlock, dlh);
}
void *md, int *md_size, const char *name)
{
int rc = 0;
- mdd_read_lock(env, obj);
+ mdd_read_lock(env, obj, MOR_TGT_CHILD);
rc = mdd_get_md(env, obj, md, md_size, name);
mdd_read_unlock(env, obj);
return rc;
if ((uc->mu_fsuid != tmp_la->la_uid) &&
!mdd_capable(uc, CFS_CAP_FOWNER))
rc = mdd_permission_internal_locked(env, obj, tmp_la,
- MAY_WRITE);
+ MAY_WRITE, MOR_TGT_CHILD);
RETURN(rc);
}
int rc = 0;
ENTRY;
- mdd_read_lock(env, obj);
+ mdd_read_lock(env, obj, MOR_TGT_CHILD);
rc = mdo_attr_get(env, obj, tmp_la, mdd_object_capa(env, obj));
mdd_read_unlock(env, obj);
if (rc)
if (IS_ERR(handle))
CERROR("Cannot get thandle\n");
else {
- mdd_write_lock(env, mdd_obj);
+ mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
/* let's remove obj from the orphan list */
__mdd_orphan_del(env, mdd_obj, handle);
mdd_write_unlock(env, mdd_obj);
int rc;
ENTRY;
- mdd_read_lock(env, mdd_obj);
+ mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = __mdd_lmm_get(env, mdd_obj, ma);
mdd_read_unlock(env, mdd_obj);
RETURN(rc);
int needlock = ma->ma_need & (MA_LOV | MA_LMV | MA_ACL_DEF);
if (needlock)
- mdd_read_lock(env, mdd_obj);
+ mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdd_attr_get_internal(env, mdd_obj, ma);
if (needlock)
mdd_read_unlock(env, mdd_obj);
LASSERT(mdd_object_exists(mdd_obj));
- mdd_read_lock(env, mdd_obj);
+ mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdo_xattr_get(env, mdd_obj, buf, name,
mdd_object_capa(env, mdd_obj));
mdd_read_unlock(env, mdd_obj);
LASSERT(mdd_object_exists(mdd_obj));
next = mdd_object_child(mdd_obj);
- mdd_read_lock(env, mdd_obj);
+ mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = next->do_body_ops->dbo_read(env, next, buf, &pos,
mdd_object_capa(env, mdd_obj));
mdd_read_unlock(env, mdd_obj);
ENTRY;
- mdd_read_lock(env, mdd_obj);
+ mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdo_xattr_list(env, mdd_obj, buf, mdd_object_capa(env, mdd_obj));
mdd_read_unlock(env, mdd_obj);
needacl = needacl && (attr->la_valid & LA_MODE);
if (needacl)
- mdd_write_lock(env, obj);
+ mdd_write_lock(env, obj, MOR_TGT_CHILD);
rc = mdd_attr_set_internal(env, obj, attr, handle, needacl);
if (needacl)
mdd_write_unlock(env, obj);
needacl = needacl && (attr->la_valid & LA_MODE);
if (needacl)
- mdd_write_lock(env, obj);
+ mdd_write_lock(env, obj, MOR_TGT_CHILD);
rc = mdd_attr_check_set_internal(env, obj, attr, handle, needacl);
if (needacl)
mdd_write_unlock(env, obj);
if ((uc->mu_fsuid != tmp_la->la_uid) &&
!mdd_capable(uc, CFS_CAP_FOWNER)) {
rc = mdd_permission_internal_locked(env, obj, tmp_la,
- MAY_WRITE);
+ MAY_WRITE,
+ MOR_TGT_CHILD);
if (rc)
RETURN(rc);
}
(uc->mu_fsuid == tmp_la->la_uid)) &&
!(ma->ma_attr_flags & MDS_PERM_BYPASS)) {
rc = mdd_permission_internal_locked(env, obj,
- tmp_la, MAY_WRITE);
+ tmp_la, MAY_WRITE,
+ MOR_TGT_CHILD);
if (rc)
RETURN(rc);
}
int rc;
ENTRY;
- mdd_write_lock(env, obj);
+ mdd_write_lock(env, obj, MOR_TGT_CHILD);
rc = __mdd_xattr_set(env, obj, buf, name, fl, handle);
mdd_write_unlock(env, obj);
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
- mdd_write_lock(env, mdd_obj);
+ mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdo_xattr_del(env, mdd_obj, name, handle,
mdd_object_capa(env, mdd_obj));
mdd_write_unlock(env, mdd_obj);
if (IS_ERR(handle))
RETURN(-ENOMEM);
- mdd_write_lock(env, mdd_obj);
+ mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdd_unlink_sanity_check(env, NULL, mdd_obj, ma);
if (rc)
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
- mdd_write_lock(env, mdd_obj);
+ mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdd_oc_sanity_check(env, mdd_obj, ma);
if (rc)
GOTO(unlock, rc);
}
EXIT;
unlock:
- mdd_write_unlock(env, mdd_obj);
if (rc == 0)
- rc = mdd_attr_get_internal_locked(env, mdd_obj, ma);
+ rc = mdd_attr_get_internal(env, mdd_obj, ma);
+ mdd_write_unlock(env, mdd_obj);
mdd_trans_stop(env, mdd, rc, handle);
return rc;
if (IS_ERR(handle))
RETURN(-ENOMEM);
- mdd_write_lock(env, mdd_obj);
+ mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdd_link_sanity_check(env, NULL, NULL, mdd_obj);
if (rc == 0)
__mdd_ref_add(env, mdd_obj, handle);
struct mdd_object *mdd_obj = md2mdd_obj(obj);
int rc = 0;
- mdd_write_lock(env, mdd_obj);
+ mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdd_open_sanity_check(env, mdd_obj, flags);
if (rc == 0)
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
- mdd_write_lock(env, mdd_obj);
+ mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
/* release open count */
mdd_obj->mod_count --;
LASSERT(mdd_object_exists(mdd_obj));
- mdd_read_lock(env, mdd_obj);
+ mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = mdd_readpage_sanity_check(env, mdd_obj);
if (rc)
GOTO(out_unlock, rc);
if (IS_ERR(mdo))
CERROR("Invalid orphan!\n");
else {
- mdd_write_lock(env, mdo);
+ mdd_write_lock(env, mdo, MOR_TGT_CHILD);
if (mdo->mod_count == 0) {
/* non-opened orphan, let's delete it */
struct md_attr *ma = &mdd_env_info(env)->mti_ma;
}
int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj,
- struct lu_attr *la, int mask, int needlock)
+ struct lu_attr *la, int mask, int role)
{
struct md_ucred *uc = md_ucred(env);
__u32 mode;
mode >>= 6;
} else {
if (mode & S_IRWXG) {
- if (needlock)
- mdd_read_lock(env, obj);
+ if (role != -1)
+ mdd_read_lock(env, obj, role);
rc = mdd_check_acl(env, obj, la, mask);
- if (needlock)
+ if (role != -1)
mdd_read_unlock(env, obj);
if (rc == -EACCES)
goto check_capabilities;
MAY_VTX_PART | MAY_VTX_FULL |
MAY_RGETFACL);
- rc = mdd_permission_internal_locked(env, mdd_cobj, NULL, mask);
+ rc = mdd_permission_internal_locked(env, mdd_cobj, NULL, mask,
+ MOR_TGT_CHILD);
if (!rc && (check_create || check_link))
rc = mdd_may_create(env, mdd_cobj, NULL, 1, check_link);
struct inode *oo_inode;
struct rw_semaphore oo_sem;
struct osd_directory *oo_dir;
- /* protects inode attributes. */
+ /** protects inode attributes. */
spinlock_t oo_guard;
-#if OSD_COUNTERS
const struct lu_env *oo_owner;
+#ifdef CONFIG_LOCKDEP
+ struct lockdep_map oo_dep_map;
#endif
};
};
static void osd_object_read_lock(const struct lu_env *env,
- struct dt_object *dt)
+ struct dt_object *dt, unsigned role)
{
struct osd_object *obj = osd_dt_obj(dt);
+ struct osd_thread_info *oti = osd_oti_get(env);
- LASSERT(osd_invariant(obj));
+ LINVRNT(osd_invariant(obj));
- OSD_COUNTERS_DO(LASSERT(obj->oo_owner != env));
- down_read(&obj->oo_sem);
-#if OSD_COUNTERS
- {
- struct osd_thread_info *oti = osd_oti_get(env);
+ LASSERT(obj->oo_owner != env);
+ down_read_nested(&obj->oo_sem, role);
LASSERT(obj->oo_owner == NULL);
oti->oti_r_locks++;
- }
-#endif
}
static void osd_object_write_lock(const struct lu_env *env,
- struct dt_object *dt)
+ struct dt_object *dt, unsigned role)
{
struct osd_object *obj = osd_dt_obj(dt);
+ struct osd_thread_info *oti = osd_oti_get(env);
- LASSERT(osd_invariant(obj));
+ LINVRNT(osd_invariant(obj));
- OSD_COUNTERS_DO(LASSERT(obj->oo_owner != env));
- down_write(&obj->oo_sem);
-#if OSD_COUNTERS
- {
- struct osd_thread_info *oti = osd_oti_get(env);
+ LASSERT(obj->oo_owner != env);
+ down_write_nested(&obj->oo_sem, role);
LASSERT(obj->oo_owner == NULL);
obj->oo_owner = env;
oti->oti_w_locks++;
- }
-#endif
}
static void osd_object_read_unlock(const struct lu_env *env,
struct dt_object *dt)
{
struct osd_object *obj = osd_dt_obj(dt);
-
- LASSERT(osd_invariant(obj));
-#if OSD_COUNTERS
- {
struct osd_thread_info *oti = osd_oti_get(env);
+ LINVRNT(osd_invariant(obj));
+
LASSERT(oti->oti_r_locks > 0);
oti->oti_r_locks--;
- }
-#endif
up_read(&obj->oo_sem);
}