switch minix to ->evict_inode(), fix write_inode/delete_inode race
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 5 Jun 2010 02:27:38 +0000 (22:27 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 9 Aug 2010 20:47:53 +0000 (16:47 -0400)
We need to wait for completion of possible writeback in progress
before we clear on-disk inode during deletion.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/minix/bitmap.c
fs/minix/inode.c

index 482779fe4e7cfc2e52104f0ae77815dbcf9de4ef..3f32bcb0d9bd5beb882b67480ff3593d202f5837 100644 (file)
@@ -200,13 +200,13 @@ void minix_free_inode(struct inode * inode)
        ino = inode->i_ino;
        if (ino < 1 || ino > sbi->s_ninodes) {
                printk("minix_free_inode: inode 0 or nonexistent inode\n");
-               goto out;
+               return;
        }
        bit = ino & ((1<<k) - 1);
        ino >>= k;
        if (ino >= sbi->s_imap_blocks) {
                printk("minix_free_inode: nonexistent imap in superblock\n");
-               goto out;
+               return;
        }
 
        minix_clear_inode(inode);       /* clear on-disk copy */
@@ -217,8 +217,6 @@ void minix_free_inode(struct inode * inode)
                printk("minix_free_inode: bit %lu already cleared\n", bit);
        spin_unlock(&bitmap_lock);
        mark_buffer_dirty(bh);
- out:
-       clear_inode(inode);             /* clear in-memory copy */
 }
 
 struct inode *minix_new_inode(const struct inode *dir, int mode, int *error)
index 125062f55ef2d7b51c2afbf5183817cdaa7e55e6..e39d6bf2e8fbcf3ccbc36117aca4fd03a67c862e 100644 (file)
@@ -24,12 +24,17 @@ static int minix_write_inode(struct inode *inode,
 static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int minix_remount (struct super_block * sb, int * flags, char * data);
 
-static void minix_delete_inode(struct inode *inode)
+static void minix_evict_inode(struct inode *inode)
 {
        truncate_inode_pages(&inode->i_data, 0);
-       inode->i_size = 0;
-       minix_truncate(inode);
-       minix_free_inode(inode);
+       if (!inode->i_nlink) {
+               inode->i_size = 0;
+               minix_truncate(inode);
+       }
+       invalidate_inode_buffers(inode);
+       end_writeback(inode);
+       if (!inode->i_nlink)
+               minix_free_inode(inode);
 }
 
 static void minix_put_super(struct super_block *sb)
@@ -96,7 +101,7 @@ static const struct super_operations minix_sops = {
        .alloc_inode    = minix_alloc_inode,
        .destroy_inode  = minix_destroy_inode,
        .write_inode    = minix_write_inode,
-       .delete_inode   = minix_delete_inode,
+       .evict_inode    = minix_evict_inode,
        .put_super      = minix_put_super,
        .statfs         = minix_statfs,
        .remount_fs     = minix_remount,