From de73bdafb0e0ab187865dcdcc76c0f48e1b5239e Mon Sep 17 00:00:00 2001 From: wang di Date: Thu, 16 Jan 2014 15:26:56 -0800 Subject: [PATCH] LU-4456 osp: extra check for opd_pre 1. Add extra check for opd_pre in statfs_interpret, in case opd_pre has been freed before the callback. 2. switch the sync_fini and pre_fini, so opd_pre will be freed after all of the possible access has been stopped. 3. opd_pre_waitq will be accessed in several update threads, osp_precreate, osp_statfs_timer_cb, statfs_interrupt, move it to osp_device to make sure it is accessiable even after osp_pre is freed. Signed-off-by: wang di Change-Id: I5c73cb52e2406ed03570fc3471111c409e6fe08f Reviewed-on: http://review.whamcloud.com/8890 Tested-by: Jenkins Reviewed-by: Alex Zhuravlev Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/osp/osp_dev.c | 6 +++--- lustre/osp/osp_internal.h | 5 ++--- lustre/osp/osp_precreate.c | 40 +++++++++++++++++++++------------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/lustre/osp/osp_dev.c b/lustre/osp/osp_dev.c index 819338b..5828d88 100644 --- a/lustre/osp/osp_dev.c +++ b/lustre/osp/osp_dev.c @@ -352,12 +352,12 @@ static int osp_shutdown(const struct lu_env *env, struct osp_device *d) rc = osp_disconnect(d); if (!d->opd_connect_mdt) { - /* stop precreate thread */ - osp_precreate_fini(d); - /* stop sync thread */ osp_sync_fini(d); + /* stop precreate thread */ + osp_precreate_fini(d); + /* release last_used file */ osp_last_used_fini(env, d); } diff --git a/lustre/osp/osp_internal.h b/lustre/osp/osp_internal.h index 025a249..0871d8da 100644 --- a/lustre/osp/osp_internal.h +++ b/lustre/osp/osp_internal.h @@ -77,8 +77,6 @@ struct osp_precreate { struct lu_fid osp_pre_last_created_fid; /* how many ids are reserved in declare, we shouldn't block in create */ __u64 osp_pre_reserved; - /* thread waits for signals about pool going empty */ - wait_queue_head_t osp_pre_waitq; /* consumers (who needs new ids) wait here */ wait_queue_head_t osp_pre_user_waitq; /* current precreation status: working, failed, stopping? */ @@ -137,6 +135,8 @@ struct osp_device { struct osp_precreate *opd_pre; /* dedicate precreate thread */ struct ptlrpc_thread opd_pre_thread; + /* thread waits for signals about pool going empty */ + wait_queue_head_t opd_pre_waitq; /* * OST synchronization @@ -190,7 +190,6 @@ struct osp_device { #define opd_pre_used_fid opd_pre->osp_pre_used_fid #define opd_pre_last_created_fid opd_pre->osp_pre_last_created_fid #define opd_pre_reserved opd_pre->osp_pre_reserved -#define opd_pre_waitq opd_pre->osp_pre_waitq #define opd_pre_user_waitq opd_pre->osp_pre_user_waitq #define opd_pre_status opd_pre->osp_pre_status #define opd_pre_grow_count opd_pre->osp_pre_grow_count diff --git a/lustre/osp/osp_precreate.c b/lustre/osp/osp_precreate.c index 22a1060..574cd0d 100644 --- a/lustre/osp/osp_precreate.c +++ b/lustre/osp/osp_precreate.c @@ -65,12 +65,29 @@ static inline int osp_statfs_need_update(struct osp_device *d) d->opd_statfs_fresh_till); } +/* + * OSP tries to maintain pool of available objects so that calls to create + * objects don't block most of time + * + * each time OSP gets connected to OST, we should start from precreation cleanup + */ +static inline bool osp_precreate_running(struct osp_device *d) +{ + return !!(d->opd_pre_thread.t_flags & SVC_RUNNING); +} + +static inline bool osp_precreate_stopped(struct osp_device *d) +{ + return !!(d->opd_pre_thread.t_flags & SVC_STOPPED); +} + static void osp_statfs_timer_cb(unsigned long _d) { struct osp_device *d = (struct osp_device *) _d; LASSERT(d); - wake_up(&d->opd_pre_waitq); + if (d->opd_pre != NULL && osp_precreate_running(d)) + wake_up(&d->opd_pre_waitq); } static int osp_statfs_interpret(const struct lu_env *env, @@ -108,7 +125,9 @@ static int osp_statfs_interpret(const struct lu_env *env, RETURN(0); out: /* couldn't update statfs, try again as soon as possible */ - wake_up(&d->opd_pre_waitq); + if (d->opd_pre != NULL && osp_precreate_running(d)) + wake_up(&d->opd_pre_waitq); + if (req->rq_import_generation == imp->imp_generation) CDEBUG(D_CACHE, "%s: couldn't update statfs: rc = %d\n", d->opd_obd->obd_name, rc); @@ -178,23 +197,6 @@ void osp_statfs_need_now(struct osp_device *d) } } - -/* - * OSP tries to maintain pool of available objects so that calls to create - * objects don't block most of time - * - * each time OSP gets connected to OST, we should start from precreation cleanup - */ -static inline int osp_precreate_running(struct osp_device *d) -{ - return !!(d->opd_pre_thread.t_flags & SVC_RUNNING); -} - -static inline int osp_precreate_stopped(struct osp_device *d) -{ - return !!(d->opd_pre_thread.t_flags & SVC_STOPPED); -} - static inline int osp_objs_precreated(const struct lu_env *env, struct osp_device *osp) { -- 1.8.3.1