From c173ef1be8e2936d4f186dda576e401602d485fd Mon Sep 17 00:00:00 2001 From: huanghua Date: Tue, 26 Aug 2008 03:32:38 +0000 Subject: [PATCH] Branch HEAD b=16656 i=tom.wang i=yury.umanets change locking in mdd_create() to never take more than 1 dt_object lock at a time. --- lustre/mdd/mdd_dir.c | 64 +++++++++++++++++++++++++++++---------------- lustre/mdd/mdd_internal.h | 4 +-- lustre/mdd/mdd_object.c | 2 +- lustre/mdd/mdd_permission.c | 29 +------------------- 4 files changed, 44 insertions(+), 55 deletions(-) diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 221df4f..1c76e3d 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -1266,24 +1266,27 @@ static int mdd_create(const struct lu_env *env, struct md_op_spec *spec, struct md_attr* ma) { - char *name = lname->ln_name; - struct lu_attr *la = &mdd_env_info(env)->mti_la_for_fix; - struct mdd_object *mdd_pobj = md2mdd_obj(pobj); - struct mdd_object *son = md2mdd_obj(child); - struct mdd_device *mdd = mdo2mdd(pobj); - struct lu_attr *attr = &ma->ma_attr; - struct lov_mds_md *lmm = NULL; - struct thandle *handle; + struct mdd_thread_info *info = mdd_env_info(env); + struct lu_attr *la = &info->mti_la_for_fix; + struct md_attr *ma_acl = &info->mti_ma; + struct mdd_object *mdd_pobj = md2mdd_obj(pobj); + struct mdd_object *son = md2mdd_obj(child); + struct mdd_device *mdd = mdo2mdd(pobj); + struct lu_attr *attr = &ma->ma_attr; + struct lov_mds_md *lmm = NULL; + struct thandle *handle; + struct dynlock_handle *dlh; + char *name = lname->ln_name; int rc, created = 0, initialized = 0, inserted = 0, lmm_size = 0; - struct dynlock_handle *dlh; + int got_def_acl = 0; ENTRY; /* * Two operations have to be performed: * - * - allocation of new object (->do_create()), and + * - an allocation of a new object (->do_create()), and * - * - insertion into parent index (->dio_insert()). + * - an insertion into a parent index (->dio_insert()). * * Due to locking, operation order is not important, when both are * successful, *but* error handling cases are quite different: @@ -1330,6 +1333,21 @@ static int mdd_create(const struct lu_env *env, RETURN(rc); } + if (!S_ISLNK(attr->la_mode)) { + ma_acl->ma_acl_size = sizeof info->mti_xattr_buf; + ma_acl->ma_acl = info->mti_xattr_buf; + ma_acl->ma_need = MA_ACL_DEF; + ma_acl->ma_valid = 0; + + mdd_read_lock(env, mdd_pobj); + rc = mdd_def_acl_get(env, mdd_pobj, ma_acl); + mdd_read_unlock(env, mdd_pobj); + if (rc) + GOTO(out_free, rc); + else if (ma_acl->ma_valid & MA_ACL_DEF) + got_def_acl = 1; + } + mdd_txn_param_build(env, mdd, MDD_TXN_MKDIR_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) @@ -1339,10 +1357,6 @@ static int mdd_create(const struct lu_env *env, if (dlh == NULL) GOTO(out_trans, rc = -ENOMEM); - /* - * XXX: Check that link can be added to the parent in mkdir case. - */ - mdd_write_lock(env, son); rc = mdd_object_create_internal(env, mdd_pobj, son, ma, handle); if (rc) { @@ -1353,14 +1367,18 @@ static int mdd_create(const struct lu_env *env, created = 1; #ifdef CONFIG_FS_POSIX_ACL - mdd_read_lock(env, mdd_pobj); - rc = mdd_acl_init(env, mdd_pobj, son, &ma->ma_attr.la_mode, handle); - mdd_read_unlock(env, mdd_pobj); - if (rc) { - mdd_write_unlock(env, son); - GOTO(cleanup, rc); - } else { - ma->ma_attr.la_valid |= LA_MODE; + if (got_def_acl) { + struct lu_buf *acl_buf = &info->mti_buf; + acl_buf->lb_buf = ma_acl->ma_acl; + acl_buf->lb_len = ma_acl->ma_acl_size; + + rc = __mdd_acl_init(env, son, acl_buf, &attr->la_mode, handle); + if (rc) { + mdd_write_unlock(env, son); + GOTO(cleanup, rc); + } else { + ma->ma_attr.la_valid |= LA_MODE; + } } #endif diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 01fb5c7..2747678 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -333,14 +333,12 @@ static inline int mdd_capable(struct md_ucred *uc, int cap) return 0; } -int mdd_acl_def_get(const struct lu_env *env, struct mdd_object *mdd_obj, +int mdd_def_acl_get(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma); int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode, struct thandle *handle); int __mdd_acl_init(const struct lu_env *env, struct mdd_object *obj, struct lu_buf *buf, __u32 *mode, struct thandle *handle); -int mdd_acl_init(const struct lu_env *env, struct mdd_object *pobj, - struct mdd_object *cobj, __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); int mdd_permission(const struct lu_env *env, diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 7130787..1bea083 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -404,7 +404,7 @@ static int mdd_attr_get_internal(const struct lu_env *env, #ifdef CONFIG_FS_POSIX_ACL if (rc == 0 && ma->ma_need & MA_ACL_DEF) { if (S_ISDIR(mdd_object_type(mdd_obj))) - rc = mdd_acl_def_get(env, mdd_obj, ma); + rc = mdd_def_acl_get(env, mdd_obj, ma); } #endif CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64"\n", diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c index d997344..1238582 100644 --- a/lustre/mdd/mdd_permission.c +++ b/lustre/mdd/mdd_permission.c @@ -65,7 +65,7 @@ * Get default acl EA only. * Hold read_lock for mdd_obj. */ -int mdd_acl_def_get(const struct lu_env *env, struct mdd_object *mdd_obj, +int mdd_def_acl_get(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma) { struct lu_buf *buf; @@ -163,33 +163,6 @@ int __mdd_acl_init(const struct lu_env *env, struct mdd_object *obj, BYPASS_CAPA); RETURN(rc); } - -/* - * Hold read_lock for pobj. - * Hold write_lock for cobj. - */ -int mdd_acl_init(const struct lu_env *env, struct mdd_object *pobj, - struct mdd_object *cobj, __u32 *mode, struct thandle *handle) -{ - struct lu_buf *buf; - int rc; - ENTRY; - - if (S_ISLNK(*mode)) - RETURN(0); - - buf = mdd_buf_get(env, mdd_env_info(env)->mti_xattr_buf, - sizeof(mdd_env_info(env)->mti_xattr_buf)); - rc = mdo_xattr_get(env, pobj, buf, XATTR_NAME_ACL_DEFAULT, BYPASS_CAPA); - if ((rc == -EOPNOTSUPP) || (rc == -ENODATA)) - RETURN(0); - else if (rc <= 0) - RETURN(rc); - - buf->lb_len = rc; - rc = __mdd_acl_init(env, cobj, buf, mode, handle); - RETURN(rc); -} #endif /* -- 1.8.3.1