Whamcloud - gitweb
LU-12780 scrub: all update to bitfields must be protected.
[fs/lustre-release.git] / lustre / osd-zfs / osd_scrub.c
index 56a718b..9df6f74 100644 (file)
@@ -196,7 +196,10 @@ zget:
                        GOTO(out, rc);
                }
 
+               spin_lock(&scrub->os_lock);
                scrub->os_full_speed = 1;
+               spin_unlock(&scrub->os_lock);
+
                sf->sf_flags |= SF_INCONSISTENT;
        } else if (oid == oid2) {
                GOTO(out, rc = 0);
@@ -227,7 +230,9 @@ zget:
                }
 
 update:
+               spin_lock(&scrub->os_lock);
                scrub->os_full_speed = 1;
+               spin_unlock(&scrub->os_lock);
                sf->sf_flags |= SF_INCONSISTENT;
        }
 
@@ -304,6 +309,7 @@ static int osd_scrub_prep(const struct lu_env *env, struct osd_device *dev)
        if (flags & SS_RESET)
                scrub_file_reset(scrub, dev->od_uuid, 0);
 
+       spin_lock(&scrub->os_lock);
        scrub->os_partial_scan = 0;
        if (flags & SS_AUTO_FULL) {
                scrub->os_full_speed = 1;
@@ -315,7 +321,6 @@ static int osd_scrub_prep(const struct lu_env *env, struct osd_device *dev)
                scrub->os_full_speed = 0;
        }
 
-       spin_lock(&scrub->os_lock);
        scrub->os_in_prior = 0;
        scrub->os_waiting = 0;
        scrub->os_paused = 0;
@@ -414,7 +419,6 @@ osd_scrub_wakeup(struct lustre_scrub *scrub, struct osd_otable_it *it)
 static int osd_scrub_next(const struct lu_env *env, struct osd_device *dev,
                          struct lu_fid *fid, uint64_t *oid)
 {
-       struct l_wait_info lwi = { 0 };
        struct lustre_scrub *scrub = &dev->od_scrub;
        struct ptlrpc_thread *thread = &scrub->os_thread;
        struct osd_otable_it *it = dev->od_otable_it;
@@ -425,15 +429,14 @@ static int osd_scrub_next(const struct lu_env *env, struct osd_device *dev,
        ENTRY;
 
        if (OBD_FAIL_CHECK(OBD_FAIL_OSD_SCRUB_DELAY) && cfs_fail_val > 0) {
-               lwi = LWI_TIMEOUT(cfs_time_seconds(cfs_fail_val), NULL, NULL);
-               if (likely(lwi.lwi_timeout > 0)) {
-                       l_wait_event(thread->t_ctl_waitq,
-                               !list_empty(&scrub->os_inconsistent_items) ||
-                               !thread_is_running(thread),
-                               &lwi);
-                       if (unlikely(!thread_is_running(thread)))
-                               RETURN(SCRUB_NEXT_EXIT);
-               }
+               wait_event_idle_timeout(
+                       thread->t_ctl_waitq,
+                       !list_empty(&scrub->os_inconsistent_items) ||
+                       !thread_is_running(thread),
+                       cfs_time_seconds(cfs_fail_val));
+
+               if (unlikely(!thread_is_running(thread)))
+                       RETURN(SCRUB_NEXT_EXIT);
        }
 
        if (OBD_FAIL_CHECK(OBD_FAIL_OSD_SCRUB_CRASH)) {
@@ -470,12 +473,9 @@ again:
                spin_unlock(&scrub->os_lock);
        }
 
-       if (!scrub->os_full_speed && !osd_scrub_has_window(it)) {
-               memset(&lwi, 0, sizeof(lwi));
-               l_wait_event(thread->t_ctl_waitq,
-                            osd_scrub_wakeup(scrub, it),
-                            &lwi);
-       }
+       if (!scrub->os_full_speed && !osd_scrub_has_window(it))
+               wait_event_idle(thread->t_ctl_waitq,
+                               osd_scrub_wakeup(scrub, it));
 
        if (unlikely(!thread_is_running(thread)))
                GOTO(out, rc = SCRUB_NEXT_EXIT);
@@ -543,7 +543,9 @@ static int osd_scrub_exec(const struct lu_env *env, struct osd_device *dev,
                        spin_unlock(&scrub->os_lock);
                }
        } else {
+               spin_lock(&scrub->os_lock);
                scrub->os_in_prior = 0;
+               spin_unlock(&scrub->os_lock);
        }
 
        if (rc)
@@ -585,12 +587,12 @@ static int osd_scrub_main(void *args)
        }
 
        if (!scrub->os_full_speed) {
-               struct l_wait_info lwi = { 0 };
                struct osd_otable_it *it = dev->od_otable_it;
 
-               l_wait_event(thread->t_ctl_waitq,
-                            it->ooi_user_ready || !thread_is_running(thread),
-                            &lwi);
+               wait_event_idle(thread->t_ctl_waitq,
+                               it->ooi_user_ready ||
+                               !thread_is_running(thread));
+
                if (unlikely(!thread_is_running(thread)))
                        GOTO(post, rc = 0);
 
@@ -1273,8 +1275,7 @@ static int osd_ios_ROOT_sd(const struct lu_env *env, struct osd_device *dev,
                                    sizeof(*zde) / 8, (void *)zde);
                if (rc) {
                        if (rc != -ENOENT)
-                               CWARN("%s: initial OI scrub failed to find"
-                                     "the entry %s under .lustre: rc = %d\n",
+                               CWARN("%s: initial OI scrub failed to find the entry %s under .lustre: rc = %d\n",
                                      osd_name(dev), map->olm_name, rc);
                        else if (!fid_is_zero(&map->olm_fid))
                                /* Try to remove the stale OI mapping. */
@@ -1394,7 +1395,9 @@ void osd_scrub_stop(struct osd_device *dev)
 
        /* od_otable_sem: prevent concurrent start/stop */
        down(&dev->od_otable_sem);
+       spin_lock(&scrub->os_lock);
        scrub->os_paused = 1;
+       spin_unlock(&scrub->os_lock);
        scrub_stop(scrub);
        up(&dev->od_otable_sem);
 
@@ -1417,7 +1420,7 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev)
        bool dirty = false;
        ENTRY;
 
-       memcpy(dev->od_uuid,
+       memcpy(dev->od_uuid.b,
               &dsl_dataset_phys(dev->od_os->os_dsl_dataset)->ds_guid,
               sizeof(dsl_dataset_phys(dev->od_os->os_dsl_dataset)->ds_guid));
        memset(&dev->od_scrub, 0, sizeof(struct lustre_scrub));
@@ -1457,30 +1460,12 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev)
        } else if (rc < 0) {
                GOTO(cleanup_obj, rc);
        } else {
-               if (memcmp(sf->sf_uuid, dev->od_uuid, 16) != 0) {
-                       struct obd_uuid *old_uuid;
-                       struct obd_uuid *new_uuid;
-
-                       OBD_ALLOC_PTR(old_uuid);
-                       OBD_ALLOC_PTR(new_uuid);
-                       if (!old_uuid || !new_uuid) {
-                               CERROR("%s: UUID has been changed, but"
-                                      "failed to allocate RAM for report\n",
-                                      osd_name(dev));
-                       } else {
-                               snprintf(old_uuid->uuid, UUID_SIZE, "%pU", sf->sf_uuid);
-                               snprintf(new_uuid->uuid, UUID_SIZE, "%pU", dev->od_uuid);
-                               CDEBUG(D_LFSCK,
-                                      "%s: UUID has been changed from %s to %s\n",
-                                      osd_name(dev),
-                                      old_uuid->uuid, new_uuid->uuid);
-                       }
+               if (!uuid_equal(&sf->sf_uuid, &dev->od_uuid)) {
+                       CDEBUG(D_LFSCK,
+                              "%s: UUID has been changed from %pU to %pU\n",
+                              osd_name(dev), &sf->sf_uuid, &dev->od_uuid);
                        scrub_file_reset(scrub, dev->od_uuid, SF_INCONSISTENT);
                        dirty = true;
-                       if (old_uuid)
-                               OBD_FREE_PTR(old_uuid);
-                       if (new_uuid)
-                               OBD_FREE_PTR(new_uuid);
                } else if (sf->sf_status == SS_SCANNING) {
                        sf->sf_status = SS_CRASHED;
                        dirty = true;
@@ -1700,11 +1685,10 @@ static int osd_otable_it_next(const struct lu_env *env, struct dt_it *di)
        struct osd_device *dev = it->ooi_dev;
        struct lustre_scrub *scrub = &dev->od_scrub;
        struct ptlrpc_thread *thread = &scrub->os_thread;
-       struct l_wait_info lwi = { 0 };
        struct lustre_mdt_attrs *lma = NULL;
        nvlist_t *nvbuf = NULL;
-       int size = 0;
-       int rc;
+       int rc, size = 0;
+       bool locked;
        ENTRY;
 
        LASSERT(it->ooi_user_ready);
@@ -1722,9 +1706,8 @@ again:
        }
 
        if (it->ooi_pos >= scrub->os_pos_current)
-               l_wait_event(thread->t_ctl_waitq,
-                            osd_otable_it_wakeup(scrub, it),
-                            &lwi);
+               wait_event_idle(thread->t_ctl_waitq,
+                               osd_otable_it_wakeup(scrub, it));
 
        if (!thread_is_running(thread) && !it->ooi_used_outside)
                GOTO(out, rc = 1);
@@ -1741,16 +1724,20 @@ again:
 
        rc = __osd_xattr_load_by_oid(dev, it->ooi_pos, &nvbuf);
 
-       if (!scrub->os_full_speed)
+       locked = false;
+       if (!scrub->os_full_speed) {
                spin_lock(&scrub->os_lock);
+               locked = true;
+       }
        it->ooi_prefetched--;
        if (!scrub->os_full_speed) {
                if (scrub->os_waiting) {
                        scrub->os_waiting = 0;
                        wake_up_all(&thread->t_ctl_waitq);
                }
-               spin_unlock(&scrub->os_lock);
        }
+       if (locked)
+               spin_unlock(&scrub->os_lock);
 
        if (rc == -ENOENT || rc == -EEXIST || rc == -ENODATA)
                goto again;