Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

switch minix to ->evict_inode(), fix write_inode/delete_inode race

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>

Al Viro 5ccb4a78 01cd9fef

+12 -9
+2 -4
fs/minix/bitmap.c
··· 200 200 ino = inode->i_ino; 201 201 if (ino < 1 || ino > sbi->s_ninodes) { 202 202 printk("minix_free_inode: inode 0 or nonexistent inode\n"); 203 - goto out; 203 + return; 204 204 } 205 205 bit = ino & ((1<<k) - 1); 206 206 ino >>= k; 207 207 if (ino >= sbi->s_imap_blocks) { 208 208 printk("minix_free_inode: nonexistent imap in superblock\n"); 209 - goto out; 209 + return; 210 210 } 211 211 212 212 minix_clear_inode(inode); /* clear on-disk copy */ ··· 217 217 printk("minix_free_inode: bit %lu already cleared\n", bit); 218 218 spin_unlock(&bitmap_lock); 219 219 mark_buffer_dirty(bh); 220 - out: 221 - clear_inode(inode); /* clear in-memory copy */ 222 220 } 223 221 224 222 struct inode *minix_new_inode(const struct inode *dir, int mode, int *error)
+10 -5
fs/minix/inode.c
··· 24 24 static int minix_statfs(struct dentry *dentry, struct kstatfs *buf); 25 25 static int minix_remount (struct super_block * sb, int * flags, char * data); 26 26 27 - static void minix_delete_inode(struct inode *inode) 27 + static void minix_evict_inode(struct inode *inode) 28 28 { 29 29 truncate_inode_pages(&inode->i_data, 0); 30 - inode->i_size = 0; 31 - minix_truncate(inode); 32 - minix_free_inode(inode); 30 + if (!inode->i_nlink) { 31 + inode->i_size = 0; 32 + minix_truncate(inode); 33 + } 34 + invalidate_inode_buffers(inode); 35 + end_writeback(inode); 36 + if (!inode->i_nlink) 37 + minix_free_inode(inode); 33 38 } 34 39 35 40 static void minix_put_super(struct super_block *sb) ··· 101 96 .alloc_inode = minix_alloc_inode, 102 97 .destroy_inode = minix_destroy_inode, 103 98 .write_inode = minix_write_inode, 104 - .delete_inode = minix_delete_inode, 99 + .evict_inode = minix_evict_inode, 105 100 .put_super = minix_put_super, 106 101 .statfs = minix_statfs, 107 102 .remount_fs = minix_remount,