diff options
author | Christoph Hellwig <hch@lst.de> | 2010-06-04 05:29:56 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-08-09 16:47:31 -0400 |
commit | f4e420dc423148fba637af1ab618fa8896dfb2d6 (patch) | |
tree | df0e81f5f4b8448dd6b3929e5537dcc46e7d7dde /fs/ext2 | |
parent | 282dc178849882289d30e58b54be6b2799b351aa (diff) |
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>
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/dir.c | 24 | ||||
-rw-r--r-- | fs/ext2/ext2.h | 3 | ||||
-rw-r--r-- | fs/ext2/inode.c | 11 |
3 files changed, 14 insertions, 24 deletions
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 7516957273ed..6b946bae11cf 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -448,6 +448,12 @@ ino_t ext2_inode_by_name(struct inode *dir, struct qstr *child) | |||
448 | return res; | 448 | return res; |
449 | } | 449 | } |
450 | 450 | ||
451 | static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len) | ||
452 | { | ||
453 | return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, | ||
454 | &page, NULL, ext2_get_block); | ||
455 | } | ||
456 | |||
451 | /* Releases the page */ | 457 | /* Releases the page */ |
452 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, | 458 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, |
453 | struct page *page, struct inode *inode, int update_times) | 459 | 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, | |||
458 | int err; | 464 | int err; |
459 | 465 | ||
460 | lock_page(page); | 466 | lock_page(page); |
461 | err = __ext2_write_begin(NULL, page->mapping, pos, len, | 467 | err = ext2_prepare_chunk(page, pos, len); |
462 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
463 | BUG_ON(err); | 468 | BUG_ON(err); |
464 | de->inode = cpu_to_le32(inode->i_ino); | 469 | de->inode = cpu_to_le32(inode->i_ino); |
465 | ext2_set_de_type(de, inode); | 470 | ext2_set_de_type(de, inode); |
@@ -542,8 +547,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) | |||
542 | got_it: | 547 | got_it: |
543 | pos = page_offset(page) + | 548 | pos = page_offset(page) + |
544 | (char*)de - (char*)page_address(page); | 549 | (char*)de - (char*)page_address(page); |
545 | err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0, | 550 | err = ext2_prepare_chunk(page, pos, rec_len); |
546 | &page, NULL); | ||
547 | if (err) | 551 | if (err) |
548 | goto out_unlock; | 552 | goto out_unlock; |
549 | if (de->inode) { | 553 | if (de->inode) { |
@@ -576,8 +580,7 @@ out_unlock: | |||
576 | */ | 580 | */ |
577 | int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) | 581 | int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) |
578 | { | 582 | { |
579 | struct address_space *mapping = page->mapping; | 583 | struct inode *inode = page->mapping->host; |
580 | struct inode *inode = mapping->host; | ||
581 | char *kaddr = page_address(page); | 584 | char *kaddr = page_address(page); |
582 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); | 585 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); |
583 | unsigned to = ((char *)dir - kaddr) + | 586 | unsigned to = ((char *)dir - kaddr) + |
@@ -601,8 +604,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) | |||
601 | from = (char*)pde - (char*)page_address(page); | 604 | from = (char*)pde - (char*)page_address(page); |
602 | pos = page_offset(page) + from; | 605 | pos = page_offset(page) + from; |
603 | lock_page(page); | 606 | lock_page(page); |
604 | err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0, | 607 | err = ext2_prepare_chunk(page, pos, to - from); |
605 | &page, NULL); | ||
606 | BUG_ON(err); | 608 | BUG_ON(err); |
607 | if (pde) | 609 | if (pde) |
608 | pde->rec_len = ext2_rec_len_to_disk(to - from); | 610 | pde->rec_len = ext2_rec_len_to_disk(to - from); |
@@ -621,8 +623,7 @@ out: | |||
621 | */ | 623 | */ |
622 | int ext2_make_empty(struct inode *inode, struct inode *parent) | 624 | int ext2_make_empty(struct inode *inode, struct inode *parent) |
623 | { | 625 | { |
624 | struct address_space *mapping = inode->i_mapping; | 626 | struct page *page = grab_cache_page(inode->i_mapping, 0); |
625 | struct page *page = grab_cache_page(mapping, 0); | ||
626 | unsigned chunk_size = ext2_chunk_size(inode); | 627 | unsigned chunk_size = ext2_chunk_size(inode); |
627 | struct ext2_dir_entry_2 * de; | 628 | struct ext2_dir_entry_2 * de; |
628 | int err; | 629 | int err; |
@@ -631,8 +632,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent) | |||
631 | if (!page) | 632 | if (!page) |
632 | return -ENOMEM; | 633 | return -ENOMEM; |
633 | 634 | ||
634 | err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0, | 635 | err = ext2_prepare_chunk(page, 0, chunk_size); |
635 | &page, NULL); | ||
636 | if (err) { | 636 | if (err) { |
637 | unlock_page(page); | 637 | unlock_page(page); |
638 | goto fail; | 638 | goto fail; |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 52b34f1d2738..8f53d11bf957 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -127,9 +127,6 @@ extern void ext2_set_inode_flags(struct inode *inode); | |||
127 | extern void ext2_get_inode_flags(struct ext2_inode_info *); | 127 | extern void ext2_get_inode_flags(struct ext2_inode_info *); |
128 | extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 128 | extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
129 | u64 start, u64 len); | 129 | u64 start, u64 len); |
130 | int __ext2_write_begin(struct file *file, struct address_space *mapping, | ||
131 | loff_t pos, unsigned len, unsigned flags, | ||
132 | struct page **pagep, void **fsdata); | ||
133 | 130 | ||
134 | /* ioctl.c */ | 131 | /* ioctl.c */ |
135 | extern long ext2_ioctl(struct file *, unsigned int, unsigned long); | 132 | extern long ext2_ioctl(struct file *, unsigned int, unsigned long); |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 348805cd4109..2f4dfbcd7696 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -765,14 +765,6 @@ ext2_readpages(struct file *file, struct address_space *mapping, | |||
765 | return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); | 765 | return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); |
766 | } | 766 | } |
767 | 767 | ||
768 | int __ext2_write_begin(struct file *file, struct address_space *mapping, | ||
769 | loff_t pos, unsigned len, unsigned flags, | ||
770 | struct page **pagep, void **fsdata) | ||
771 | { | ||
772 | return block_write_begin_newtrunc(file, mapping, pos, len, flags, | ||
773 | pagep, fsdata, ext2_get_block); | ||
774 | } | ||
775 | |||
776 | static int | 768 | static int |
777 | ext2_write_begin(struct file *file, struct address_space *mapping, | 769 | ext2_write_begin(struct file *file, struct address_space *mapping, |
778 | loff_t pos, unsigned len, unsigned flags, | 770 | loff_t pos, unsigned len, unsigned flags, |
@@ -781,7 +773,8 @@ ext2_write_begin(struct file *file, struct address_space *mapping, | |||
781 | int ret; | 773 | int ret; |
782 | 774 | ||
783 | *pagep = NULL; | 775 | *pagep = NULL; |
784 | ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata); | 776 | ret = block_write_begin_newtrunc(file, mapping, pos, len, flags, |
777 | pagep, fsdata, ext2_get_block); | ||
785 | if (ret < 0) | 778 | if (ret < 0) |
786 | ext2_write_failed(mapping, pos + len); | 779 | ext2_write_failed(mapping, pos + len); |
787 | return ret; | 780 | return ret; |