Whamcloud - gitweb
LU-1146 build: batch update copyright messages
[fs/lustre-release.git] / lustre / mdd / mdd_dir.c
index 9365542..21cd018 100644 (file)
@@ -29,8 +29,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011 Whamcloud, Inc.
- *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -494,43 +493,6 @@ int mdd_link_sanity_check(const struct lu_env *env,
         RETURN(rc);
 }
 
-/**
- * If subdir count is up to ddp_max_nlink, then enable MNLINK_OBJ flag and
- * assign i_nlink to 1 which means the i_nlink for subdir count is incredible
- * (maybe too large to be represented). It is a trick to break through the
- * "i_nlink" limitation for subdir count.
- */
-void __mdd_ref_add(const struct lu_env *env, struct mdd_object *obj,
-                   struct thandle *handle)
-{
-        struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
-        struct mdd_device *m = mdd_obj2mdd_dev(obj);
-
-        if (!mdd_is_mnlink(obj)) {
-                if (S_ISDIR(mdd_object_type(obj))) {
-                        if (mdd_la_get(env, obj, tmp_la, BYPASS_CAPA))
-                                return;
-
-                        if (tmp_la->la_nlink >= m->mdd_dt_conf.ddp_max_nlink) {
-                                obj->mod_flags |= MNLINK_OBJ;
-                                tmp_la->la_nlink = 1;
-                                tmp_la->la_valid = LA_NLINK;
-                                mdd_attr_set_internal(env, obj, tmp_la, handle,
-                                                      0);
-                                return;
-                        }
-                }
-                mdo_ref_add(env, obj, handle);
-        }
-}
-
-void __mdd_ref_del(const struct lu_env *env, struct mdd_object *obj,
-                   struct thandle *handle, int is_dot)
-{
-        if (!mdd_is_mnlink(obj) || is_dot)
-                mdo_ref_del(env, obj, handle);
-}
-
 static int __mdd_index_delete_only(const struct lu_env *env, struct mdd_object *pobj,
                                    const char *name, struct thandle *handle,
                                    struct lustre_capa *capa)
@@ -584,7 +546,7 @@ static int __mdd_index_insert(const struct lu_env *env, struct mdd_object *pobj,
         rc = __mdd_index_insert_only(env, pobj, lf, name, handle, capa);
         if (rc == 0 && is_dir) {
                 mdd_write_lock(env, pobj, MOR_TGT_PARENT);
-                __mdd_ref_add(env, pobj, handle);
+                mdo_ref_add(env, pobj, handle);
                 mdd_write_unlock(env, pobj);
         }
         RETURN(rc);
@@ -600,12 +562,8 @@ static int __mdd_index_delete(const struct lu_env *env, struct mdd_object *pobj,
 
         rc = __mdd_index_delete_only(env, pobj, name, handle, capa);
         if (rc == 0 && is_dir) {
-                int is_dot = 0;
-
-                if (name != NULL && name[0] == '.' && name[1] == 0)
-                        is_dot = 1;
                 mdd_write_lock(env, pobj, MOR_TGT_PARENT);
-                __mdd_ref_del(env, pobj, handle, is_dot);
+                mdo_ref_del(env, pobj, handle);
                 mdd_write_unlock(env, pobj);
         }
 
@@ -622,14 +580,29 @@ int mdd_declare_llog_record(const struct lu_env *env, struct mdd_device *mdd,
 
         LASSERT(mdd->mdd_capa);
 
+        /* XXX: Since we use the 'mdd_capa' as fake llog object here, we
+         *      have to set the parameter 'size' as INT_MAX or 0 to inform
+         *      OSD that this record write is for a llog write or catalog
+         *      header update, and osd declare function will reserve less
+         *      credits for optimization purpose.
+         *
+         *      Reserve 6 blocks for a llog write, since the llog file is
+         *      usually small, reserve 2 blocks for catalog header update,
+         *      because we know for sure that catalog header is already
+         *      allocated.
+         *
+         *      This hack should be removed in 2.3.
+         */
+
         /* record itself */
-        rc = dt_declare_record_write(env, mdd->mdd_capa, reclen, 0, handle);
+        rc = dt_declare_record_write(env, mdd->mdd_capa,
+                                     DECLARE_LLOG_WRITE, 0, handle);
         if (rc)
                 return rc;
 
         /* header will be updated as well */
-        rc = dt_declare_record_write(env, mdd->mdd_capa, LLOG_CHUNK_SIZE,
-                                     0, handle);
+        rc = dt_declare_record_write(env, mdd->mdd_capa,
+                                     DECLARE_LLOG_WRITE, 0, handle);
         if (rc)
                 return rc;
 
@@ -640,13 +613,13 @@ int mdd_declare_llog_record(const struct lu_env *env, struct mdd_device *mdd,
 
         /* new record referencing new plain llog */
         rc = dt_declare_record_write(env, mdd->mdd_capa,
-                                     sizeof(struct llog_logid_rec), 0, handle);
+                                     DECLARE_LLOG_WRITE, 0, handle);
         if (rc)
                 return rc;
 
         /* catalog's header will be updated as well */
-        rc = dt_declare_record_write(env, mdd->mdd_capa, LLOG_CHUNK_SIZE,
-                                     0, handle);
+        rc = dt_declare_record_write(env, mdd->mdd_capa,
+                                     DECLARE_LLOG_REWRITE, 0, handle);
 
         return rc;
 }
@@ -834,7 +807,7 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj,
         if (rc)
                 GOTO(out_unlock, rc);
 
-        __mdd_ref_add(env, mdd_sobj, handle);
+        mdo_ref_add(env, mdd_sobj, handle);
 
         LASSERT(ma->ma_attr.la_valid & LA_CTIME);
         la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
@@ -896,6 +869,7 @@ int mdd_finish_unlink(const struct lu_env *env,
 {
         int rc;
         int reset = 1;
+        int is_dir = S_ISDIR(ma->ma_attr.la_mode);
         ENTRY;
 
         LASSERT(mdd_write_locked(env, obj) != 0);
@@ -903,7 +877,7 @@ int mdd_finish_unlink(const struct lu_env *env,
         /* read HSM flags, needed to set changelogs flags */
         ma->ma_need = MA_HSM | MA_INODE;
         rc = mdd_attr_get_internal(env, obj, ma);
-        if (rc == 0 && ma->ma_attr.la_nlink == 0) {
+        if (rc == 0 && (ma->ma_attr.la_nlink == 0 || is_dir)) {
                 obj->mod_flags |= DEAD_OBJ;
                 /* add new orphan and the object
                  * will be deleted during mdd_close() */
@@ -926,6 +900,9 @@ int mdd_finish_unlink(const struct lu_env *env,
                                 reset = 0;
                 }
 
+                /* get the i_nlink */
+                ma->ma_need = MA_INODE;
+                rc = mdd_attr_get_internal(env, obj, ma);
         }
         if (reset)
                 ma->ma_valid &= ~(MA_LOV | MA_COOKIE);
@@ -1044,10 +1021,10 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
         if (rc)
                 GOTO(cleanup, rc);
 
-        __mdd_ref_del(env, mdd_cobj, handle, 0);
+        mdo_ref_del(env, mdd_cobj, handle);
         if (is_dir)
                 /* unlink dot */
-                __mdd_ref_del(env, mdd_cobj, handle, 1);
+                mdo_ref_del(env, mdd_cobj, handle);
 
         LASSERT(ma->ma_attr.la_valid & LA_CTIME);
         la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
@@ -1463,11 +1440,11 @@ static int mdd_rename_tgt(const struct lu_env *env,
          * it must be local one.
          */
         if (tobj && mdd_object_exists(mdd_tobj)) {
-                __mdd_ref_del(env, mdd_tobj, handle, 0);
+                mdo_ref_del(env, mdd_tobj, handle);
 
                 /* Remove dot reference. */
                 if (S_ISDIR(ma->ma_attr.la_mode))
-                        __mdd_ref_del(env, mdd_tobj, handle, 1);
+                        mdo_ref_del(env, mdd_tobj, handle);
 
                 la->la_valid = LA_CTIME;
                 rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0);
@@ -1561,7 +1538,6 @@ static int mdd_create_data(const struct lu_env *env, struct md_object *pobj,
         struct mdd_device *mdd = mdo2mdd(cobj);
         struct mdd_object *mdd_pobj = md2mdd_obj(pobj);
         struct mdd_object *son = md2mdd_obj(cobj);
-        struct lu_attr    *attr = &ma->ma_attr;
         struct lov_mds_md *lmm = NULL;
         int                lmm_size = 0;
         struct thandle    *handle;
@@ -1575,8 +1551,8 @@ static int mdd_create_data(const struct lu_env *env, struct md_object *pobj,
         if (!md_should_create(spec->sp_cr_flags))
                 RETURN(0);
         lmm_size = ma->ma_lmm_size;
-        rc = mdd_lov_create(env, mdd, mdd_pobj, son, &lmm, &lmm_size,
-                            spec, attr);
+
+        rc = mdd_lov_create(env, mdd, mdd_pobj, son, &lmm, &lmm_size, spec, ma);
         if (rc)
                 RETURN(rc);
 
@@ -1621,6 +1597,8 @@ stop:
         mdd_trans_stop(env, mdd, rc, handle);
 out_free:
         /* Finish mdd_lov_create() stuff. */
+        /* if no_create == 0 (not replay), we free lmm allocated by
+         * mdd_lov_create() */
         mdd_lov_create_finish(env, mdd, lmm, lmm_size, spec);
         RETURN(rc);
 }
@@ -1717,7 +1695,7 @@ int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid,
 
         if (S_ISDIR(ma->ma_attr.la_mode)) {
                 /* Add "." and ".." for newly created dir */
-                __mdd_ref_add(env, child, handle);
+                mdo_ref_add(env, child, handle);
                 rc = __mdd_index_insert_only(env, child, mdo2fid(child),
                                              dot, handle, BYPASS_CAPA);
                 if (rc == 0)
@@ -1725,7 +1703,7 @@ int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid,
                                                      dotdot, handle,
                                                      BYPASS_CAPA);
                 if (rc != 0)
-                        __mdd_ref_del(env, child, handle, 1);
+                        mdo_ref_del(env, child, handle);
         }
         if (rc == 0)
                 mdd_links_add(env, child, pfid, lname, handle, 1);
@@ -2015,7 +1993,7 @@ static int mdd_create(const struct lu_env *env,
         if (S_ISREG(attr->la_mode)) {
                 lmm_size = ma->ma_lmm_size;
                 rc = mdd_lov_create(env, mdd, mdd_pobj, son, &lmm, &lmm_size,
-                                    spec, attr);
+                                    spec, ma);
                 if (rc)
                         GOTO(out_pending, rc);
         }
@@ -2155,9 +2133,9 @@ cleanup:
 
                 if (rc2 == 0) {
                         mdd_write_lock(env, son, MOR_TGT_CHILD);
-                        __mdd_ref_del(env, son, handle, 0);
+                        mdo_ref_del(env, son, handle);
                         if (initialized && S_ISDIR(attr->la_mode))
-                                __mdd_ref_del(env, son, handle, 1);
+                                mdo_ref_del(env, son, handle);
                         mdd_write_unlock(env, son);
                 }
         }
@@ -2575,11 +2553,11 @@ static int mdd_rename(const struct lu_env *env,
                         rc = -EINVAL;
                         goto cleanup;
                 }
-                __mdd_ref_del(env, mdd_tobj, handle, 0);
+                mdo_ref_del(env, mdd_tobj, handle);
 
                 /* Remove dot reference. */
                 if (is_dir)
-                        __mdd_ref_del(env, mdd_tobj, handle, 1);
+                        mdo_ref_del(env, mdd_tobj, handle);
 
                 la->la_valid = LA_CTIME;
                 rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0);
@@ -3004,6 +2982,7 @@ const struct md_dir_operations mdd_dir_ops = {
         .mdo_rename        = mdd_rename,
         .mdo_link          = mdd_link,
         .mdo_unlink        = mdd_unlink,
+        .mdo_lum_lmm_cmp   = mdd_lum_lmm_cmp,
         .mdo_name_insert   = mdd_name_insert,
         .mdo_name_remove   = mdd_name_remove,
         .mdo_rename_tgt    = mdd_rename_tgt,