Whamcloud - gitweb
Augment ->do_{read,write}_lock() prototypes with a `role' parameter indicating
authornikita <nikita>
Sat, 18 Oct 2008 15:25:48 +0000 (15:25 +0000)
committernikita <nikita>
Sat, 18 Oct 2008 15:25:48 +0000 (15:25 +0000)
lock ordering. Update mdd code to use new locking interface.
b=16450

lustre/ChangeLog
lustre/include/dt_object.h
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_lock.c
lustre/mdd/mdd_lov.c
lustre/mdd/mdd_object.c
lustre/mdd/mdd_orphans.c
lustre/mdd/mdd_permission.c
lustre/osd/osd_handler.c

index f3df71e..04c2402 100644 (file)
@@ -1464,6 +1464,13 @@ Bugzilla   : 16450
 Description: simplify cmm_device freeing logic.
 Details    : Call cmm_device_free() in the failure path of cmm_device_alloc().
 
 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>
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
index 981f461..f535c69 100644 (file)
@@ -182,19 +182,19 @@ struct dt_allocation_hint {
         __u32             dah_mode;
 };
 
         __u32             dah_mode;
 };
 
-/*
+/**
  * Per-dt-object operations.
  */
 struct dt_object_operations {
         void  (*do_read_lock)(const struct lu_env *env,
  * 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,
         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);
         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
          * 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
index 8692b23..4625205 100644 (file)
@@ -80,7 +80,7 @@ __mdd_lookup_locked(const struct lu_env *env, struct md_object *pobj,
         struct dynlock_handle *dlh;
         int rc;
 
         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);
         if (unlikely(dlh == NULL))
                 return -ENOMEM;
         rc = __mdd_lookup(env, pobj, lname, fid, mask);
@@ -223,7 +223,7 @@ static int mdd_dir_is_empty(const struct lu_env *env,
 {
         struct dt_it     *it;
         struct dt_object *obj;
 {
         struct dt_it     *it;
         struct dt_object *obj;
-        struct dt_it_ops *iops;
+        const struct dt_it_ops *iops;
         int result;
         ENTRY;
 
         int result;
         ENTRY;
 
@@ -295,7 +295,8 @@ int mdd_may_create(const struct lu_env *env, struct mdd_object *pobj,
 
         if (check_perm)
                 rc = mdd_permission_internal_locked(env, pobj, NULL,
 
         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);
 
         if (!rc && check_nlink)
                 rc = __mdd_may_link(env, pobj);
@@ -320,7 +321,8 @@ int mdd_may_unlink(const struct lu_env *env, struct mdd_object *pobj,
                 RETURN(-EPERM);
 
         rc = mdd_permission_internal_locked(env, pobj, NULL,
                 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 (rc)
                 RETURN(rc);
 
@@ -383,7 +385,8 @@ int mdd_may_delete(const struct lu_env *env, struct mdd_object *pobj,
 
                 if (check_perm) {
                         rc = mdd_permission_internal_locked(env, pobj, NULL,
 
                 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)
                                 RETURN(rc);
                 }
@@ -521,7 +524,7 @@ static int __mdd_index_insert(const struct lu_env *env, struct mdd_object *pobj,
 
         if (rc == 0) {
                 if (is_dir) {
 
         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);
                 }
                         __mdd_ref_add(env, pobj, handle);
                         mdd_write_unlock(env, pobj);
                 }
@@ -547,7 +550,7 @@ static int __mdd_index_delete(const struct lu_env *env, struct mdd_object *pobj,
 
                         if (name != NULL && name[0] == '.' && name[1] == 0)
                                 is_dot = 1;
 
                         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);
                 }
                         __mdd_ref_del(env, pobj, handle, is_dot);
                         mdd_write_unlock(env, pobj);
                 }
@@ -596,10 +599,10 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj,
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
         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);
         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)
 
         rc = mdd_link_sanity_check(env, mdd_tobj, lname, mdd_sobj);
         if (rc)
@@ -701,10 +704,10 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
                 RETURN(PTR_ERR(handle));
 
 
                 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);
         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);
 
         is_dir = S_ISDIR(ma->ma_attr.la_mode);
         rc = mdd_unlink_sanity_check(env, mdd_pobj, mdd_cobj, ma);
@@ -790,7 +793,7 @@ static int mdd_name_insert(const struct lu_env *env,
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
         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 (dlh == NULL)
                 GOTO(out_trans, rc = -ENOMEM);
 
@@ -863,7 +866,7 @@ static int mdd_name_remove(const struct lu_env *env,
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
         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 (dlh == NULL)
                 GOTO(out_trans, rc = -ENOMEM);
 
@@ -944,11 +947,11 @@ static int mdd_rename_tgt(const struct lu_env *env,
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
         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)
         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)
 
         rc = mdd_rt_sanity_check(env, mdd_tpobj, mdd_tobj, ma);
         if (rc)
@@ -1114,7 +1117,8 @@ __mdd_lookup(const struct lu_env *env, struct md_object *pobj,
         if (unlikely(lname->ln_namelen > m->mdd_dt_conf.ddp_max_name_len))
                 RETURN(-ENAMETOOLONG);
 
         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);
 
         if (rc)
                 RETURN(rc);
 
@@ -1214,7 +1218,8 @@ static int mdd_create_sanity_check(const struct lu_env *env,
                  * EXEC permission have been checked
                  * when lookup before create already.
                  */
                  * 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);
         }
                 if (rc)
                         RETURN(rc);
         }
@@ -1339,7 +1344,7 @@ static int mdd_create(const struct lu_env *env,
                 ma_acl->ma_need = MA_ACL_DEF;
                 ma_acl->ma_valid = 0;
 
                 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)
                 rc = mdd_def_acl_get(env, mdd_pobj, ma_acl);
                 mdd_read_unlock(env, mdd_pobj);
                 if (rc)
@@ -1353,11 +1358,11 @@ static int mdd_create(const struct lu_env *env,
         if (IS_ERR(handle))
                 GOTO(out_free, rc = PTR_ERR(handle));
 
         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);
 
         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);
         rc = mdd_object_create_internal(env, mdd_pobj, son, ma, handle);
         if (rc) {
                 mdd_write_unlock(env, son);
@@ -1456,7 +1461,7 @@ cleanup:
                 }
 
                 if (rc2 == 0) {
                 }
 
                 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);
                         __mdd_ref_del(env, son, handle, 0);
                         if (initialized && S_ISDIR(attr->la_mode))
                                 __mdd_ref_del(env, son, handle, 1);
@@ -1598,18 +1603,20 @@ static int mdd_rename(const struct lu_env *env,
 
         /* Get locks in determined order */
         if (rc == MDD_RN_SAME) {
 
         /* 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))
                 /* 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) {
                 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 {
         } 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);
         }
         if (sdlh == NULL || tdlh == NULL)
                 GOTO(cleanup, rc = -ENOMEM);
@@ -1657,7 +1664,7 @@ static int mdd_rename(const struct lu_env *env,
          * it must be local one.
          */
         if (tobj && mdd_object_exists(mdd_tobj)) {
          * 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. */
                 __mdd_ref_del(env, mdd_tobj, handle, 0);
 
                 /* Remove dot reference. */
index 5263556..896248a 100644 (file)
@@ -100,6 +100,13 @@ enum mod_flags {
 #define LUSTRE_IMMUTABLE_FL LDISKFS_IMMUTABLE_FL
 #define LUSTRE_DIRSYNC_FL LDISKFS_DIRSYNC_FL
 
 #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 */
 struct mdd_object {
         struct md_object  mod_obj;
         /* open count */
@@ -107,6 +114,9 @@ struct mdd_object {
         __u32             mod_valid;
         unsigned long     mod_flags;
         struct dynlock    mod_pdlock;
         __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 {
 };
 
 struct orph_key {
@@ -196,8 +206,10 @@ int mdd_attr_check_set_internal_locked(const struct lu_env *env,
 int mdd_lmm_get_locked(const struct lu_env *env, struct mdd_object *mdd_obj,
                        struct md_attr *ma);
 /* mdd_lock.c */
 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);
 
 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);
 
@@ -205,10 +217,12 @@ void mdd_pdlock_init(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,
 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,
 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,
 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,
@@ -340,7 +354,7 @@ int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode,
 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,
 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);
 int mdd_permission(const struct lu_env *env,
                    struct md_object *pobj, struct md_object *cobj,
                    struct md_attr *ma, int mask);
@@ -500,14 +514,15 @@ static inline int mdd_permission_internal(const struct lu_env *env,
                                           struct mdd_object *obj,
                                           struct lu_attr *la, 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,
 }
 
 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 */
 }
 
 /* mdd inline func for calling osd_dt_object ops */
index 3b13db7..e90ae04 100644 (file)
 #include <lustre_ver.h>
 #include "mdd_internal.h"
 
 #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);
 
 {
         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);
 {
         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_write_unlock(const struct lu_env *env, struct mdd_object *obj)
@@ -82,7 +119,7 @@ void mdd_read_unlock(const struct lu_env *env, struct mdd_object *obj)
 void mdd_pdlock_init(struct mdd_object *obj)
 {
         dynlock_init(&obj->mod_pdlock);
 void mdd_pdlock_init(struct mdd_object *obj)
 {
         dynlock_init(&obj->mod_pdlock);
-
+        mdd_lockdep_init(obj);
 }
 
 unsigned long mdd_name2hash(const char *name)
 }
 
 unsigned long mdd_name2hash(const char *name)
@@ -92,28 +129,41 @@ unsigned long mdd_name2hash(const char *name)
 
 struct dynlock_handle *mdd_pdo_write_lock(const struct lu_env *env,
                                           struct mdd_object *obj,
 
 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);
         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,
 }
 
 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);
         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)
 {
 }
 
 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)
 {
         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);
 }
         return dynlock_unlock(&obj->mod_pdlock, dlh);
 }
index d05c902..fcce64e 100644 (file)
@@ -220,7 +220,7 @@ int mdd_get_md_locked(const struct lu_env *env, struct mdd_object *obj,
                       void *md, int *md_size, const char *name)
 {
         int rc = 0;
                       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;
         rc = mdd_get_md(env, obj, md, md_size, name);
         mdd_read_unlock(env, obj);
         return rc;
@@ -296,7 +296,7 @@ int mdd_lsm_sanity_check(const struct lu_env *env,  struct mdd_object *obj)
         if ((uc->mu_fsuid != tmp_la->la_uid) &&
             !mdd_capable(uc, CFS_CAP_FOWNER))
                 rc = mdd_permission_internal_locked(env, obj, tmp_la,
         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);
 }
 
         RETURN(rc);
 }
@@ -852,7 +852,7 @@ int mdd_lov_setattr_async(const struct lu_env *env, struct mdd_object *obj,
         int rc = 0;
         ENTRY;
 
         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)
         rc = mdo_attr_get(env, obj, tmp_la, mdd_object_capa(env, obj));
         mdd_read_unlock(env, obj);
         if (rc)
index 1f49ce0..f057b2e 100644 (file)
@@ -232,7 +232,7 @@ static void mdd_object_delete(const struct lu_env *env,
                 if (IS_ERR(handle))
                         CERROR("Cannot get thandle\n");
                 else {
                 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);
                         /* let's remove obj from the orphan list */
                         __mdd_orphan_del(env, mdd_obj, handle);
                         mdd_write_unlock(env, mdd_obj);
@@ -357,7 +357,7 @@ int mdd_lmm_get_locked(const struct lu_env *env, struct mdd_object *mdd_obj,
         int rc;
         ENTRY;
 
         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);
         rc = __mdd_lmm_get(env, mdd_obj, ma);
         mdd_read_unlock(env, mdd_obj);
         RETURN(rc);
@@ -419,7 +419,7 @@ int mdd_attr_get_internal_locked(const struct lu_env *env,
         int needlock = ma->ma_need & (MA_LOV | MA_LMV | MA_ACL_DEF);
 
         if (needlock)
         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);
         rc = mdd_attr_get_internal(env, mdd_obj, ma);
         if (needlock)
                 mdd_read_unlock(env, mdd_obj);
@@ -454,7 +454,7 @@ static int mdd_xattr_get(const struct lu_env *env,
 
         LASSERT(mdd_object_exists(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);
         rc = mdo_xattr_get(env, mdd_obj, buf, name,
                            mdd_object_capa(env, mdd_obj));
         mdd_read_unlock(env, mdd_obj);
@@ -478,7 +478,7 @@ static int mdd_readlink(const struct lu_env *env, struct md_object *obj,
         LASSERT(mdd_object_exists(mdd_obj));
 
         next = mdd_object_child(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);
         rc = next->do_body_ops->dbo_read(env, next, buf, &pos,
                                          mdd_object_capa(env, mdd_obj));
         mdd_read_unlock(env, mdd_obj);
@@ -496,7 +496,7 @@ static int mdd_xattr_list(const struct lu_env *env, struct md_object *obj,
 
         ENTRY;
 
 
         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);
 
         rc = mdo_xattr_list(env, mdd_obj, buf, mdd_object_capa(env, mdd_obj));
         mdd_read_unlock(env, mdd_obj);
 
@@ -599,7 +599,7 @@ static int mdd_attr_set_internal_locked(const struct lu_env *env,
 
         needacl = needacl && (attr->la_valid & LA_MODE);
         if (needacl)
 
         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);
         rc = mdd_attr_set_internal(env, obj, attr, handle, needacl);
         if (needacl)
                 mdd_write_unlock(env, obj);
@@ -617,7 +617,7 @@ int mdd_attr_check_set_internal_locked(const struct lu_env *env,
 
         needacl = needacl && (attr->la_valid & LA_MODE);
         if (needacl)
 
         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);
         rc = mdd_attr_check_set_internal(env, obj, attr, handle, needacl);
         if (needacl)
                 mdd_write_unlock(env, obj);
@@ -724,7 +724,8 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj,
                 if ((uc->mu_fsuid != tmp_la->la_uid) &&
                     !mdd_capable(uc, CFS_CAP_FOWNER)) {
                         rc = mdd_permission_internal_locked(env, obj, tmp_la,
                 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);
                 }
                         if (rc)
                                 RETURN(rc);
                 }
@@ -829,7 +830,8 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj,
                               (uc->mu_fsuid == tmp_la->la_uid)) &&
                             !(ma->ma_attr_flags & MDS_PERM_BYPASS)) {
                                 rc = mdd_permission_internal_locked(env, obj,
                               (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);
                         }
                                 if (rc)
                                         RETURN(rc);
                         }
@@ -940,7 +942,7 @@ int mdd_xattr_set_txn(const struct lu_env *env, struct mdd_object *obj,
         int  rc;
         ENTRY;
 
         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);
 
         rc = __mdd_xattr_set(env, obj, buf, name, fl, handle);
         mdd_write_unlock(env, obj);
 
@@ -1020,7 +1022,7 @@ int mdd_xattr_del(const struct lu_env *env, struct md_object *obj,
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
         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);
         rc = mdo_xattr_del(env, mdd_obj, name, handle,
                            mdd_object_capa(env, mdd_obj));
         mdd_write_unlock(env, mdd_obj);
@@ -1057,7 +1059,7 @@ static int mdd_ref_del(const struct lu_env *env, struct md_object *obj,
         if (IS_ERR(handle))
                 RETURN(-ENOMEM);
 
         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)
 
         rc = mdd_unlink_sanity_check(env, NULL, mdd_obj, ma);
         if (rc)
@@ -1130,7 +1132,7 @@ static int mdd_object_create(const struct lu_env *env,
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
         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);
         rc = mdd_oc_sanity_check(env, mdd_obj, ma);
         if (rc)
                 GOTO(unlock, rc);
@@ -1179,9 +1181,9 @@ static int mdd_object_create(const struct lu_env *env,
         }
         EXIT;
 unlock:
         }
         EXIT;
 unlock:
-        mdd_write_unlock(env, mdd_obj);
         if (rc == 0)
         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;
 
         mdd_trans_stop(env, mdd, rc, handle);
         return rc;
@@ -1203,7 +1205,7 @@ static int mdd_ref_add(const struct lu_env *env, struct md_object *obj,
         if (IS_ERR(handle))
                 RETURN(-ENOMEM);
 
         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);
         rc = mdd_link_sanity_check(env, NULL, NULL, mdd_obj);
         if (rc == 0)
                 __mdd_ref_add(env, mdd_obj, handle);
@@ -1315,7 +1317,7 @@ static int mdd_open(const struct lu_env *env, struct md_object *obj,
         struct mdd_object *mdd_obj = md2mdd_obj(obj);
         int rc = 0;
 
         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)
 
         rc = mdd_open_sanity_check(env, mdd_obj, flags);
         if (rc == 0)
@@ -1362,7 +1364,7 @@ static int mdd_close(const struct lu_env *env, struct md_object *obj,
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
         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 --;
 
         /* release open count */
         mdd_obj->mod_count --;
 
@@ -1566,7 +1568,7 @@ static int mdd_readpage(const struct lu_env *env, struct md_object *obj,
 
         LASSERT(mdd_object_exists(mdd_obj));
 
 
         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);
         rc = mdd_readpage_sanity_check(env, mdd_obj);
         if (rc)
                 GOTO(out_unlock, rc);
index 18a1912..2ac658b 100644 (file)
@@ -130,7 +130,7 @@ static void orph_key_test_and_del(const struct lu_env *env,
         if (IS_ERR(mdo))
                 CERROR("Invalid orphan!\n");
         else {
         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;
                 if (mdo->mod_count == 0) {
                         /* non-opened orphan, let's delete it */
                         struct md_attr *ma = &mdd_env_info(env)->mti_ma;
index f1cf0ac..7714e61 100644 (file)
@@ -202,7 +202,7 @@ static int mdd_check_acl(const struct lu_env *env, struct mdd_object *obj,
 }
 
 int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj,
 }
 
 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;
 {
         struct md_ucred *uc = md_ucred(env);
         __u32 mode;
@@ -238,10 +238,10 @@ int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj,
                 mode >>= 6;
         } else {
                 if (mode & S_IRWXG) {
                 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);
                         rc = mdd_check_acl(env, obj, la, mask);
-                        if (needlock)
+                        if (role != -1)
                                 mdd_read_unlock(env, obj);
                         if (rc == -EACCES)
                                 goto check_capabilities;
                                 mdd_read_unlock(env, obj);
                         if (rc == -EACCES)
                                 goto check_capabilities;
@@ -315,7 +315,8 @@ int mdd_permission(const struct lu_env *env,
                 MAY_VTX_PART | MAY_VTX_FULL |
                 MAY_RGETFACL);
 
                 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);
 
         if (!rc && (check_create || check_link))
                 rc = mdd_may_create(env, mdd_cobj, NULL, 1, check_link);
index 7c6994b..62ed154 100644 (file)
@@ -100,10 +100,11 @@ struct osd_object {
         struct inode          *oo_inode;
         struct rw_semaphore    oo_sem;
         struct osd_directory  *oo_dir;
         struct inode          *oo_inode;
         struct rw_semaphore    oo_sem;
         struct osd_directory  *oo_dir;
-        /* protects inode attributes. */
+        /** protects inode attributes. */
         spinlock_t             oo_guard;
         spinlock_t             oo_guard;
-#if OSD_COUNTERS
         const struct lu_env   *oo_owner;
         const struct lu_env   *oo_owner;
+#ifdef CONFIG_LOCKDEP
+        struct lockdep_map     oo_dep_map;
 #endif
 };
 
 #endif
 };
 
@@ -785,58 +786,46 @@ static struct dt_device_operations osd_dt_ops = {
 };
 
 static void osd_object_read_lock(const struct lu_env *env,
 };
 
 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_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++;
 
                 LASSERT(obj->oo_owner == NULL);
                 oti->oti_r_locks++;
-        }
-#endif
 }
 
 static void osd_object_write_lock(const struct lu_env *env,
 }
 
 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_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++;
 
                 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);
 }
 
 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);
 
                 struct osd_thread_info *oti = osd_oti_get(env);
 
+        LINVRNT(osd_invariant(obj));
+
                 LASSERT(oti->oti_r_locks > 0);
                 oti->oti_r_locks--;
                 LASSERT(oti->oti_r_locks > 0);
                 oti->oti_r_locks--;
-        }
-#endif
         up_read(&obj->oo_sem);
 }
 
         up_read(&obj->oo_sem);
 }