aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext2/dir.c55
-rw-r--r--fs/ext2/ext2.h3
-rw-r--r--fs/ext2/inode.c24
3 files changed, 53 insertions, 29 deletions
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 2bf49d7ef841..05d9342bb64e 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -22,7 +22,9 @@
22 */ 22 */
23 23
24#include "ext2.h" 24#include "ext2.h"
25#include <linux/buffer_head.h>
25#include <linux/pagemap.h> 26#include <linux/pagemap.h>
27#include <linux/swap.h>
26 28
27typedef struct ext2_dir_entry_2 ext2_dirent; 29typedef struct ext2_dir_entry_2 ext2_dirent;
28 30
@@ -61,16 +63,25 @@ ext2_last_byte(struct inode *inode, unsigned long page_nr)
61 return last_byte; 63 return last_byte;
62} 64}
63 65
64static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to) 66static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
65{ 67{
66 struct inode *dir = page->mapping->host; 68 struct address_space *mapping = page->mapping;
69 struct inode *dir = mapping->host;
67 int err = 0; 70 int err = 0;
71
68 dir->i_version++; 72 dir->i_version++;
69 page->mapping->a_ops->commit_write(NULL, page, from, to); 73 block_write_end(NULL, mapping, pos, len, len, page, NULL);
74
75 if (pos+len > dir->i_size) {
76 i_size_write(dir, pos+len);
77 mark_inode_dirty(dir);
78 }
79
70 if (IS_DIRSYNC(dir)) 80 if (IS_DIRSYNC(dir))
71 err = write_one_page(page, 1); 81 err = write_one_page(page, 1);
72 else 82 else
73 unlock_page(page); 83 unlock_page(page);
84
74 return err; 85 return err;
75} 86}
76 87
@@ -412,16 +423,18 @@ ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry)
412void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, 423void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
413 struct page *page, struct inode *inode) 424 struct page *page, struct inode *inode)
414{ 425{
415 unsigned from = (char *) de - (char *) page_address(page); 426 loff_t pos = page_offset(page) +
416 unsigned to = from + le16_to_cpu(de->rec_len); 427 (char *) de - (char *) page_address(page);
428 unsigned len = le16_to_cpu(de->rec_len);
417 int err; 429 int err;
418 430
419 lock_page(page); 431 lock_page(page);
420 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 432 err = __ext2_write_begin(NULL, page->mapping, pos, len,
433 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
421 BUG_ON(err); 434 BUG_ON(err);
422 de->inode = cpu_to_le32(inode->i_ino); 435 de->inode = cpu_to_le32(inode->i_ino);
423 ext2_set_de_type (de, inode); 436 ext2_set_de_type(de, inode);
424 err = ext2_commit_chunk(page, from, to); 437 err = ext2_commit_chunk(page, pos, len);
425 ext2_put_page(page); 438 ext2_put_page(page);
426 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 439 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
427 EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; 440 EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
@@ -444,7 +457,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
444 unsigned long npages = dir_pages(dir); 457 unsigned long npages = dir_pages(dir);
445 unsigned long n; 458 unsigned long n;
446 char *kaddr; 459 char *kaddr;
447 unsigned from, to; 460 loff_t pos;
448 int err; 461 int err;
449 462
450 /* 463 /*
@@ -497,9 +510,10 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
497 return -EINVAL; 510 return -EINVAL;
498 511
499got_it: 512got_it:
500 from = (char*)de - (char*)page_address(page); 513 pos = page_offset(page) +
501 to = from + rec_len; 514 (char*)de - (char*)page_address(page);
502 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 515 err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0,
516 &page, NULL);
503 if (err) 517 if (err)
504 goto out_unlock; 518 goto out_unlock;
505 if (de->inode) { 519 if (de->inode) {
@@ -509,10 +523,10 @@ got_it:
509 de = de1; 523 de = de1;
510 } 524 }
511 de->name_len = namelen; 525 de->name_len = namelen;
512 memcpy (de->name, name, namelen); 526 memcpy(de->name, name, namelen);
513 de->inode = cpu_to_le32(inode->i_ino); 527 de->inode = cpu_to_le32(inode->i_ino);
514 ext2_set_de_type (de, inode); 528 ext2_set_de_type (de, inode);
515 err = ext2_commit_chunk(page, from, to); 529 err = ext2_commit_chunk(page, pos, rec_len);
516 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 530 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
517 EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; 531 EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
518 mark_inode_dirty(dir); 532 mark_inode_dirty(dir);
@@ -537,6 +551,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
537 char *kaddr = page_address(page); 551 char *kaddr = page_address(page);
538 unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); 552 unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
539 unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len); 553 unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
554 loff_t pos;
540 ext2_dirent * pde = NULL; 555 ext2_dirent * pde = NULL;
541 ext2_dirent * de = (ext2_dirent *) (kaddr + from); 556 ext2_dirent * de = (ext2_dirent *) (kaddr + from);
542 int err; 557 int err;
@@ -553,13 +568,15 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
553 } 568 }
554 if (pde) 569 if (pde)
555 from = (char*)pde - (char*)page_address(page); 570 from = (char*)pde - (char*)page_address(page);
571 pos = page_offset(page) + from;
556 lock_page(page); 572 lock_page(page);
557 err = mapping->a_ops->prepare_write(NULL, page, from, to); 573 err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0,
574 &page, NULL);
558 BUG_ON(err); 575 BUG_ON(err);
559 if (pde) 576 if (pde)
560 pde->rec_len = cpu_to_le16(to-from); 577 pde->rec_len = cpu_to_le16(to - from);
561 dir->inode = 0; 578 dir->inode = 0;
562 err = ext2_commit_chunk(page, from, to); 579 err = ext2_commit_chunk(page, pos, to - from);
563 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 580 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
564 EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL; 581 EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
565 mark_inode_dirty(inode); 582 mark_inode_dirty(inode);
@@ -582,7 +599,9 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
582 599
583 if (!page) 600 if (!page)
584 return -ENOMEM; 601 return -ENOMEM;
585 err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); 602
603 err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0,
604 &page, NULL);
586 if (err) { 605 if (err) {
587 unlock_page(page); 606 unlock_page(page);
588 goto fail; 607 goto fail;
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 9fd0ec5ba0d0..a08052d2c008 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -134,6 +134,9 @@ extern void ext2_truncate (struct inode *);
134extern int ext2_setattr (struct dentry *, struct iattr *); 134extern int ext2_setattr (struct dentry *, struct iattr *);
135extern void ext2_set_inode_flags(struct inode *inode); 135extern void ext2_set_inode_flags(struct inode *inode);
136extern void ext2_get_inode_flags(struct ext2_inode_info *); 136extern void ext2_get_inode_flags(struct ext2_inode_info *);
137int __ext2_write_begin(struct file *file, struct address_space *mapping,
138 loff_t pos, unsigned len, unsigned flags,
139 struct page **pagep, void **fsdata);
137 140
138/* ioctl.c */ 141/* ioctl.c */
139extern int ext2_ioctl (struct inode *, struct file *, unsigned int, 142extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 0079b2cd5314..63ab02aa4c52 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -642,18 +642,21 @@ ext2_readpages(struct file *file, struct address_space *mapping,
642 return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); 642 return mpage_readpages(mapping, pages, nr_pages, ext2_get_block);
643} 643}
644 644
645static int 645int __ext2_write_begin(struct file *file, struct address_space *mapping,
646ext2_prepare_write(struct file *file, struct page *page, 646 loff_t pos, unsigned len, unsigned flags,
647 unsigned from, unsigned to) 647 struct page **pagep, void **fsdata)
648{ 648{
649 return block_prepare_write(page,from,to,ext2_get_block); 649 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
650 ext2_get_block);
650} 651}
651 652
652static int 653static int
653ext2_nobh_prepare_write(struct file *file, struct page *page, 654ext2_write_begin(struct file *file, struct address_space *mapping,
654 unsigned from, unsigned to) 655 loff_t pos, unsigned len, unsigned flags,
656 struct page **pagep, void **fsdata)
655{ 657{
656 return nobh_prepare_write(page,from,to,ext2_get_block); 658 *pagep = NULL;
659 return __ext2_write_begin(file, mapping, pos, len, flags, pagep,fsdata);
657} 660}
658 661
659static int ext2_nobh_writepage(struct page *page, 662static int ext2_nobh_writepage(struct page *page,
@@ -689,8 +692,8 @@ const struct address_space_operations ext2_aops = {
689 .readpages = ext2_readpages, 692 .readpages = ext2_readpages,
690 .writepage = ext2_writepage, 693 .writepage = ext2_writepage,
691 .sync_page = block_sync_page, 694 .sync_page = block_sync_page,
692 .prepare_write = ext2_prepare_write, 695 .write_begin = ext2_write_begin,
693 .commit_write = generic_commit_write, 696 .write_end = generic_write_end,
694 .bmap = ext2_bmap, 697 .bmap = ext2_bmap,
695 .direct_IO = ext2_direct_IO, 698 .direct_IO = ext2_direct_IO,
696 .writepages = ext2_writepages, 699 .writepages = ext2_writepages,
@@ -707,8 +710,7 @@ const struct address_space_operations ext2_nobh_aops = {
707 .readpages = ext2_readpages, 710 .readpages = ext2_readpages,
708 .writepage = ext2_nobh_writepage, 711 .writepage = ext2_nobh_writepage,
709 .sync_page = block_sync_page, 712 .sync_page = block_sync_page,
710 .prepare_write = ext2_nobh_prepare_write, 713 /* XXX: todo */
711 .commit_write = nobh_commit_write,
712 .bmap = ext2_bmap, 714 .bmap = ext2_bmap,
713 .direct_IO = ext2_direct_IO, 715 .direct_IO = ext2_direct_IO,
714 .writepages = ext2_writepages, 716 .writepages = ext2_writepages,