Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[pandora-kernel.git] / fs / ocfs2 / super.c
index 7efb349..a3f8871 100644 (file)
@@ -777,6 +777,7 @@ static int ocfs2_sb_probe(struct super_block *sb,
                }
                di = (struct ocfs2_dinode *) (*bh)->b_data;
                memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats));
+               spin_lock_init(&stats->b_lock);
                status = ocfs2_verify_volume(di, *bh, blksize, stats);
                if (status >= 0)
                        goto bail;
@@ -1182,7 +1183,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
        wake_up(&osb->osb_mount_event);
 
        /* Start this when the mount is almost sure of being successful */
-       ocfs2_orphan_scan_init(osb);
+       ocfs2_orphan_scan_start(osb);
 
        mlog_exit(status);
        return status;
@@ -1213,14 +1214,31 @@ static int ocfs2_get_sb(struct file_system_type *fs_type,
                           mnt);
 }
 
+static void ocfs2_kill_sb(struct super_block *sb)
+{
+       struct ocfs2_super *osb = OCFS2_SB(sb);
+
+       /* Failed mount? */
+       if (!osb || atomic_read(&osb->vol_state) == VOLUME_DISABLED)
+               goto out;
+
+       /* Prevent further queueing of inode drop events */
+       spin_lock(&dentry_list_lock);
+       ocfs2_set_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED);
+       spin_unlock(&dentry_list_lock);
+       /* Wait for work to finish and/or remove it */
+       cancel_work_sync(&osb->dentry_lock_work);
+out:
+       kill_block_super(sb);
+}
+
 static struct file_system_type ocfs2_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ocfs2",
        .get_sb         = ocfs2_get_sb, /* is this called when we mount
                                        * the fs? */
-       .kill_sb        = kill_block_super, /* set to the generic one
-                                            * right now, but do we
-                                            * need to change that? */
+       .kill_sb        = ocfs2_kill_sb,
+
        .fs_flags       = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE,
        .next           = NULL
 };
@@ -1819,6 +1837,12 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
 
        debugfs_remove(osb->osb_ctxt);
 
+       /*
+        * Flush inode dropping work queue so that deletes are
+        * performed while the filesystem is still working
+        */
+       ocfs2_drop_all_dl_inodes(osb);
+
        /* Orphan scan should be stopped as early as possible */
        ocfs2_orphan_scan_stop(osb);
 
@@ -1981,6 +2005,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
        snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
                 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
 
+       ocfs2_orphan_scan_init(osb);
+
        status = ocfs2_recovery_init(osb);
        if (status) {
                mlog(ML_ERROR, "Unable to initialize recovery state\n");