Commit ba9d8cec6c7165e440f9b2413a0464cf3c12fb25
Committed by
Linus Torvalds
1 parent
797b4cffdf
reiserfs: convert to new aops
Convert reiserfs to new aops Signed-off-by: Vladimir Saveliev <vs@namesys.com> Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 183 additions and 19 deletions Side-by-side Diff
fs/reiserfs/inode.c
... | ... | @@ -17,11 +17,12 @@ |
17 | 17 | #include <linux/mpage.h> |
18 | 18 | #include <linux/writeback.h> |
19 | 19 | #include <linux/quotaops.h> |
20 | +#include <linux/swap.h> | |
20 | 21 | |
21 | -static int reiserfs_commit_write(struct file *f, struct page *page, | |
22 | - unsigned from, unsigned to); | |
23 | -static int reiserfs_prepare_write(struct file *f, struct page *page, | |
24 | - unsigned from, unsigned to); | |
22 | +int reiserfs_commit_write(struct file *f, struct page *page, | |
23 | + unsigned from, unsigned to); | |
24 | +int reiserfs_prepare_write(struct file *f, struct page *page, | |
25 | + unsigned from, unsigned to); | |
25 | 26 | |
26 | 27 | void reiserfs_delete_inode(struct inode *inode) |
27 | 28 | { |
28 | 29 | |
... | ... | @@ -2550,9 +2551,72 @@ |
2550 | 2551 | return reiserfs_write_full_page(page, wbc); |
2551 | 2552 | } |
2552 | 2553 | |
2553 | -static int reiserfs_prepare_write(struct file *f, struct page *page, | |
2554 | - unsigned from, unsigned to) | |
2554 | +static int reiserfs_write_begin(struct file *file, | |
2555 | + struct address_space *mapping, | |
2556 | + loff_t pos, unsigned len, unsigned flags, | |
2557 | + struct page **pagep, void **fsdata) | |
2555 | 2558 | { |
2559 | + struct inode *inode; | |
2560 | + struct page *page; | |
2561 | + pgoff_t index; | |
2562 | + int ret; | |
2563 | + int old_ref = 0; | |
2564 | + | |
2565 | + index = pos >> PAGE_CACHE_SHIFT; | |
2566 | + page = __grab_cache_page(mapping, index); | |
2567 | + if (!page) | |
2568 | + return -ENOMEM; | |
2569 | + *pagep = page; | |
2570 | + | |
2571 | + inode = mapping->host; | |
2572 | + reiserfs_wait_on_write_block(inode->i_sb); | |
2573 | + fix_tail_page_for_writing(page); | |
2574 | + if (reiserfs_transaction_running(inode->i_sb)) { | |
2575 | + struct reiserfs_transaction_handle *th; | |
2576 | + th = (struct reiserfs_transaction_handle *)current-> | |
2577 | + journal_info; | |
2578 | + BUG_ON(!th->t_refcount); | |
2579 | + BUG_ON(!th->t_trans_id); | |
2580 | + old_ref = th->t_refcount; | |
2581 | + th->t_refcount++; | |
2582 | + } | |
2583 | + ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | |
2584 | + reiserfs_get_block); | |
2585 | + if (ret && reiserfs_transaction_running(inode->i_sb)) { | |
2586 | + struct reiserfs_transaction_handle *th = current->journal_info; | |
2587 | + /* this gets a little ugly. If reiserfs_get_block returned an | |
2588 | + * error and left a transacstion running, we've got to close it, | |
2589 | + * and we've got to free handle if it was a persistent transaction. | |
2590 | + * | |
2591 | + * But, if we had nested into an existing transaction, we need | |
2592 | + * to just drop the ref count on the handle. | |
2593 | + * | |
2594 | + * If old_ref == 0, the transaction is from reiserfs_get_block, | |
2595 | + * and it was a persistent trans. Otherwise, it was nested above. | |
2596 | + */ | |
2597 | + if (th->t_refcount > old_ref) { | |
2598 | + if (old_ref) | |
2599 | + th->t_refcount--; | |
2600 | + else { | |
2601 | + int err; | |
2602 | + reiserfs_write_lock(inode->i_sb); | |
2603 | + err = reiserfs_end_persistent_transaction(th); | |
2604 | + reiserfs_write_unlock(inode->i_sb); | |
2605 | + if (err) | |
2606 | + ret = err; | |
2607 | + } | |
2608 | + } | |
2609 | + } | |
2610 | + if (ret) { | |
2611 | + unlock_page(page); | |
2612 | + page_cache_release(page); | |
2613 | + } | |
2614 | + return ret; | |
2615 | +} | |
2616 | + | |
2617 | +int reiserfs_prepare_write(struct file *f, struct page *page, | |
2618 | + unsigned from, unsigned to) | |
2619 | +{ | |
2556 | 2620 | struct inode *inode = page->mapping->host; |
2557 | 2621 | int ret; |
2558 | 2622 | int old_ref = 0; |
2559 | 2623 | |
... | ... | @@ -2604,10 +2668,102 @@ |
2604 | 2668 | return generic_block_bmap(as, block, reiserfs_bmap); |
2605 | 2669 | } |
2606 | 2670 | |
2607 | -static int reiserfs_commit_write(struct file *f, struct page *page, | |
2608 | - unsigned from, unsigned to) | |
2671 | +static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |
2672 | + loff_t pos, unsigned len, unsigned copied, | |
2673 | + struct page *page, void *fsdata) | |
2609 | 2674 | { |
2610 | 2675 | struct inode *inode = page->mapping->host; |
2676 | + int ret = 0; | |
2677 | + int update_sd = 0; | |
2678 | + struct reiserfs_transaction_handle *th; | |
2679 | + unsigned start; | |
2680 | + | |
2681 | + | |
2682 | + reiserfs_wait_on_write_block(inode->i_sb); | |
2683 | + if (reiserfs_transaction_running(inode->i_sb)) | |
2684 | + th = current->journal_info; | |
2685 | + else | |
2686 | + th = NULL; | |
2687 | + | |
2688 | + start = pos & (PAGE_CACHE_SIZE - 1); | |
2689 | + if (unlikely(copied < len)) { | |
2690 | + if (!PageUptodate(page)) | |
2691 | + copied = 0; | |
2692 | + | |
2693 | + page_zero_new_buffers(page, start + copied, start + len); | |
2694 | + } | |
2695 | + flush_dcache_page(page); | |
2696 | + | |
2697 | + reiserfs_commit_page(inode, page, start, start + copied); | |
2698 | + | |
2699 | + /* generic_commit_write does this for us, but does not update the | |
2700 | + ** transaction tracking stuff when the size changes. So, we have | |
2701 | + ** to do the i_size updates here. | |
2702 | + */ | |
2703 | + pos += copied; | |
2704 | + if (pos > inode->i_size) { | |
2705 | + struct reiserfs_transaction_handle myth; | |
2706 | + reiserfs_write_lock(inode->i_sb); | |
2707 | + /* If the file have grown beyond the border where it | |
2708 | + can have a tail, unmark it as needing a tail | |
2709 | + packing */ | |
2710 | + if ((have_large_tails(inode->i_sb) | |
2711 | + && inode->i_size > i_block_size(inode) * 4) | |
2712 | + || (have_small_tails(inode->i_sb) | |
2713 | + && inode->i_size > i_block_size(inode))) | |
2714 | + REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; | |
2715 | + | |
2716 | + ret = journal_begin(&myth, inode->i_sb, 1); | |
2717 | + if (ret) { | |
2718 | + reiserfs_write_unlock(inode->i_sb); | |
2719 | + goto journal_error; | |
2720 | + } | |
2721 | + reiserfs_update_inode_transaction(inode); | |
2722 | + inode->i_size = pos; | |
2723 | + /* | |
2724 | + * this will just nest into our transaction. It's important | |
2725 | + * to use mark_inode_dirty so the inode gets pushed around on the | |
2726 | + * dirty lists, and so that O_SYNC works as expected | |
2727 | + */ | |
2728 | + mark_inode_dirty(inode); | |
2729 | + reiserfs_update_sd(&myth, inode); | |
2730 | + update_sd = 1; | |
2731 | + ret = journal_end(&myth, inode->i_sb, 1); | |
2732 | + reiserfs_write_unlock(inode->i_sb); | |
2733 | + if (ret) | |
2734 | + goto journal_error; | |
2735 | + } | |
2736 | + if (th) { | |
2737 | + reiserfs_write_lock(inode->i_sb); | |
2738 | + if (!update_sd) | |
2739 | + mark_inode_dirty(inode); | |
2740 | + ret = reiserfs_end_persistent_transaction(th); | |
2741 | + reiserfs_write_unlock(inode->i_sb); | |
2742 | + if (ret) | |
2743 | + goto out; | |
2744 | + } | |
2745 | + | |
2746 | + out: | |
2747 | + unlock_page(page); | |
2748 | + page_cache_release(page); | |
2749 | + return ret == 0 ? copied : ret; | |
2750 | + | |
2751 | + journal_error: | |
2752 | + if (th) { | |
2753 | + reiserfs_write_lock(inode->i_sb); | |
2754 | + if (!update_sd) | |
2755 | + reiserfs_update_sd(th, inode); | |
2756 | + ret = reiserfs_end_persistent_transaction(th); | |
2757 | + reiserfs_write_unlock(inode->i_sb); | |
2758 | + } | |
2759 | + | |
2760 | + goto out; | |
2761 | +} | |
2762 | + | |
2763 | +int reiserfs_commit_write(struct file *f, struct page *page, | |
2764 | + unsigned from, unsigned to) | |
2765 | +{ | |
2766 | + struct inode *inode = page->mapping->host; | |
2611 | 2767 | loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + to; |
2612 | 2768 | int ret = 0; |
2613 | 2769 | int update_sd = 0; |
... | ... | @@ -2999,8 +3155,8 @@ |
2999 | 3155 | .releasepage = reiserfs_releasepage, |
3000 | 3156 | .invalidatepage = reiserfs_invalidatepage, |
3001 | 3157 | .sync_page = block_sync_page, |
3002 | - .prepare_write = reiserfs_prepare_write, | |
3003 | - .commit_write = reiserfs_commit_write, | |
3158 | + .write_begin = reiserfs_write_begin, | |
3159 | + .write_end = reiserfs_write_end, | |
3004 | 3160 | .bmap = reiserfs_aop_bmap, |
3005 | 3161 | .direct_IO = reiserfs_direct_IO, |
3006 | 3162 | .set_page_dirty = reiserfs_set_page_dirty, |
fs/reiserfs/ioctl.c
... | ... | @@ -128,6 +128,10 @@ |
128 | 128 | } |
129 | 129 | #endif |
130 | 130 | |
131 | +int reiserfs_commit_write(struct file *f, struct page *page, | |
132 | + unsigned from, unsigned to); | |
133 | +int reiserfs_prepare_write(struct file *f, struct page *page, | |
134 | + unsigned from, unsigned to); | |
131 | 135 | /* |
132 | 136 | ** reiserfs_unpack |
133 | 137 | ** Function try to convert tail from direct item into indirect. |
134 | 138 | |
... | ... | @@ -175,15 +179,13 @@ |
175 | 179 | if (!page) { |
176 | 180 | goto out; |
177 | 181 | } |
178 | - retval = | |
179 | - mapping->a_ops->prepare_write(NULL, page, write_from, write_from); | |
182 | + retval = reiserfs_prepare_write(NULL, page, write_from, write_from); | |
180 | 183 | if (retval) |
181 | 184 | goto out_unlock; |
182 | 185 | |
183 | 186 | /* conversion can change page contents, must flush */ |
184 | 187 | flush_dcache_page(page); |
185 | - retval = | |
186 | - mapping->a_ops->commit_write(NULL, page, write_from, write_from); | |
188 | + retval = reiserfs_commit_write(NULL, page, write_from, write_from); | |
187 | 189 | REISERFS_I(inode)->i_flags |= i_nopack_mask; |
188 | 190 | |
189 | 191 | out_unlock: |
fs/reiserfs/xattr.c
... | ... | @@ -426,6 +426,12 @@ |
426 | 426 | return csum_partial(msg, len, 0); |
427 | 427 | } |
428 | 428 | |
429 | +int reiserfs_commit_write(struct file *f, struct page *page, | |
430 | + unsigned from, unsigned to); | |
431 | +int reiserfs_prepare_write(struct file *f, struct page *page, | |
432 | + unsigned from, unsigned to); | |
433 | + | |
434 | + | |
429 | 435 | /* Generic extended attribute operations that can be used by xa plugins */ |
430 | 436 | |
431 | 437 | /* |
432 | 438 | |
... | ... | @@ -512,15 +518,15 @@ |
512 | 518 | rxh->h_hash = cpu_to_le32(xahash); |
513 | 519 | } |
514 | 520 | |
515 | - err = mapping->a_ops->prepare_write(fp, page, page_offset, | |
516 | - page_offset + chunk + skip); | |
521 | + err = reiserfs_prepare_write(fp, page, page_offset, | |
522 | + page_offset + chunk + skip); | |
517 | 523 | if (!err) { |
518 | 524 | if (buffer) |
519 | 525 | memcpy(data + skip, buffer + buffer_pos, chunk); |
520 | 526 | err = |
521 | - mapping->a_ops->commit_write(fp, page, page_offset, | |
522 | - page_offset + chunk + | |
523 | - skip); | |
527 | + reiserfs_commit_write(fp, page, page_offset, | |
528 | + page_offset + chunk + | |
529 | + skip); | |
524 | 530 | } |
525 | 531 | unlock_page(page); |
526 | 532 | reiserfs_put_page(page); |