X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Fscrub.c;h=c9852a69ab645883567ad76d4206330323566204;hb=cda353e6efae5013a26aedbe49d8aa6fb8fe456e;hp=c828bb6197272505246296f521ebdb30493e1ef2;hpb=90fd0cd449b9ae3fbff5a99e0edcf288799037c0;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/scrub.c b/lustre/obdclass/scrub.c index c828bb6..c9852a6 100644 --- a/lustre/obdclass/scrub.c +++ b/lustre/obdclass/scrub.c @@ -41,7 +41,8 @@ static inline struct dt_device *scrub_obj2dev(struct dt_object *obj) { - return container_of0(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev); + return container_of_safe(obj->do_lu.lo_dev, struct dt_device, + dd_lu_dev); } static void scrub_file_to_cpu(struct scrub_file *des, struct scrub_file *src) @@ -274,28 +275,12 @@ EXPORT_SYMBOL(scrub_checkpoint); int scrub_start(int (*threadfn)(void *data), struct lustre_scrub *scrub, void *data, __u32 flags) { - struct ptlrpc_thread *thread = &scrub->os_thread; - struct l_wait_info lwi = { 0 }; struct task_struct *task; int rc; ENTRY; -again: - /* os_lock: sync status between stop and scrub thread */ - spin_lock(&scrub->os_lock); - if (thread_is_running(thread)) { - spin_unlock(&scrub->os_lock); + if (scrub->os_task) RETURN(-EALREADY); - } - - if (unlikely(thread_is_stopping(thread))) { - spin_unlock(&scrub->os_lock); - l_wait_event(thread->t_ctl_waitq, - thread_is_stopped(thread), - &lwi); - goto again; - } - spin_unlock(&scrub->os_lock); if (scrub->os_file.sf_status == SS_COMPLETED) { if (!(flags & SS_SET_FAILOUT)) @@ -307,19 +292,25 @@ again: flags |= SS_RESET; } - scrub->os_start_flags = flags; - thread_set_flags(thread, 0); - task = kthread_run(threadfn, data, "OI_scrub"); + task = kthread_create(threadfn, data, "OI_scrub"); if (IS_ERR(task)) { rc = PTR_ERR(task); CERROR("%s: cannot start iteration thread: rc = %d\n", scrub->os_name, rc); RETURN(rc); } - - l_wait_event(thread->t_ctl_waitq, - thread_is_running(thread) || thread_is_stopped(thread), - &lwi); + spin_lock(&scrub->os_lock); + if (scrub->os_task) { + /* Lost a race */ + spin_unlock(&scrub->os_lock); + kthread_stop(task); + RETURN(-EALREADY); + } + scrub->os_start_flags = flags; + scrub->os_task = task; + wake_up_process(task); + spin_unlock(&scrub->os_lock); + wait_var_event(scrub, scrub->os_running || !scrub->os_task); RETURN(0); } @@ -327,23 +318,14 @@ EXPORT_SYMBOL(scrub_start); void scrub_stop(struct lustre_scrub *scrub) { - struct ptlrpc_thread *thread = &scrub->os_thread; - struct l_wait_info lwi = { 0 }; + struct task_struct *task; - /* os_lock: sync status between stop and scrub thread */ spin_lock(&scrub->os_lock); - if (!thread_is_init(thread) && !thread_is_stopped(thread)) { - thread_set_flags(thread, SVC_STOPPING); - spin_unlock(&scrub->os_lock); - wake_up_all(&thread->t_ctl_waitq); - l_wait_event(thread->t_ctl_waitq, - thread_is_stopped(thread), - &lwi); - /* Do not skip the last lock/unlock, which can guarantee that - * the caller cannot return until the OI scrub thread exit. */ - spin_lock(&scrub->os_lock); - } + scrub->os_running = 0; spin_unlock(&scrub->os_lock); + task = xchg(&scrub->os_task, NULL); + if (task) + kthread_stop(task); } EXPORT_SYMBOL(scrub_stop); @@ -380,7 +362,7 @@ static void scrub_bits_dump(struct seq_file *m, int bits, const char *names[], seq_printf(m, "%s:%c", prefix, bits != 0 ? ' ' : '\n'); - for (i = 0, flag = 1; bits != 0; i++, flag = 1 << i) { + for (i = 0, flag = 1; bits != 0; i++, flag = BIT(i)) { if (flag & bits) { bits &= ~flag; seq_printf(m, "%s%c", names[i], @@ -459,7 +441,7 @@ void scrub_dump(struct seq_file *m, struct lustre_scrub *scrub) sf->sf_items_igif, sf->sf_success_count); speed = checked; - if (thread_is_running(&scrub->os_thread)) { + if (scrub->os_running) { s64 new_checked = scrub->os_new_checked; time64_t duration; time64_t rtime; @@ -479,7 +461,7 @@ void scrub_dump(struct seq_file *m, struct lustre_scrub *scrub) seq_printf(m, "run_time: %lld seconds\n" "average_speed: %lld objects/sec\n" - "real-time_speed: %lld objects/sec\n" + "real_time_speed: %lld objects/sec\n" "current_position: %llu\n" "scrub_in_prior: %s\n" "scrub_full_speed: %s\n" @@ -492,9 +474,9 @@ void scrub_dump(struct seq_file *m, struct lustre_scrub *scrub) } else { if (sf->sf_run_time != 0) speed = div_s64(speed, sf->sf_run_time); - seq_printf(m, "run_time: %ld seconds\n" + seq_printf(m, "run_time: %d seconds\n" "average_speed: %lld objects/sec\n" - "real-time_speed: N/A\n" + "real_time_speed: N/A\n" "current_position: N/A\n", sf->sf_run_time, speed); }