return fs;
}
+static int show_orphans(struct fs *fs)
+{
+ struct datablock *db;
+ printk("Orphans:\n");
+ list_for_each_entry(db, &fs->pending_orphans,
+ orphans) {
+ printk("orphan=%s\n", strblk(&db->b));
+ if (LAFSI(db->b.inode)->type == TypeInodeFile)
+ lafs_print_tree(&LAFSI(db->my_inode)->iblock->b, 0);
+ }
+ printk("cleaner active: %d %d\n", fs->cleaner.active,
+ fs->scan.done);
+ return 1; /* meaningless, but makes it easy to add to wait_event below */
+}
+
static void
lafs_release(struct fs *fs)
{
/* Release the 'struct fs' */
int i;
+ /* FIXME should I refcount this when there are multiple
+ * filesets? How does that work?
+ */
+
/* Delay final destruction of the root inode */
/* FIXME all the sbs... */
set_bit(I_Deleting, &LAFSI(fs->ss[0].root)->iflags);
+
+ /* FIXME I'm not sure we should be waiting for the
+ * cleaner. Maybe we should just release all tc->cleaning
+ * blocks instead.
+ */
+ set_bit(CleanerDisabled, &fs->fsstate);
+
+ wait_event(fs->async_complete,
+ show_orphans(fs) &&
+ !test_bit(OrphansRunning, &fs->fsstate) &&
+ list_empty(&fs->pending_orphans) &&
+ fs->scan.done == 1 &&
+ fs->cleaner.active == 0);
+
for (i = 0; i < fs->devices; i++) {
struct fs_dev *dv = &fs->devs[i];
kfree(dv->devblk);
kfree(fs);
}
-static int show_orphans(struct fs *fs)
-{
- struct datablock *db;
- printk("Orphans:\n");
- list_for_each_entry(db, &fs->pending_orphans,
- orphans) {
- printk("orphan=%s\n", strblk(&db->b));
- if (LAFSI(db->b.inode)->type == TypeInodeFile)
- lafs_print_tree(&LAFSI(db->my_inode)->iblock->b, 0);
- }
- printk("cleaner active: %d %d\n", fs->cleaner.active,
- fs->scan.done);
- return 1; /* meaningless, but makes it easy to add to wait_event below */
-}
-
static void
lafs_put_super(struct super_block *sb)
{
if (sb == fs->prime_sb) {
int d;
/* This is the main sb, not a snapshot or
- * subordinate fs
- */
- /* FIXME I'm not sure we should be waiting for the
- * cleaner. Maybe we should just release all tc->cleaning
- * blocks instead.
+ * subordinate fs.
+ * Now that all inodes have been invalidated we can do
+ * the final checkpoint.
*/
- set_bit(CleanerDisabled, &fs->fsstate);
-
- /* FIXME maybe I want these tests in a spinlock ?? */
- wait_event(fs->async_complete,
- show_orphans(fs) &&
- !test_bit(OrphansRunning, &fs->fsstate) &&
- list_empty(&fs->pending_orphans) &&
- fs->scan.done == 1 &&
- fs->cleaner.active == 0);
lafs_checkpoint_lock(fs);
/* Don't incorporate any more segusage/quota updates. */
lafs_checkpoint_start(fs);