Check-in [fce4e23351]

Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1 Hash:fce4e233516637ce17dd198e437016e8a5c211ee
Date: 2009-06-15 20:32:21
User: stephan
Comment:fixed part of a small memleak when an fs is closed while inodes are still held open. To fix the second part (leaked whefs_fs or whio_dev objects) we need to track those in an is-opened list like we do inodes (but that's a bummer).
Tags And Properties
Changes
hide diffs unified diffs patch

Changes to whefs_fs.c

Old (fc5d5b096ea49ee9) New (c1af1ce07e7fc035)
1 /* 1 /*
2 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) 2 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/)
3 3
4 License: Public Domain 4 License: Public Domain
5 5
295 hidden lines
301 } 301 }
302 302
303 void whefs_fs_finalize( whefs_fs * restrict fs ) 303 void whefs_fs_finalize( whefs_fs * restrict fs )
304 { 304 {
305 if( ! fs ) return; 305 if( ! fs ) return;
> 306 whefs_fs_flush(fs);
306 if( fs->opened_nodes ) 307 if( fs->opened_nodes )
307 { 308 {
308 WHEFS_DBG_WARN("We're closing with opened inodes! Flushing them..."); | 309 WHEFS_DBG_WARN("We're closing with opened inodes! Closing them...");
309 whefs_inode_list * l = fs->opened_nodes; 310 whefs_inode_list * l = fs->opened_nodes;
310 whefs_inode_list * n = l; | 311 while( fs->opened_nodes )
311 fs->opened_nodes = 0; | 312 {
312 while( n ) | 313 l = fs->opened_nodes->next;
313 { | 314 WHEFS_DBG_WARN("Auto-closing inode #"WHEFS_ID_TYPE_PFMT", but leaking its whefs_file or whio_dev handle (if any).");
314 n = l->next; | 315 whefs_inode_close( fs, &fs->opened_nodes->inode, fs->opened_nodes->inode.writer );
315 whefs_inode_flush(fs, &l->inode); |
316 free(l); |
317 } 316 }
> 317 // FIXME: this doesn't stop us from leaking unclosed whefs_file or whio_dev handles!
> 318 // We don't currently track those.
318 } 319 }
319 whefs_fs_caches_clear(fs); 320 whefs_fs_caches_clear(fs);
320 whefs_hashid_list_free( fs->cache.hashes ); 321 whefs_hashid_list_free( fs->cache.hashes );
321 whio_blockdev_cleanup ( &fs->fences.s ); 322 whio_blockdev_cleanup ( &fs->fences.s );
322 whio_blockdev_cleanup ( &fs->fences.i ); 323 whio_blockdev_cleanup ( &fs->fences.i );
323 //whio_blockdev_cleanup ( &fs->fences.b ); 324 //whio_blockdev_cleanup ( &fs->fences.b );
324 whefs_string_cache_cleanup( &fs->cache.strings ); 325 whefs_string_cache_cleanup( &fs->cache.strings );
325 if( fs->dev ) 326 if( fs->dev )
326 { 327 {
327 whefs_fs_flush(fs); | 328 /**
| 329 Philosophical problem: because finalizing fs->dev
| 330 might flush the device, *should* finalize fs->dev
| 331 BEFORE we unlock. However, we cannot unlock once
| 332 fs->dev is destroyed.
| 333 */
328 whefs_fs_unlock( fs, 0, SEEK_SET, 0 ); 334 whefs_fs_unlock( fs, 0, SEEK_SET, 0 );
329 if( fs->ownsDev ) fs->dev->api->finalize( fs->dev ); 335 if( fs->ownsDev ) fs->dev->api->finalize( fs->dev );
330 fs->dev = 0; 336 fs->dev = 0;
331 } 337 }
332 whefs_fs_free( fs ); 338 whefs_fs_free( fs );
175 hidden lines
508 { 514 {
509 /* reminder: (!*cached) is ambiguous: it could be an unused inode slot or 515 /* reminder: (!*cached) is ambiguous: it could be an unused inode slot or
510 an empty name. 516 an empty name.
511 */ 517 */
512 //WHEFS_DBG("Got cached name for inode #%"WHEFS_ID_TYPE_PFMT" [%s]",id,cached); 518 //WHEFS_DBG("Got cached name for inode #%"WHEFS_ID_TYPE_PFMT" [%s]",id,cached);
513 //WHEFS_DBG("[inode strings db: misses=%u Hits=%u][name=[%s]]",hitmiss[0],hitmiss[1],cached); | 519 WHEFS_DBG_CACHE("Got cached name for inode #%"WHEFS_ID_TYPE_PFMT" [name=[%s]]. TOTAL cache misses=%u, hits=%u]",id,cached,hitmiss[0],hitmiss[1]);
514 ++hitmiss[1]; 520 ++hitmiss[1];
515 return whefs_string_copy_cstring( tgt, cached ); 521 return whefs_string_copy_cstring( tgt, cached );
516 } 522 }
517 ++hitmiss[0]; 523 ++hitmiss[0];
518 } 524 }
943 hidden lines
1462 if( whefs_rc.OK != rc ) break; 1468 if( whefs_rc.OK != rc ) break;
1463 } 1469 }
1464 whefs_fs_flush( fs ); 1470 whefs_fs_flush( fs );
1465 return rc; 1471 return rc;
1466 } 1472 }