Whamcloud - gitweb
Branch HEAD
authorhuanghua <huanghua>
Tue, 26 Aug 2008 03:32:38 +0000 (03:32 +0000)
committerhuanghua <huanghua>
Tue, 26 Aug 2008 03:32:38 +0000 (03:32 +0000)
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
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_object.c
lustre/mdd/mdd_permission.c

index 221df4f..1c76e3d 100644 (file)
@@ -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
 
index 01fb5c7..2747678 100644 (file)
@@ -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,
index 7130787..1bea083 100644 (file)
@@ -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",
index d997344..1238582 100644 (file)
@@ -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
 
 /*