diff options
Diffstat (limited to 'fs/ext2/dir.c')
-rw-r--r-- | fs/ext2/dir.c | 55 |
1 files changed, 37 insertions, 18 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 | ||
27 | typedef struct ext2_dir_entry_2 ext2_dirent; | 29 | typedef 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 | ||
64 | static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to) | 66 | static 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) | |||
412 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, | 423 | void 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 | ||
499 | got_it: | 512 | got_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; |