From: Al Viro Subject: [PATCH 12/58] switch minix to ->evict_inode(), fix write_inode/delete_inode race Date: Tue, 08 Jun 2010 23:16:53 +0100 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: linux-fsdevel@vger.kernel.org Return-path: Received: from zeniv.linux.org.uk ([195.92.253.2]:38826 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932257Ab0FHWQx (ORCPT ); Tue, 8 Jun 2010 18:16:53 -0400 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.69 #1 (Red Hat Linux)) id 1OM76L-0004Ym-2h for linux-fsdevel@vger.kernel.org; Tue, 08 Jun 2010 22:16:53 +0000 Sender: linux-fsdevel-owner@vger.kernel.org List-ID: We need to wait for completion of possible writeback in progress before we clear on-disk inode during deletion. Signed-off-by: Al Viro --- fs/minix/bitmap.c | 6 ++---- fs/minix/inode.c | 15 ++++++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 482779f..3f32bcb 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -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; 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) diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 125062f..e39d6bf 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -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, -- 1.5.6.5