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 <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:

committed by
Al Viro

parent
282dc17884
commit
f4e420dc42
@@ -448,6 +448,12 @@ ino_t ext2_inode_by_name(struct inode *dir, struct qstr *child)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len)
|
||||
{
|
||||
return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0,
|
||||
&page, NULL, ext2_get_block);
|
||||
}
|
||||
|
||||
/* Releases the page */
|
||||
void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
|
||||
struct page *page, struct inode *inode, int update_times)
|
||||
@@ -458,8 +464,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
|
||||
int err;
|
||||
|
||||
lock_page(page);
|
||||
err = __ext2_write_begin(NULL, page->mapping, pos, len,
|
||||
AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
|
||||
err = ext2_prepare_chunk(page, pos, len);
|
||||
BUG_ON(err);
|
||||
de->inode = cpu_to_le32(inode->i_ino);
|
||||
ext2_set_de_type(de, inode);
|
||||
@@ -542,8 +547,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
|
||||
got_it:
|
||||
pos = page_offset(page) +
|
||||
(char*)de - (char*)page_address(page);
|
||||
err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0,
|
||||
&page, NULL);
|
||||
err = ext2_prepare_chunk(page, pos, rec_len);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
if (de->inode) {
|
||||
@@ -576,8 +580,7 @@ out_unlock:
|
||||
*/
|
||||
int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
|
||||
{
|
||||
struct address_space *mapping = page->mapping;
|
||||
struct inode *inode = mapping->host;
|
||||
struct inode *inode = page->mapping->host;
|
||||
char *kaddr = page_address(page);
|
||||
unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
|
||||
unsigned to = ((char *)dir - kaddr) +
|
||||
@@ -601,8 +604,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
|
||||
from = (char*)pde - (char*)page_address(page);
|
||||
pos = page_offset(page) + from;
|
||||
lock_page(page);
|
||||
err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0,
|
||||
&page, NULL);
|
||||
err = ext2_prepare_chunk(page, pos, to - from);
|
||||
BUG_ON(err);
|
||||
if (pde)
|
||||
pde->rec_len = ext2_rec_len_to_disk(to - from);
|
||||
@@ -621,8 +623,7 @@ out:
|
||||
*/
|
||||
int ext2_make_empty(struct inode *inode, struct inode *parent)
|
||||
{
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
struct page *page = grab_cache_page(mapping, 0);
|
||||
struct page *page = grab_cache_page(inode->i_mapping, 0);
|
||||
unsigned chunk_size = ext2_chunk_size(inode);
|
||||
struct ext2_dir_entry_2 * de;
|
||||
int err;
|
||||
@@ -631,8 +632,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0,
|
||||
&page, NULL);
|
||||
err = ext2_prepare_chunk(page, 0, chunk_size);
|
||||
if (err) {
|
||||
unlock_page(page);
|
||||
goto fail;
|
||||
|
@@ -127,9 +127,6 @@ extern void ext2_set_inode_flags(struct inode *inode);
|
||||
extern void ext2_get_inode_flags(struct ext2_inode_info *);
|
||||
extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
u64 start, u64 len);
|
||||
int __ext2_write_begin(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned flags,
|
||||
struct page **pagep, void **fsdata);
|
||||
|
||||
/* ioctl.c */
|
||||
extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
|
||||
|
@@ -765,14 +765,6 @@ ext2_readpages(struct file *file, struct address_space *mapping,
|
||||
return mpage_readpages(mapping, pages, nr_pages, ext2_get_block);
|
||||
}
|
||||
|
||||
int __ext2_write_begin(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned flags,
|
||||
struct page **pagep, void **fsdata)
|
||||
{
|
||||
return block_write_begin_newtrunc(file, mapping, pos, len, flags,
|
||||
pagep, fsdata, ext2_get_block);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_write_begin(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned len, unsigned flags,
|
||||
@@ -781,7 +773,8 @@ ext2_write_begin(struct file *file, struct address_space *mapping,
|
||||
int ret;
|
||||
|
||||
*pagep = NULL;
|
||||
ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
|
||||
ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
|
||||
pagep, fsdata, ext2_get_block);
|
||||
if (ret < 0)
|
||||
ext2_write_failed(mapping, pos + len);
|
||||
return ret;
|
||||
|
Reference in New Issue
Block a user