From 6c8ed1d8edb0f6fe1d79172f7fa4a0fcf5053dfe Mon Sep 17 00:00:00 2001 From: nikita Date: Sat, 18 Oct 2008 15:25:48 +0000 Subject: [PATCH] Augment ->do_{read,write}_lock() prototypes with a `role' parameter indicating lock ordering. Update mdd code to use new locking interface. b=16450 --- lustre/ChangeLog | 7 +++++ lustre/include/dt_object.h | 8 +++--- lustre/mdd/mdd_dir.c | 63 ++++++++++++++++++++++------------------- lustre/mdd/mdd_internal.h | 31 +++++++++++++++------ lustre/mdd/mdd_lock.c | 68 +++++++++++++++++++++++++++++++++++++++------ lustre/mdd/mdd_lov.c | 6 ++-- lustre/mdd/mdd_object.c | 42 +++++++++++++++------------- lustre/mdd/mdd_orphans.c | 2 +- lustre/mdd/mdd_permission.c | 11 ++++---- lustre/osd/osd_handler.c | 41 ++++++++++----------------- 10 files changed, 175 insertions(+), 104 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index f3df71e..04c2402 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -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(). +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. diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index 981f461..f535c69 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -182,19 +182,19 @@ struct dt_allocation_hint { __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 diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 8692b23..4625205 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -80,7 +80,7 @@ __mdd_lookup_locked(const struct lu_env *env, struct md_object *pobj, 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); @@ -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_ops *iops; + const struct dt_it_ops *iops; 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, - MAY_WRITE | MAY_EXEC); + MAY_WRITE | MAY_EXEC, + MOR_TGT_PARENT); 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, - MAY_WRITE | MAY_EXEC); + MAY_WRITE | MAY_EXEC, + MOR_TGT_PARENT); 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, - MAY_WRITE | MAY_EXEC); + MAY_WRITE | MAY_EXEC, + MOR_TGT_PARENT); 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) { - mdd_write_lock(env, pobj); + mdd_write_lock(env, pobj, MOR_TGT_PARENT); __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; - 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); } @@ -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)); - 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) @@ -701,10 +704,10 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, 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); @@ -790,7 +793,7 @@ static int mdd_name_insert(const struct lu_env *env, 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); @@ -863,7 +866,7 @@ static int mdd_name_remove(const struct lu_env *env, 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); @@ -944,11 +947,11 @@ static int mdd_rename_tgt(const struct lu_env *env, 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) @@ -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); - 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); @@ -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. */ - 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); } @@ -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; - 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) @@ -1353,11 +1358,11 @@ static int mdd_create(const struct lu_env *env, 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); @@ -1456,7 +1461,7 @@ cleanup: } 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); @@ -1598,18 +1603,20 @@ static int mdd_rename(const struct lu_env *env, /* 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); @@ -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)) { - 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. */ diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 5263556..896248a 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -100,6 +100,13 @@ enum mod_flags { #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 */ @@ -107,6 +114,9 @@ struct mdd_object { __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 { @@ -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 */ -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); @@ -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, - 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, @@ -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, - 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); @@ -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) { - 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 */ diff --git a/lustre/mdd/mdd_lock.c b/lustre/mdd/mdd_lock.c index 3b13db7..e90ae04 100644 --- a/lustre/mdd/mdd_lock.c +++ b/lustre/mdd/mdd_lock.c @@ -49,17 +49,54 @@ #include #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) @@ -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); - + mdd_lockdep_init(obj); } 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, - 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); } diff --git a/lustre/mdd/mdd_lov.c b/lustre/mdd/mdd_lov.c index d05c902..fcce64e 100644 --- a/lustre/mdd/mdd_lov.c +++ b/lustre/mdd/mdd_lov.c @@ -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; - 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; @@ -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, - MAY_WRITE); + MAY_WRITE, MOR_TGT_CHILD); RETURN(rc); } @@ -852,7 +852,7 @@ int mdd_lov_setattr_async(const struct lu_env *env, struct mdd_object *obj, 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) diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 1f49ce0..f057b2e 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -232,7 +232,7 @@ static void mdd_object_delete(const struct lu_env *env, 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); @@ -357,7 +357,7 @@ int mdd_lmm_get_locked(const struct lu_env *env, struct mdd_object *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); @@ -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) - 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); @@ -454,7 +454,7 @@ static int mdd_xattr_get(const struct lu_env *env, 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); @@ -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); - 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); @@ -496,7 +496,7 @@ static int mdd_xattr_list(const struct lu_env *env, struct md_object *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); @@ -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) - 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); @@ -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) - 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); @@ -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, - MAY_WRITE); + MAY_WRITE, + MOR_TGT_CHILD); 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, - tmp_la, MAY_WRITE); + tmp_la, MAY_WRITE, + MOR_TGT_CHILD); 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; - 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); @@ -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)); - 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); @@ -1057,7 +1059,7 @@ static int mdd_ref_del(const struct lu_env *env, struct md_object *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) @@ -1130,7 +1132,7 @@ static int mdd_object_create(const struct lu_env *env, 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); @@ -1179,9 +1181,9 @@ static int mdd_object_create(const struct lu_env *env, } 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; @@ -1203,7 +1205,7 @@ static int mdd_ref_add(const struct lu_env *env, struct md_object *obj, 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); @@ -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; - 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) @@ -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)); - mdd_write_lock(env, mdd_obj); + mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); /* 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)); - 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); diff --git a/lustre/mdd/mdd_orphans.c b/lustre/mdd/mdd_orphans.c index 18a1912..2ac658b 100644 --- a/lustre/mdd/mdd_orphans.c +++ b/lustre/mdd/mdd_orphans.c @@ -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 { - 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; diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c index f1cf0ac..7714e61 100644 --- a/lustre/mdd/mdd_permission.c +++ b/lustre/mdd/mdd_permission.c @@ -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, - 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; @@ -238,10 +238,10 @@ int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj, 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; @@ -315,7 +315,8 @@ int mdd_permission(const struct lu_env *env, 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); diff --git a/lustre/osd/osd_handler.c b/lustre/osd/osd_handler.c index 7c6994b..62ed154 100644 --- a/lustre/osd/osd_handler.c +++ b/lustre/osd/osd_handler.c @@ -100,10 +100,11 @@ struct osd_object { 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 }; @@ -785,58 +786,46 @@ static struct dt_device_operations osd_dt_ops = { }; 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); } -- 1.8.3.1