Whamcloud - gitweb
b=20468
authoranserper <anserper>
Mon, 28 Sep 2009 15:01:31 +0000 (15:01 +0000)
committeranserper <anserper>
Mon, 28 Sep 2009 15:01:31 +0000 (15:01 +0000)
i=Johann Lombardi
i=ZhiYong Tian

make reading/setting versions atomic

lustre/quota/lproc_quota.c
lustre/quota/quota_internal.h
lustre/quota/quota_master.c

index ee20213..69b3f1c 100644 (file)
@@ -203,13 +203,12 @@ int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,
 
         /* Collect the needed information */
         oq_type = obd->u.obt.obt_qctxt.lqc_flags;
-        oq_version = obt->obt_qfmt;
         if (is_mds) {
-                rc = mds_quota_get_version(obd, &aq_version);
+                rc = mds_quota_get_version(obd, &aq_version, &oq_version);
                 if (rc)
                         return -EPROTO;
-                /* Here we can also assert that aq_type == oq_type
-                 * except for quota startup/shutdown states     */
+        } else {
+                oq_version = obt->obt_qfmt;
         }
 
         /* Transform the collected data into a user-readable string */
@@ -391,19 +390,22 @@ int lprocfs_quota_wr_type(struct file *file, const char *buffer,
                                 return -EINVAL;
 #endif
                         if (is_mds) {
-                                rc = mds_quota_set_version(obd, s2av[idx]);
+                                rc = mds_quota_set_version(obd, s2av[idx],
+                                                           s2ov[idx]);
                                 if (rc) {
                                         CDEBUG(D_QUOTA, "failed to set admin "
                                                "quota to spec %c! %d\n",
                                                stype[i], rc);
                                         return rc;
                                 }
-                        }
-                        rc = filter_quota_set_version(obd, s2ov[idx]);
-                        if (rc) {
-                                CDEBUG(D_QUOTA, "failed to set operational quota"
-                                       " to spec %c! %d\n", stype[i], rc);
-                                return rc;
+                        } else {
+                                rc = filter_quota_set_version(obd, s2ov[idx]);
+                                if (rc) {
+                                        CDEBUG(D_QUOTA, "failed to set op"
+                                               " quota to spec %c! %d\n",
+                                               stype[i], rc);
+                                        return rc;
+                                }
                         }
                         break;
                 default  : /* just skip stray symbols like \n */
index bf07ecf..b36f044 100644 (file)
@@ -127,8 +127,10 @@ int mds_quota_adjust(struct obd_device *obd, unsigned int qcids[],
 int filter_quota_adjust(struct obd_device *obd, unsigned int qcids[],
                         unsigned int qpids[], int rc, int opc);
 int init_admin_quotafiles(struct obd_device *obd, struct obd_quotactl *oqctl);
-int mds_quota_get_version(struct obd_device *obd, lustre_quota_version_t *ver);
-int mds_quota_set_version(struct obd_device *obd, lustre_quota_version_t ver);
+int mds_quota_get_version(struct obd_device *obd, lustre_quota_version_t *aver,
+                          lustre_quota_version_t *over);
+int mds_quota_set_version(struct obd_device *obd, lustre_quota_version_t aver,
+                          lustre_quota_version_t over);
 int mds_quota_invalidate(struct obd_device *obd, struct obd_quotactl *oqctl);
 int mds_quota_finvalidate(struct obd_device *obd, struct obd_quotactl *oqctl);
 
index 9d47053..6b5cede 100644 (file)
@@ -555,46 +555,67 @@ int filter_quota_adjust(struct obd_device *obd, unsigned int qcids[],
 static const char prefix[] = "OBJECTS/";
 
 int mds_quota_get_version(struct obd_device *obd,
-                          lustre_quota_version_t *version)
+                          lustre_quota_version_t *aver,
+                          lustre_quota_version_t *over)
 {
         struct mds_obd *mds = &obd->u.mds;
         struct lustre_quota_info *qinfo = &mds->mds_quota_info;
 
-        *version = qinfo->qi_version;
+        if (!atomic_dec_and_test(&mds->mds_obt.obt_quotachecking)) {
+                CDEBUG(D_INFO, "other people are doing quotacheck\n");
+                atomic_inc(&mds->mds_obt.obt_quotachecking);
+                RETURN(-EBUSY);
+        }
+        down(&mds->mds_qonoff_sem);
+
+        *aver = qinfo->qi_version;
+        *over = mds->mds_obt.obt_qfmt;
+
+        up(&mds->mds_qonoff_sem);
+        atomic_inc(&mds->mds_obt.obt_quotachecking);
 
         return 0;
 }
 
-int mds_quota_set_version(struct obd_device *obd, lustre_quota_version_t version)
+int mds_quota_set_version(struct obd_device *obd,
+                          lustre_quota_version_t aver,
+                          lustre_quota_version_t over)
 {
         struct mds_obd *mds = &obd->u.mds;
         struct lustre_quota_info *qinfo = &mds->mds_quota_info;
         int rc = 0, i;
 
-        if (version != LUSTRE_QUOTA_V1 && version != LUSTRE_QUOTA_V2)
-                return -EINVAL;
+        LASSERT(aver == LUSTRE_QUOTA_V1 || aver == LUSTRE_QUOTA_V2);
+        LASSERT(over == LUSTRE_QUOTA_V1 || over == LUSTRE_QUOTA_V2);
+
+        if (!atomic_dec_and_test(&mds->mds_obt.obt_quotachecking)) {
+                CDEBUG(D_INFO, "other people are doing quotacheck\n");
+                atomic_inc(&mds->mds_obt.obt_quotachecking);
+                RETURN(-EBUSY);
+        }
 
         down(&mds->mds_qonoff_sem);
 
         /* no need to change version? nothing to do then */
-        if (qinfo->qi_version == version)
-                goto out;
-
-        for (i = 0; i < MAXQUOTAS; i++) {
-                /* quota file has been opened ? */
-                if (qinfo->qi_files[i]) {
-                        rc = -EBUSY;
-                        goto out;
+        if (qinfo->qi_version != aver) {
+                for (i = 0; i < MAXQUOTAS; i++) {
+                        /* quota file has been opened ? */
+                        if (qinfo->qi_files[i]) {
+                                rc = -EBUSY;
+                                goto out;
+                        }
                 }
-        }
 
-        CDEBUG(D_INFO, "changing quota version %d -> %d\n", qinfo->qi_version,
-               version);
+                CDEBUG(D_INFO, "changing quota version %d -> %d\n",
+                       qinfo->qi_version, aver);
+                qinfo->qi_version = aver;
+        }
 
-        qinfo->qi_version = version;
+        mds->mds_obt.obt_qfmt = over;
 
 out:
         up(&mds->mds_qonoff_sem);
+        atomic_inc(&mds->mds_obt.obt_quotachecking);
 
         return rc;
 }