]> err.no Git - linux-2.6/blobdiff - fs/super.c
[PATCH] corrupted cramfs filesystems cause kernel oops
[linux-2.6] / fs / super.c
index aec99ddbe53f726a526d4cd0b02abb9f55179e0b..84c320f6ad7e39471277c581476860caded889e9 100644 (file)
@@ -220,6 +220,24 @@ static int grab_super(struct super_block *s) __releases(sb_lock)
        return 0;
 }
 
+/*
+ * Superblock locking.  We really ought to get rid of these two.
+ */
+void lock_super(struct super_block * sb)
+{
+       get_fs_excl();
+       mutex_lock(&sb->s_lock);
+}
+
+void unlock_super(struct super_block * sb)
+{
+       put_fs_excl();
+       mutex_unlock(&sb->s_lock);
+}
+
+EXPORT_SYMBOL(lock_super);
+EXPORT_SYMBOL(unlock_super);
+
 /*
  * Write out and wait upon all dirty data associated with this
  * superblock.  Filesystem data as well as the underlying block
@@ -260,17 +278,17 @@ int fsync_super(struct super_block *sb)
  *     that need destruction out of superblock, call generic_shutdown_super()
  *     and release aforementioned objects.  Note: dentries and inodes _are_
  *     taken care of and do not need specific handling.
+ *
+ *     Upon calling this function, the filesystem may no longer alter or
+ *     rearrange the set of dentries belonging to this super_block, nor may it
+ *     change the attachments of dentries to inodes.
  */
 void generic_shutdown_super(struct super_block *sb)
 {
-       struct dentry *root = sb->s_root;
        struct super_operations *sop = sb->s_op;
 
-       if (root) {
-               sb->s_root = NULL;
-               shrink_dcache_parent(root);
-               shrink_dcache_sb(sb);
-               dput(root);
+       if (sb->s_root) {
+               shrink_dcache_for_umount(sb);
                fsync_super(sb);
                lock_super(sb);
                sb->s_flags &= ~MS_ACTIVE;