Whamcloud - gitweb
Branch HEAD
authorvitaly <vitaly>
Tue, 28 Apr 2009 17:31:19 +0000 (17:31 +0000)
committervitaly <vitaly>
Tue, 28 Apr 2009 17:31:19 +0000 (17:31 +0000)
b=19154
i=zam
i=rread

properly protect filter_destroy() with a DLM lock

lustre/obdfilter/filter.c

index bdad15d..6463090 100644 (file)
@@ -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));