From f4e420dc423148fba637af1ab618fa8896dfb2d6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 4 Jun 2010 11:29:56 +0200 Subject: clean up write_begin usage for directories in pagecache For filesystem that implement directories in pagecache we call block_write_begin with an already allocated page for this code, while the normal regular file write path uses the default block_write_begin behaviour. Get rid of the __foofs_write_begin helper and opencode the normal write_begin call in foofs_write_begin, while adding a new foofs_prepare_chunk helper for the directory code. The added benefit is that foofs_prepare_chunk has a much saner calling convention. Note that the interruptible flag passed into block_write_begin is always ignored if we already pass in a page (see next patch for details), and we never were doing truncations of exessive blocks for this case either so we can switch directly to block_write_begin_newtrunc. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/minix/inode.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'fs/minix/inode.c') diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 756f8c93780c..f4abe45229bb 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -357,12 +357,10 @@ static int minix_readpage(struct file *file, struct page *page) return block_read_full_page(page,minix_get_block); } -int __minix_write_begin(struct file *file, struct address_space *mapping, - loff_t pos, unsigned len, unsigned flags, - struct page **pagep, void **fsdata) +int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len) { - return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, - minix_get_block); + return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, + &page, NULL, minix_get_block); } static int minix_write_begin(struct file *file, struct address_space *mapping, @@ -370,7 +368,8 @@ static int minix_write_begin(struct file *file, struct address_space *mapping, struct page **pagep, void **fsdata) { *pagep = NULL; - return __minix_write_begin(file, mapping, pos, len, flags, pagep, fsdata); + return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, + minix_get_block); } static sector_t minix_bmap(struct address_space *mapping, sector_t block) -- cgit v1.2.2 From 6e1db88d536adcbbfe562b2d4b7d6425784fff12 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 4 Jun 2010 11:29:57 +0200 Subject: introduce __block_write_begin Split up the block_write_begin implementation - __block_write_begin is a new trivial wrapper for block_prepare_write that always takes an already allocated page and can be either called from block_write_begin or filesystem code that already has a page allocated. Remove the handling of already allocated pages from block_write_begin after switching all callers that do it to __block_write_begin. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/minix/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/minix/inode.c') diff --git a/fs/minix/inode.c b/fs/minix/inode.c index f4abe45229bb..6b29e73f0ca6 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -359,8 +359,7 @@ static int minix_readpage(struct file *file, struct page *page) int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len) { - return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, - &page, NULL, minix_get_block); + return __block_write_begin(page, pos, len, minix_get_block); } static int minix_write_begin(struct file *file, struct address_space *mapping, -- cgit v1.2.2 From 155130a4f7848b1aac439cab6bda1a175507c71c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 4 Jun 2010 11:29:58 +0200 Subject: get rid of block_write_begin_newtrunc Move the call to vmtruncate to get rid of accessive blocks to the callers in preparation of the new truncate sequence and rename the non-truncating version to block_write_begin. While we're at it also remove several unused arguments to block_write_begin. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/minix/inode.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'fs/minix/inode.c') diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 6b29e73f0ca6..125062f55ef2 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -366,9 +366,17 @@ static int minix_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { - *pagep = NULL; - return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, + int ret; + + ret = block_write_begin(mapping, pos, len, flags, pagep, minix_get_block); + if (unlikely(ret)) { + loff_t isize = mapping->host->i_size; + if (pos + len > isize) + vmtruncate(mapping->host, isize); + } + + return ret; } static sector_t minix_bmap(struct address_space *mapping, sector_t block) -- cgit v1.2.2 From 5ccb4a78d8c0e27985afec32cc4894d48e7b876e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 4 Jun 2010 22:27:38 -0400 Subject: 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 --- fs/minix/inode.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'fs/minix/inode.c') diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 125062f55ef2..e39d6bf2e8fb 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, -- cgit v1.2.2