1111 *
1212 *
1313 * IDENTIFICATION
14- * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.84 2004/12/31 22:01:13 pgsql Exp $
14+ * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.85 2005/01/10 20:02:22 tgl Exp $
1515 *
1616 *-------------------------------------------------------------------------
1717 */
@@ -216,6 +216,7 @@ smgropen(RelFileNode rnode)
216216if (!found )
217217{
218218/* hash_search already filled in the lookup key */
219+ reln -> smgr_owner = NULL ;
219220reln -> smgr_which = 0 ;/* we only have md.c at present */
220221reln -> md_fd = NULL ;/* mark it not open */
221222}
@@ -224,15 +225,36 @@ smgropen(RelFileNode rnode)
224225}
225226
226227/*
227- *smgrclose () --Close and delete an SMgrRelation object.
228+ * smgrsetowner () --Establish a long-lived reference to an SMgrRelation object
228229 *
229- * It is the caller's responsibility not to leave any dangling references
230- * to the object. (Pointers should be cleared after successful return;
231- * on the off chance of failure, the SMgrRelation object will still exist.)
230+ * There can be only one owner at a time; this is sufficient since currently
231+ * the only such owners exist in the relcache.
232+ */
233+ void
234+ smgrsetowner (SMgrRelation * owner ,SMgrRelation reln )
235+ {
236+ /*
237+ * First, unhook any old owner. (Normally there shouldn't be any, but
238+ * it seems possible that this can happen during swap_relation_files()
239+ * depending on the order of processing. It's ok to close the old
240+ * relcache entry early in that case.)
241+ */
242+ if (reln -> smgr_owner )
243+ * (reln -> smgr_owner )= NULL ;
244+
245+ /* Now establish the ownership relationship. */
246+ reln -> smgr_owner = owner ;
247+ * owner = reln ;
248+ }
249+
250+ /*
251+ *smgrclose() -- Close and delete an SMgrRelation object.
232252 */
233253void
234254smgrclose (SMgrRelation reln )
235255{
256+ SMgrRelation * owner ;
257+
236258if (!(* (smgrsw [reln -> smgr_which ].smgr_close )) (reln ))
237259ereport (ERROR ,
238260(errcode_for_file_access (),
@@ -241,16 +263,24 @@ smgrclose(SMgrRelation reln)
241263reln -> smgr_rnode .dbNode ,
242264reln -> smgr_rnode .relNode )));
243265
266+ owner = reln -> smgr_owner ;
267+
244268if (hash_search (SMgrRelationHash ,
245269(void * )& (reln -> smgr_rnode ),
246270HASH_REMOVE ,NULL )== NULL )
247271elog (ERROR ,"SMgrRelation hashtable corrupted" );
272+
273+ /*
274+ * Unhook the owner pointer, if any. We do this last since in the
275+ * remote possibility of failure above, the SMgrRelation object will still
276+ * exist.
277+ */
278+ if (owner )
279+ * owner = NULL ;
248280}
249281
250282/*
251283 *smgrcloseall() -- Close all existing SMgrRelation objects.
252- *
253- * It is the caller's responsibility not to leave any dangling references.
254284 */
255285void
256286smgrcloseall (void )
@@ -275,8 +305,6 @@ smgrcloseall(void)
275305 * This has the same effects as smgrclose(smgropen(rnode)), but it avoids
276306 * uselessly creating a hashtable entry only to drop it again when no
277307 * such entry exists already.
278- *
279- * It is the caller's responsibility not to leave any dangling references.
280308 */
281309void
282310smgrclosenode (RelFileNode rnode )