aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/inode.c')
-rw-r--r--fs/reiserfs/inode.c176
1 files changed, 166 insertions, 10 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index ddde489f1cb2..21db3a705f1e 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -17,11 +17,12 @@
17#include <linux/mpage.h> 17#include <linux/mpage.h>
18#include <linux/writeback.h> 18#include <linux/writeback.h>
19#include <linux/quotaops.h> 19#include <linux/quotaops.h>
20#include <linux/swap.h>
20 21
21static int reiserfs_commit_write(struct file *f, struct page *page, 22int reiserfs_commit_write(struct file *f, struct page *page,
22 unsigned from, unsigned to); 23 unsigned from, unsigned to);
23static int reiserfs_prepare_write(struct file *f, struct page *page, 24int reiserfs_prepare_write(struct file *f, struct page *page,
24 unsigned from, unsigned to); 25 unsigned from, unsigned to);
25 26
26void reiserfs_delete_inode(struct inode *inode) 27void reiserfs_delete_inode(struct inode *inode)
27{ 28{
@@ -2550,8 +2551,71 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
2550 return reiserfs_write_full_page(page, wbc); 2551 return reiserfs_write_full_page(page, wbc);
2551} 2552}
2552 2553
2553static int reiserfs_prepare_write(struct file *f, struct page *page, 2554static int reiserfs_write_begin(struct file *file,
2554 unsigned from, unsigned to) 2555 struct address_space *mapping,
2556 loff_t pos, unsigned len, unsigned flags,
2557 struct page **pagep, void **fsdata)
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
2617int reiserfs_prepare_write(struct file *f, struct page *page,
2618 unsigned from, unsigned to)
2555{ 2619{
2556 struct inode *inode = page->mapping->host; 2620 struct inode *inode = page->mapping->host;
2557 int ret; 2621 int ret;
@@ -2604,8 +2668,100 @@ static sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block)
2604 return generic_block_bmap(as, block, reiserfs_bmap); 2668 return generic_block_bmap(as, block, reiserfs_bmap);
2605} 2669}
2606 2670
2607static int reiserfs_commit_write(struct file *f, struct page *page, 2671static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2608 unsigned from, unsigned to) 2672 loff_t pos, unsigned len, unsigned copied,
2673 struct page *page, void *fsdata)
2674{
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
2763int reiserfs_commit_write(struct file *f, struct page *page,
2764 unsigned from, unsigned to)
2609{ 2765{
2610 struct inode *inode = page->mapping->host; 2766 struct inode *inode = page->mapping->host;
2611 loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + to; 2767 loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + to;
@@ -2999,8 +3155,8 @@ const struct address_space_operations reiserfs_address_space_operations = {
2999 .releasepage = reiserfs_releasepage, 3155 .releasepage = reiserfs_releasepage,
3000 .invalidatepage = reiserfs_invalidatepage, 3156 .invalidatepage = reiserfs_invalidatepage,
3001 .sync_page = block_sync_page, 3157 .sync_page = block_sync_page,
3002 .prepare_write = reiserfs_prepare_write, 3158 .write_begin = reiserfs_write_begin,
3003 .commit_write = reiserfs_commit_write, 3159 .write_end = reiserfs_write_end,
3004 .bmap = reiserfs_aop_bmap, 3160 .bmap = reiserfs_aop_bmap,
3005 .direct_IO = reiserfs_direct_IO, 3161 .direct_IO = reiserfs_direct_IO,
3006 .set_page_dirty = reiserfs_set_page_dirty, 3162 .set_page_dirty = reiserfs_set_page_dirty,