Commit ba9d8cec6c7165e440f9b2413a0464cf3c12fb25

Authored by Vladimir Saveliev
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

... ... @@ -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,
... ... @@ -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:
... ... @@ -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);