From 7e6a9068608cebf030a8376c47035e04096be4cd Mon Sep 17 00:00:00 2001 From: vitaly Date: Tue, 28 Apr 2009 17:31:19 +0000 Subject: [PATCH] Branch HEAD b=19154 i=zam i=rread properly protect filter_destroy() with a DLM lock --- lustre/obdfilter/filter.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index bdad15d..6463090 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -1575,9 +1575,8 @@ struct dentry *filter_fid2dentry(struct obd_device *obd, } static int filter_prepare_destroy(struct obd_device *obd, obd_id objid, - obd_id group) + obd_id group, struct lustre_handle *lockh) { - struct lustre_handle lockh; int flags = LDLM_AST_DISCARD_DATA, rc; struct ldlm_res_id res_id; ldlm_policy_data_t policy = { .l_extent = { 0, OBD_OBJECT_EOF } }; @@ -1589,15 +1588,19 @@ static int filter_prepare_destroy(struct obd_device *obd, obd_id objid, rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id, LDLM_EXTENT, &policy, LCK_PW, &flags, ldlm_blocking_ast, ldlm_completion_ast, NULL, NULL, 0, NULL, - NULL, &lockh); - - /* We only care about the side-effects, just drop the lock. */ - if (rc == ELDLM_OK) - ldlm_lock_decref(&lockh, LCK_PW); - + NULL, lockh); + if (rc != ELDLM_OK) + lockh->cookie = 0; RETURN(rc); } +static void filter_fini_destroy(struct obd_device *obd, + struct lustre_handle *lockh) +{ + if (lockh->cookie) + ldlm_lock_decref(lockh, LCK_PW); +} + /* This is vfs_unlink() without down(i_sem). If we call regular vfs_unlink() * we have 2.6 lock ordering issues with filter_commitrw_write() as it takes * i_sem before starting a handle, while filter_destroy() + vfs_unlink do the @@ -4023,6 +4026,7 @@ int filter_destroy(struct obd_export *exp, struct obdo *oa, struct obd_device *obd; struct filter_obd *filter; struct dentry *dchild = NULL, *dparent = NULL; + struct lustre_handle lockh = { 0 }; struct lvfs_run_ctxt saved; void *handle = NULL; struct llog_cookie *fcc = NULL; @@ -4075,7 +4079,7 @@ int filter_destroy(struct obd_export *exp, struct obdo *oa, GOTO(cleanup, rc = -ENOENT); } - filter_prepare_destroy(obd, oa->o_id, oa->o_gr); + filter_prepare_destroy(obd, oa->o_id, oa->o_gr, &lockh); /* Our MDC connection is established by the MDS to us */ if (oa->o_valid & OBD_MD_FLCOOKIE) { @@ -4171,6 +4175,8 @@ cleanup: case 3: filter_parent_unlock(dparent); case 2: + filter_fini_destroy(obd, &lockh); + f_dput(dchild); if (fcc != NULL) OBD_FREE(fcc, sizeof(*fcc)); -- 1.8.3.1