Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / mdd / mdd_dir.c
index f00d307..03a9e86 100644 (file)
@@ -675,12 +675,15 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj,
 
                 rc = mdd_la_get(env, mdd_tobj, la_tmp, BYPASS_CAPA);
                 if (!rc) {
+                        void *data = NULL;
+                        mdd_data_get(env, mdd_tobj, &data);
                         quota_opc = FSFILT_OP_LINK;
                         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);
+                                        &rec_pending, NULL, LQUOTA_FLAGS_BLK,
+                                        data, 1);
                 }
         }
 #endif
@@ -735,7 +738,7 @@ out_pending:
                 if (rec_pending)
                         lquota_pending_commit(mds_quota_interface_ref, obd,
                                               qids[USRQUOTA], qids[GRPQUOTA],
-                                              1, 1);
+                                              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,
@@ -959,13 +962,15 @@ static int mdd_name_insert(const struct lu_env *env,
 
                         rc = mdd_la_get(env, mdd_obj, la_tmp, BYPASS_CAPA);
                         if (!rc) {
+                                void *data = NULL;
+                                mdd_data_get(env, mdd_obj, &data);
                                 quota_opc = FSFILT_OP_LINK;
                                 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);
+                                                LQUOTA_FLAGS_BLK, data, 1);
                         }
                 } else {
                         uc->mu_cap |= CFS_CAP_SYS_RESOURCE_MASK;
@@ -1014,7 +1019,8 @@ out_pending:
                         if (rec_pending)
                                 lquota_pending_commit(mds_quota_interface_ref,
                                                       obd, qids[USRQUOTA],
-                                                      qids[GRPQUOTA], 1, 1);
+                                                      qids[GRPQUOTA],
+                                                      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,
@@ -1182,12 +1188,15 @@ static int mdd_rename_tgt(const struct lu_env *env,
 
                 rc = mdd_la_get(env, mdd_tpobj, la_tmp, BYPASS_CAPA);
                 if (!rc) {
+                        void *data = NULL;
+                        mdd_data_get(env, mdd_tpobj, &data);
                         quota_opc = 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);
+                                        &rec_pending, NULL, LQUOTA_FLAGS_BLK,
+                                        data, 1);
                 }
         }
 #endif
@@ -1276,7 +1285,7 @@ out_pending:
                         lquota_pending_commit(mds_quota_interface_ref, obd,
                                               qpids[USRQUOTA],
                                               qpids[GRPQUOTA],
-                                              1, 1);
+                                              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
@@ -1636,7 +1645,7 @@ static int mdd_create(const struct lu_env *env,
                         /* get file quota for child */
                         lquota_chkquota(mds_quota_interface_ref, obd,
                                         qcids[USRQUOTA], qcids[GRPQUOTA], 1,
-                                        &inode_pending, NULL, 0);
+                                        &inode_pending, NULL, 0, NULL, 0);
                         switch (ma->ma_attr.la_mode & S_IFMT) {
                         case S_IFLNK:
                         case S_IFDIR:
@@ -1657,12 +1666,12 @@ static int mdd_create(const struct lu_env *env,
                                                 qcids[USRQUOTA], qcids[GRPQUOTA],
                                                 block_count,
                                                 &block_pending, NULL,
-                                                LQUOTA_FLAGS_BLK);
+                                                LQUOTA_FLAGS_BLK, NULL, 0);
                         if (!same)
                                 lquota_chkquota(mds_quota_interface_ref, obd,
                                                 qpids[USRQUOTA], qpids[GRPQUOTA], 1,
                                                 &parent_pending, NULL,
-                                                LQUOTA_FLAGS_BLK);
+                                                LQUOTA_FLAGS_BLK, NULL, 0);
                 }
         }
 #endif
@@ -1834,15 +1843,15 @@ out_pending:
                 if (inode_pending)
                         lquota_pending_commit(mds_quota_interface_ref, obd,
                                               qcids[USRQUOTA], qcids[GRPQUOTA],
-                                              1, 0);
+                                              inode_pending, 0);
                 if (block_pending)
                         lquota_pending_commit(mds_quota_interface_ref, obd,
                                               qcids[USRQUOTA], qcids[GRPQUOTA],
-                                              block_count, 1);
+                                              block_pending, 1);
                 if (parent_pending)
                         lquota_pending_commit(mds_quota_interface_ref, obd,
                                               qpids[USRQUOTA], qpids[GRPQUOTA],
-                                              1, 1);
+                                              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,
@@ -1982,6 +1991,8 @@ static int mdd_rename(const struct lu_env *env,
                                 rc = mdd_la_get(env, mdd_tpobj, la_tmp,
                                                 BYPASS_CAPA);
                                 if (!rc) {
+                                        void *data = NULL;
+                                        mdd_data_get(env, mdd_tpobj, &data);
                                         quota_opc = FSFILT_OP_LINK;
                                         mdd_quota_wrapper(la_tmp, qtpids);
                                         /* get block quota for target parent */
@@ -1989,7 +2000,8 @@ static int mdd_rename(const struct lu_env *env,
                                                         obd, qtpids[USRQUOTA],
                                                         qtpids[GRPQUOTA], 1,
                                                         &rec_pending, NULL,
-                                                        LQUOTA_FLAGS_BLK);
+                                                        LQUOTA_FLAGS_BLK,
+                                                        data, 1);
                                 }
                         }
                 }
@@ -2159,7 +2171,7 @@ out_pending:
                         lquota_pending_commit(mds_quota_interface_ref, obd,
                                               qtpids[USRQUOTA],
                                               qtpids[GRPQUOTA],
-                                              1, 1);
+                                              rec_pending, 1);
                 /* Trigger dqrel on the source owner of parent.
                  * If failed, the next call for lquota_chkquota will
                  * process it. */
@@ -2225,6 +2237,8 @@ struct lu_buf *mdd_links_get(const struct lu_env *env,
         }
         if (leh->leh_magic != LINK_EA_MAGIC)
                 return ERR_PTR(-EINVAL);
+        if (leh->leh_reccount == 0)
+                return ERR_PTR(-ENODATA);
 
         return buf;
 }
@@ -2278,8 +2292,7 @@ static int __mdd_links_add(const struct lu_env *env, struct lu_buf *buf,
         leh = buf->lb_buf;
         reclen = lname->ln_namelen + sizeof(struct link_ea_entry);
         if (leh->leh_len + reclen > buf->lb_len) {
-                mdd_buf_grow(env, leh->leh_len + reclen);
-                if (buf->lb_buf == NULL)
+                if (mdd_buf_grow(env, leh->leh_len + reclen) < 0)
                         return -ENOMEM;
         }
 
@@ -2366,7 +2379,8 @@ static int mdd_links_rename(const struct lu_env *env,
         struct lu_name *tmpname = &mdd_env_info(env)->mti_name;
         struct lu_fid  *tmpfid = &mdd_env_info(env)->mti_fid;
         int reclen = 0;
-        int rc, count;
+        int count;
+        int rc, rc2 = 0;
         ENTRY;
 
         if (!mdd_linkea_enable)
@@ -2410,9 +2424,8 @@ static int mdd_links_rename(const struct lu_env *env,
 
         /* If renaming, add the new record */
         if (newpfid != NULL) {
-                rc = __mdd_links_add(env, buf, newpfid, newlname);
-                if (rc)
-                        GOTO(out, rc);
+                /* if the add fails, we still delete the out-of-date old link */
+                rc2 = __mdd_links_add(env, buf, newpfid, newlname);
                 leh = buf->lb_buf;
         }
 
@@ -2421,6 +2434,8 @@ static int mdd_links_rename(const struct lu_env *env,
                              XATTR_NAME_LINK, 0, handle);
 
 out:
+        if (rc == 0)
+                rc = rc2;
         if (rc)
                 CDEBUG(D_INODE, "link_ea mv/unlink '%.*s' failed %d "DFID"\n",
                        oldlname->ln_namelen, oldlname->ln_name, rc,