[PATCH] Re: The next ramfs bug ... Bad news - the patch is broken

From: Alexander Viro (viro@math.psu.edu)
Date: Fri Jun 16 2000 - 22:06:45 EDT

  • Next message: Warren Young: "Re: (reiserfs) Re: Red Hat (was Re: reiserfs)"

    OK, how about the following? It seems to fix all problems.
    Alan, I think that ->detach_page() thing (do whatever we need to make the
    page droppable: ClearPageDirty() in case of ramfs) makes sense and for
    block-based filesystems we simply should make ->detach_page ==
    block_destroy_buffers. Comments?

    diff -urN linux-ac19/fs/ramfs/inode.c linux-ac19-fixes/fs/ramfs/inode.c
    --- linux-ac19/fs/ramfs/inode.c Fri Jun 16 21:47:05 2000
    +++ linux-ac19-fixes/fs/ramfs/inode.c Fri Jun 16 21:29:57 2000
    @@ -82,6 +82,12 @@
             return 0;
     }
     
    +static int ramfs_detach_page(struct page *page)
    +{
    + ClearPageDirty(page);
    + return 0;
    +}
    +
     static int ramfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
     {
             void *addr;
    @@ -272,7 +278,8 @@
             readpage: ramfs_readpage,
             writepage: ramfs_writepage,
             prepare_write: ramfs_prepare_write,
    - commit_write: ramfs_commit_write
    + commit_write: ramfs_commit_write,
    + detach_page: ramfs_detach_page,
     };
     
     static struct file_operations ramfs_file_operations = {
    @@ -298,15 +305,9 @@
             rename: ramfs_rename,
     };
     
    -static void ramfs_put_super(struct super_block *sb)
    -{
    - d_genocide(sb->s_root);
    - shrink_dcache_parent(sb->s_root);
    -}
    -
     static struct super_operations ramfs_ops = {
    - put_super: ramfs_put_super,
             statfs: ramfs_statfs,
    + put_inode: force_delete,
     };
     
     static struct super_block *ramfs_read_super(struct super_block * sb, void * data, int silent)
    @@ -331,7 +332,7 @@
             return sb;
     }
     
    -static DECLARE_FSTYPE(ramfs_fs_type, "ramfs", ramfs_read_super, 0);
    +static DECLARE_FSTYPE(ramfs_fs_type, "ramfs", ramfs_read_super, FS_LITTER);
     
     static int __init init_ramfs_fs(void)
     {
    diff -urN linux-ac19/fs/super.c linux-ac19-fixes/fs/super.c
    --- linux-ac19/fs/super.c Fri Jun 16 21:47:05 2000
    +++ linux-ac19-fixes/fs/super.c Fri Jun 16 20:22:25 2000
    @@ -824,8 +824,14 @@
     {
             struct block_device *bdev;
             kdev_t dev;
    - dput(sb->s_root);
    + struct dentry *root = sb->s_root;
             sb->s_root = NULL;
    + /* Need to clean after the sucker */
    + if (sb->s_type->fs_flags & FS_LITTER)
    + d_genocide(root);
    + if (sb->s_type->fs_flags & (FS_SINGLE|FS_LITTER))
    + shrink_dcache_parent(root);
    + dput(root);
             lock_super(sb);
             if (sb->s_op) {
                     if (sb->s_op->write_super && sb->s_dirt)
    diff -urN linux-ac19/include/linux/fs.h linux-ac19-fixes/include/linux/fs.h
    --- linux-ac19/include/linux/fs.h Fri Jun 16 21:47:06 2000
    +++ linux-ac19-fixes/include/linux/fs.h Fri Jun 16 20:59:49 2000
    @@ -89,6 +89,7 @@
                                * kernel-wide vfsmnt is kept in ->kern_mnt.
                                */
     #define FS_NOMOUNT 16 /* Never mount from userland */
    +#define FS_LITTER 32 /* Keeps the tree in dcache */
     /*
      * These are the fs-independent mount-flags: up to 16 flags are supported
      */
    @@ -355,6 +356,7 @@
             int (*sync_page)(struct page *);
             int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
             int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
    + int (*detach_page)(struct page *);
             /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
             int (*bmap)(struct address_space *, long);
     };
    diff -urN linux-ac19/kernel/ksyms.c linux-ac19-fixes/kernel/ksyms.c
    --- linux-ac19/kernel/ksyms.c Fri Jun 16 21:47:07 2000
    +++ linux-ac19-fixes/kernel/ksyms.c Fri Jun 16 20:22:25 2000
    @@ -217,7 +217,6 @@
     EXPORT_SYMBOL(locks_mandatory_area);
     EXPORT_SYMBOL(dput);
     EXPORT_SYMBOL(have_submounts);
    -EXPORT_SYMBOL(d_genocide);
     EXPORT_SYMBOL(d_find_alias);
     EXPORT_SYMBOL(d_prune_aliases);
     EXPORT_SYMBOL(prune_dcache);
    diff -urN linux-ac19/mm/filemap.c linux-ac19-fixes/mm/filemap.c
    --- linux-ac19/mm/filemap.c Fri Jun 16 21:47:07 2000
    +++ linux-ac19-fixes/mm/filemap.c Fri Jun 16 21:09:34 2000
    @@ -166,6 +166,8 @@
     {
             if (page->buffers)
                     block_destroy_buffers(page);
    + if (page->mapping->a_ops->detach_page)
    + page->mapping->a_ops->detach_page(page);
             lru_cache_del(page);
             
             /*
    @@ -277,6 +279,18 @@
                             spin_unlock(&pagemap_lru_lock);
                             spin_unlock(&pagecache_lock);
                             block_destroy_buffers(page);
    + remove_inode_page(page);
    + lru_cache_del(page);
    + page_cache_release(page);
    + UnlockPage(page);
    + page_cache_release(page);
    + goto repeat;
    + }
    + if (page->mapping->a_ops->detach_page) {
    + page_cache_get(page);
    + spin_unlock(&pagemap_lru_lock);
    + spin_unlock(&pagecache_lock);
    + page->mapping->a_ops->detach_page(page);
                             remove_inode_page(page);
                             lru_cache_del(page);
                             page_cache_release(page);

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Fri Jun 16 2000 - 22:11:47 EDT