Whamcloud - gitweb
b=19188
[fs/lustre-release.git] / lustre / mdd / mdd_dir.c
index 9966c9e..f5bfade 100644 (file)
@@ -391,7 +391,13 @@ int mdd_may_delete(const struct lu_env *env, struct mdd_object *pobj,
         if (!mdd_object_exists(cobj))
                 RETURN(-ENOENT);
 
+        if (mdd_is_dead_obj(cobj))
+                RETURN(-ESTALE);
+
         if (pobj) {
+                if (!mdd_object_exists(pobj))
+                        RETURN(-ENOENT);
+
                 if (mdd_is_dead_obj(pobj))
                         RETURN(-ENOENT);
 
@@ -448,6 +454,9 @@ int mdd_link_sanity_check(const struct lu_env *env,
         int rc = 0;
         ENTRY;
 
+        if (!mdd_object_exists(src_obj))
+                RETURN(-ENOENT);
+
         if (mdd_is_dead_obj(src_obj))
                 RETURN(-ESTALE);
 
@@ -667,7 +676,7 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj,
         struct obd_device *obd = mdd->mdd_obd_dev;
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qids[MAXQUOTAS] = { 0, 0 };
-        int quota_opc = 0, rec_pending = 0;
+        int quota_opc = 0, rec_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         int rc;
         ENTRY;
@@ -684,9 +693,8 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj,
                         mdd_quota_wrapper(la_tmp, qids);
                         /* get block quota for parent */
                         lquota_chkquota(mds_quota_interface_ref, obd,
-                                        qids[USRQUOTA], qids[GRPQUOTA], 1,
-                                        &rec_pending, NULL, LQUOTA_FLAGS_BLK,
-                                        data, 1);
+                                        qids, rec_pending, 1, NULL,
+                                        LQUOTA_FLAGS_BLK, data, 1);
                 }
         }
 #endif
@@ -738,10 +746,8 @@ out_trans:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
-                if (rec_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qids[USRQUOTA], qids[GRPQUOTA],
-                                              rec_pending, 1);
+                lquota_pending_commit(mds_quota_interface_ref, obd,
+                                      qids, rec_pending, 1);
                 /* Trigger dqacq for the parent owner. If failed,
                  * the next call for lquota_chkquota will process it. */
                 lquota_adjust(mds_quota_interface_ref, obd, 0, qids, rc,
@@ -799,9 +805,6 @@ int mdd_unlink_sanity_check(const struct lu_env *env, struct mdd_object *pobj,
         int rc;
         ENTRY;
 
-        if (mdd_is_dead_obj(cobj))
-                RETURN(-ESTALE);
-
         rc = mdd_may_delete(env, pobj, cobj, ma, 1, 1);
 
         RETURN(rc);
@@ -960,7 +963,7 @@ static int mdd_name_insert(const struct lu_env *env,
         struct obd_device *obd = mdd->mdd_obd_dev;
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qids[MAXQUOTAS] = { 0, 0 };
-        int quota_opc = 0, rec_pending = 0;
+        int quota_opc = 0, rec_pending[MAXQUOTAS] = { 0, 0 };
         cfs_cap_t save = uc->mu_cap;
 #endif
         int rc;
@@ -979,8 +982,7 @@ static int mdd_name_insert(const struct lu_env *env,
                                 mdd_quota_wrapper(la_tmp, qids);
                                 /* get block quota for parent */
                                 lquota_chkquota(mds_quota_interface_ref, obd,
-                                                qids[USRQUOTA], qids[GRPQUOTA],
-                                                1, &rec_pending, NULL,
+                                                qids, rec_pending, 1, NULL,
                                                 LQUOTA_FLAGS_BLK, data, 1);
                         }
                 } else {
@@ -1027,11 +1029,8 @@ out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
                 if (quota_opc) {
-                        if (rec_pending)
-                                lquota_pending_commit(mds_quota_interface_ref,
-                                                      obd, qids[USRQUOTA],
-                                                      qids[GRPQUOTA],
-                                                      rec_pending, 1);
+                        lquota_pending_commit(mds_quota_interface_ref,
+                                              obd, qids, rec_pending, 1);
                         /* Trigger dqacq for the parent owner. If failed,
                          * the next call for lquota_chkquota will process it*/
                         lquota_adjust(mds_quota_interface_ref, obd, 0, qids,
@@ -1188,7 +1187,8 @@ static int mdd_rename_tgt(const struct lu_env *env,
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qpids[MAXQUOTAS] = { 0, 0 };
-        int quota_opc = 0, rec_pending = 0;
+        int quota_copc = 0, quota_popc = 0;
+        int rec_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         int rc;
         ENTRY;
@@ -1201,13 +1201,12 @@ static int mdd_rename_tgt(const struct lu_env *env,
                 if (!rc) {
                         void *data = NULL;
                         mdd_data_get(env, mdd_tpobj, &data);
-                        quota_opc = FSFILT_OP_LINK;
+                        quota_popc = FSFILT_OP_LINK;
                         mdd_quota_wrapper(la_tmp, qpids);
                         /* get block quota for target parent */
                         lquota_chkquota(mds_quota_interface_ref, obd,
-                                        qpids[USRQUOTA], qpids[GRPQUOTA], 1,
-                                        &rec_pending, NULL, LQUOTA_FLAGS_BLK,
-                                        data, 1);
+                                        qpids, rec_pending, 1, NULL,
+                                        LQUOTA_FLAGS_BLK, data, 1);
                 }
         }
 #endif
@@ -1271,7 +1270,7 @@ static int mdd_rename_tgt(const struct lu_env *env,
 #ifdef HAVE_QUOTA_SUPPORT
                 if (mds->mds_quota && ma->ma_valid & MA_INODE &&
                     ma->ma_attr.la_nlink == 0 && mdd_tobj->mod_count == 0) {
-                        quota_opc = FSFILT_OP_UNLINK_PARTIAL_CHILD;
+                        quota_copc = FSFILT_OP_UNLINK_PARTIAL_CHILD;
                         mdd_quota_wrapper(&ma->ma_attr, qcids);
                 }
 #endif
@@ -1292,17 +1291,16 @@ out_trans:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
-                if (rec_pending)
+                if (quota_popc)
                         lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qpids[USRQUOTA],
-                                              qpids[GRPQUOTA],
-                                              rec_pending, 1);
-                if (quota_opc)
-                        /* Trigger dqrel/dqacq on the target owner of child and
-                         * parent. If failed, the next call for lquota_chkquota
+                                              qpids, rec_pending, 1);
+
+                if (quota_copc)
+                        /* Trigger dqrel on the target owner of child.
+                         * If failed, the next call for lquota_chkquota
                          * will process it. */
-                        lquota_adjust(mds_quota_interface_ref, obd, qcids,
-                                      qpids, rc, quota_opc);
+                        lquota_adjust(mds_quota_interface_ref, obd, qcids, qpids,
+                                      rc, quota_copc);
         }
 #endif
         return rc;
@@ -1344,7 +1342,7 @@ 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);
         if (rc)
@@ -1597,7 +1595,9 @@ static int mdd_create(const struct lu_env *env,
         unsigned int qcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qpids[MAXQUOTAS] = { 0, 0 };
         int quota_opc = 0, block_count = 0;
-        int inode_pending = 0, block_pending = 0, parent_pending = 0;
+        int inode_pending[MAXQUOTAS] = { 0, 0 };
+        int block_pending[MAXQUOTAS] = { 0, 0 };
+        int parent_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         ENTRY;
 
@@ -1654,9 +1654,8 @@ static int mdd_create(const struct lu_env *env,
                         mdd_quota_wrapper(&ma->ma_attr, qcids);
                         mdd_quota_wrapper(la_tmp, qpids);
                         /* get file quota for child */
-                        lquota_chkquota(mds_quota_interface_ref, obd,
-                                        qcids[USRQUOTA], qcids[GRPQUOTA], 1,
-                                        &inode_pending, NULL, 0, NULL, 0);
+                        lquota_chkquota(mds_quota_interface_ref, obd, qcids,
+                                        inode_pending, 1, NULL, 0, NULL, 0);
                         switch (ma->ma_attr.la_mode & S_IFMT) {
                         case S_IFLNK:
                         case S_IFDIR:
@@ -1674,14 +1673,12 @@ static int mdd_create(const struct lu_env *env,
                         /* get block quota for child and parent */
                         if (block_count)
                                 lquota_chkquota(mds_quota_interface_ref, obd,
-                                                qcids[USRQUOTA], qcids[GRPQUOTA],
-                                                block_count,
-                                                &block_pending, NULL,
+                                                qcids, block_pending,
+                                                block_count, NULL,
                                                 LQUOTA_FLAGS_BLK, NULL, 0);
                         if (!same)
                                 lquota_chkquota(mds_quota_interface_ref, obd,
-                                                qpids[USRQUOTA], qpids[GRPQUOTA], 1,
-                                                &parent_pending, NULL,
+                                                qpids, parent_pending, 1, NULL,
                                                 LQUOTA_FLAGS_BLK, NULL, 0);
                 }
         }
@@ -1692,6 +1689,7 @@ static int mdd_create(const struct lu_env *env,
          * first.
          */
         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);
                 if (rc)
@@ -1851,18 +1849,12 @@ out_free:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
-                if (inode_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qcids[USRQUOTA], qcids[GRPQUOTA],
-                                              inode_pending, 0);
-                if (block_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qcids[USRQUOTA], qcids[GRPQUOTA],
-                                              block_pending, 1);
-                if (parent_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qpids[USRQUOTA], qpids[GRPQUOTA],
-                                              parent_pending, 1);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qcids,
+                                      inode_pending, 0);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qcids,
+                                      block_pending, 1);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qpids,
+                                      parent_pending, 1);
                 /* Trigger dqacq on the owner of child and parent. If failed,
                  * the next call for lquota_chkquota will process it. */
                 lquota_adjust(mds_quota_interface_ref, obd, qcids, qpids, rc,
@@ -1932,9 +1924,6 @@ static int mdd_rename_sanity_check(const struct lu_env *env,
          * before mdd_rename and enable MDS_PERM_BYPASS. */
         LASSERT(sobj);
 
-        if (mdd_is_dead_obj(sobj))
-                RETURN(-ESTALE);
-
         rc = mdd_may_delete(env, src_pobj, sobj, ma, 1, 0);
         if (rc)
                 RETURN(rc);
@@ -1986,7 +1975,8 @@ static int mdd_rename(const struct lu_env *env,
         unsigned int qspids[MAXQUOTAS] = { 0, 0 };
         unsigned int qtcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qtpids[MAXQUOTAS] = { 0, 0 };
-        int quota_opc = 0, rec_pending = 0;
+        int quota_copc = 0, quota_popc = 0;
+        int rec_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         ENTRY;
 
@@ -2009,13 +1999,12 @@ static int mdd_rename(const struct lu_env *env,
                                 if (!rc) {
                                         void *data = NULL;
                                         mdd_data_get(env, mdd_tpobj, &data);
-                                        quota_opc = FSFILT_OP_LINK;
+                                        quota_popc = FSFILT_OP_LINK;
                                         mdd_quota_wrapper(la_tmp, qtpids);
                                         /* get block quota for target parent */
                                         lquota_chkquota(mds_quota_interface_ref,
-                                                        obd, qtpids[USRQUOTA],
-                                                        qtpids[GRPQUOTA], 1,
-                                                        &rec_pending, NULL,
+                                                        obd, qtpids,
+                                                        rec_pending, 1, NULL,
                                                         LQUOTA_FLAGS_BLK,
                                                         data, 1);
                                 }
@@ -2068,12 +2057,12 @@ static int mdd_rename(const struct lu_env *env,
         /* "mv dir1 dir2" needs "dir1/.." link update */
         if (is_dir && mdd_sobj) {
                 rc = __mdd_index_delete_only(env, mdd_sobj, dotdot, handle,
-                                        mdd_object_capa(env, mdd_spobj));
+                                        mdd_object_capa(env, mdd_sobj));
                 if (rc)
                         GOTO(fixup_spobj2, rc);
 
                 rc = __mdd_index_insert_only(env, mdd_sobj, tpobj_fid, dotdot,
-                                      handle, mdd_object_capa(env, mdd_tpobj));
+                                      handle, mdd_object_capa(env, mdd_sobj));
                 if (rc) {
                         GOTO(fixup_spobj, rc);
                 }
@@ -2086,7 +2075,7 @@ static int mdd_rename(const struct lu_env *env,
         rc = __mdd_index_delete(env, mdd_tpobj, tname, is_dir, handle,
                                 mdd_object_capa(env, mdd_tpobj));
         if (rc != 0) {
-                if (mdd_tobj && mdd_object_exists(mdd_tobj)) {
+                if (mdd_tobj) {
                         /* tname might been renamed to something else */
                         GOTO(fixup_spobj, rc);
                 }
@@ -2098,7 +2087,7 @@ static int mdd_rename(const struct lu_env *env,
         rc = __mdd_index_insert(env, mdd_tpobj, lf, tname, is_dir, handle,
                                 mdd_object_capa(env, mdd_tpobj));
         if (rc)
-                GOTO(fixup_spobj, rc);
+                GOTO(fixup_tpobj, rc);
 
         LASSERT(ma->ma_attr.la_valid & LA_CTIME);
         la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
@@ -2145,7 +2134,7 @@ static int mdd_rename(const struct lu_env *env,
 #ifdef HAVE_QUOTA_SUPPORT
                 if (mds->mds_quota && ma->ma_valid & MA_INODE &&
                     ma->ma_attr.la_nlink == 0 && mdd_tobj->mod_count == 0) {
-                        quota_opc = FSFILT_OP_UNLINK_PARTIAL_CHILD;
+                        quota_copc = FSFILT_OP_UNLINK_PARTIAL_CHILD;
                         mdd_quota_wrapper(&ma->ma_attr, qtcids);
                 }
 #endif
@@ -2181,23 +2170,33 @@ static int mdd_rename(const struct lu_env *env,
 fixup_tpobj:
         if (rc) {
                 rc2 = __mdd_index_delete(env, mdd_tpobj, tname, is_dir, handle,
-                                         mdd_object_capa(env, mdd_tpobj));
+                                         BYPASS_CAPA);
                 if (rc2)
                         CWARN("tp obj fix error %d\n",rc2);
 
+                if (mdd_tobj && mdd_object_exists(mdd_tobj) &&
+                    !mdd_is_dead_obj(mdd_tobj)) {
+                        rc2 = __mdd_index_insert(env, mdd_tpobj,
+                                         mdo2fid(mdd_tobj), tname,
+                                         is_dir, handle,
+                                         BYPASS_CAPA);
+
+                        if (rc2)
+                                CWARN("tp obj fix error %d\n",rc2);
+                }
         }
+
 fixup_spobj:
         if (rc && is_dir && mdd_sobj) {
                 rc2 = __mdd_index_delete_only(env, mdd_sobj, dotdot, handle,
-                                mdd_object_capa(env, mdd_spobj));
+                                              BYPASS_CAPA);
 
                 if (rc2)
                         CWARN("sp obj dotdot delete error %d\n",rc2);
 
 
                 rc2 = __mdd_index_insert_only(env, mdd_sobj, spobj_fid,
-                                dotdot, handle,
-                                mdd_object_capa(env, mdd_spobj));
+                                              dotdot, handle, BYPASS_CAPA);
                 if (rc2)
                         CWARN("sp obj dotdot insert error %d\n",rc2);
         }
@@ -2205,8 +2204,7 @@ fixup_spobj:
 fixup_spobj2:
         if (rc) {
                 rc2 = __mdd_index_insert(env, mdd_spobj,
-                                         lf, sname, is_dir, handle,
-                                         mdd_object_capa(env, mdd_tpobj));
+                                         lf, sname, is_dir, handle, BYPASS_CAPA);
                 if (rc2)
                         CWARN("sp obj fix error %d\n",rc2);
         }
@@ -2229,22 +2227,23 @@ cleanup_unlocked:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
-                if (rec_pending)
+                if (quota_popc)
                         lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qtpids[USRQUOTA],
-                                              qtpids[GRPQUOTA],
-                                              rec_pending, 1);
-                /* Trigger dqrel on the source owner of parent.
-                 * If failed, the next call for lquota_chkquota will
-                 * process it. */
-                lquota_adjust(mds_quota_interface_ref, obd, 0, qspids, rc,
-                              FSFILT_OP_UNLINK_PARTIAL_PARENT);
-                if (quota_opc)
-                        /* Trigger dqrel/dqacq on the target owner of child and
-                         * parent. If failed, the next call for lquota_chkquota
+                                              qtpids, rec_pending, 1);
+
+                if (quota_copc) {
+                        /* Trigger dqrel on the source owner of parent.
+                         * If failed, the next call for lquota_chkquota will
+                         * process it. */
+                        lquota_adjust(mds_quota_interface_ref, obd, 0, qspids, rc,
+                                      FSFILT_OP_UNLINK_PARTIAL_PARENT);
+
+                        /* Trigger dqrel on the target owner of child.
+                         * If failed, the next call for lquota_chkquota
                          * will process it. */
                         lquota_adjust(mds_quota_interface_ref, obd, qtcids,
-                                      qtpids, rc, quota_opc);
+                                      qtpids, rc, quota_copc);
+                }
         }
 #endif
         return rc;