diff options
Diffstat (limited to 'fs/reiserfs/inode.c')
-rw-r--r-- | fs/reiserfs/inode.c | 97 |
1 files changed, 54 insertions, 43 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index a14d6cd9eeda..3a28e7751b3c 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -251,7 +251,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block, | |||
251 | struct cpu_key key; | 251 | struct cpu_key key; |
252 | struct buffer_head *bh; | 252 | struct buffer_head *bh; |
253 | struct item_head *ih, tmp_ih; | 253 | struct item_head *ih, tmp_ih; |
254 | int fs_gen; | ||
255 | b_blocknr_t blocknr; | 254 | b_blocknr_t blocknr; |
256 | char *p = NULL; | 255 | char *p = NULL; |
257 | int chars; | 256 | int chars; |
@@ -265,7 +264,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block, | |||
265 | (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY, | 264 | (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY, |
266 | 3); | 265 | 3); |
267 | 266 | ||
268 | research: | ||
269 | result = search_for_position_by_key(inode->i_sb, &key, &path); | 267 | result = search_for_position_by_key(inode->i_sb, &key, &path); |
270 | if (result != POSITION_FOUND) { | 268 | if (result != POSITION_FOUND) { |
271 | pathrelse(&path); | 269 | pathrelse(&path); |
@@ -340,7 +338,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block, | |||
340 | } | 338 | } |
341 | // read file tail into part of page | 339 | // read file tail into part of page |
342 | offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1); | 340 | offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1); |
343 | fs_gen = get_generation(inode->i_sb); | ||
344 | copy_item_head(&tmp_ih, ih); | 341 | copy_item_head(&tmp_ih, ih); |
345 | 342 | ||
346 | /* we only want to kmap if we are reading the tail into the page. | 343 | /* we only want to kmap if we are reading the tail into the page. |
@@ -348,13 +345,9 @@ static int _get_block_create_0(struct inode *inode, sector_t block, | |||
348 | ** sure we need to. But, this means the item might move if | 345 | ** sure we need to. But, this means the item might move if |
349 | ** kmap schedules | 346 | ** kmap schedules |
350 | */ | 347 | */ |
351 | if (!p) { | 348 | if (!p) |
352 | p = (char *)kmap(bh_result->b_page); | 349 | p = (char *)kmap(bh_result->b_page); |
353 | if (fs_changed(fs_gen, inode->i_sb) | 350 | |
354 | && item_moved(&tmp_ih, &path)) { | ||
355 | goto research; | ||
356 | } | ||
357 | } | ||
358 | p += offset; | 351 | p += offset; |
359 | memset(p, 0, inode->i_sb->s_blocksize); | 352 | memset(p, 0, inode->i_sb->s_blocksize); |
360 | do { | 353 | do { |
@@ -489,10 +482,14 @@ static int reiserfs_get_blocks_direct_io(struct inode *inode, | |||
489 | disappeared */ | 482 | disappeared */ |
490 | if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) { | 483 | if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) { |
491 | int err; | 484 | int err; |
492 | lock_kernel(); | 485 | |
486 | reiserfs_write_lock(inode->i_sb); | ||
487 | |||
493 | err = reiserfs_commit_for_inode(inode); | 488 | err = reiserfs_commit_for_inode(inode); |
494 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; | 489 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; |
495 | unlock_kernel(); | 490 | |
491 | reiserfs_write_unlock(inode->i_sb); | ||
492 | |||
496 | if (err < 0) | 493 | if (err < 0) |
497 | ret = err; | 494 | ret = err; |
498 | } | 495 | } |
@@ -601,6 +598,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
601 | __le32 *item; | 598 | __le32 *item; |
602 | int done; | 599 | int done; |
603 | int fs_gen; | 600 | int fs_gen; |
601 | int lock_depth; | ||
604 | struct reiserfs_transaction_handle *th = NULL; | 602 | struct reiserfs_transaction_handle *th = NULL; |
605 | /* space reserved in transaction batch: | 603 | /* space reserved in transaction batch: |
606 | . 3 balancings in direct->indirect conversion | 604 | . 3 balancings in direct->indirect conversion |
@@ -616,12 +614,11 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
616 | loff_t new_offset = | 614 | loff_t new_offset = |
617 | (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1; | 615 | (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1; |
618 | 616 | ||
619 | /* bad.... */ | 617 | lock_depth = reiserfs_write_lock_once(inode->i_sb); |
620 | reiserfs_write_lock(inode->i_sb); | ||
621 | version = get_inode_item_key_version(inode); | 618 | version = get_inode_item_key_version(inode); |
622 | 619 | ||
623 | if (!file_capable(inode, block)) { | 620 | if (!file_capable(inode, block)) { |
624 | reiserfs_write_unlock(inode->i_sb); | 621 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
625 | return -EFBIG; | 622 | return -EFBIG; |
626 | } | 623 | } |
627 | 624 | ||
@@ -633,7 +630,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
633 | /* find number of block-th logical block of the file */ | 630 | /* find number of block-th logical block of the file */ |
634 | ret = _get_block_create_0(inode, block, bh_result, | 631 | ret = _get_block_create_0(inode, block, bh_result, |
635 | create | GET_BLOCK_READ_DIRECT); | 632 | create | GET_BLOCK_READ_DIRECT); |
636 | reiserfs_write_unlock(inode->i_sb); | 633 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
637 | return ret; | 634 | return ret; |
638 | } | 635 | } |
639 | /* | 636 | /* |
@@ -751,7 +748,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
751 | if (!dangle && th) | 748 | if (!dangle && th) |
752 | retval = reiserfs_end_persistent_transaction(th); | 749 | retval = reiserfs_end_persistent_transaction(th); |
753 | 750 | ||
754 | reiserfs_write_unlock(inode->i_sb); | 751 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
755 | 752 | ||
756 | /* the item was found, so new blocks were not added to the file | 753 | /* the item was found, so new blocks were not added to the file |
757 | ** there is no need to make sure the inode is updated with this | 754 | ** there is no need to make sure the inode is updated with this |
@@ -935,7 +932,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
935 | if (blocks_needed == 1) { | 932 | if (blocks_needed == 1) { |
936 | un = &unf_single; | 933 | un = &unf_single; |
937 | } else { | 934 | } else { |
938 | un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC); // We need to avoid scheduling. | 935 | un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_NOFS); |
939 | if (!un) { | 936 | if (!un) { |
940 | un = &unf_single; | 937 | un = &unf_single; |
941 | blocks_needed = 1; | 938 | blocks_needed = 1; |
@@ -997,10 +994,16 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
997 | if (retval) | 994 | if (retval) |
998 | goto failure; | 995 | goto failure; |
999 | } | 996 | } |
1000 | /* inserting indirect pointers for a hole can take a | 997 | /* |
1001 | ** long time. reschedule if needed | 998 | * inserting indirect pointers for a hole can take a |
999 | * long time. reschedule if needed and also release the write | ||
1000 | * lock for others. | ||
1002 | */ | 1001 | */ |
1003 | cond_resched(); | 1002 | if (need_resched()) { |
1003 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
1004 | schedule(); | ||
1005 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | ||
1006 | } | ||
1004 | 1007 | ||
1005 | retval = search_for_position_by_key(inode->i_sb, &key, &path); | 1008 | retval = search_for_position_by_key(inode->i_sb, &key, &path); |
1006 | if (retval == IO_ERROR) { | 1009 | if (retval == IO_ERROR) { |
@@ -1035,7 +1038,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
1035 | retval = err; | 1038 | retval = err; |
1036 | } | 1039 | } |
1037 | 1040 | ||
1038 | reiserfs_write_unlock(inode->i_sb); | 1041 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
1039 | reiserfs_check_path(&path); | 1042 | reiserfs_check_path(&path); |
1040 | return retval; | 1043 | return retval; |
1041 | } | 1044 | } |
@@ -2072,8 +2075,9 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps) | |||
2072 | int error; | 2075 | int error; |
2073 | struct buffer_head *bh = NULL; | 2076 | struct buffer_head *bh = NULL; |
2074 | int err2; | 2077 | int err2; |
2078 | int lock_depth; | ||
2075 | 2079 | ||
2076 | reiserfs_write_lock(inode->i_sb); | 2080 | lock_depth = reiserfs_write_lock_once(inode->i_sb); |
2077 | 2081 | ||
2078 | if (inode->i_size > 0) { | 2082 | if (inode->i_size > 0) { |
2079 | error = grab_tail_page(inode, &page, &bh); | 2083 | error = grab_tail_page(inode, &page, &bh); |
@@ -2142,14 +2146,17 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps) | |||
2142 | page_cache_release(page); | 2146 | page_cache_release(page); |
2143 | } | 2147 | } |
2144 | 2148 | ||
2145 | reiserfs_write_unlock(inode->i_sb); | 2149 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
2150 | |||
2146 | return 0; | 2151 | return 0; |
2147 | out: | 2152 | out: |
2148 | if (page) { | 2153 | if (page) { |
2149 | unlock_page(page); | 2154 | unlock_page(page); |
2150 | page_cache_release(page); | 2155 | page_cache_release(page); |
2151 | } | 2156 | } |
2152 | reiserfs_write_unlock(inode->i_sb); | 2157 | |
2158 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
2159 | |||
2153 | return error; | 2160 | return error; |
2154 | } | 2161 | } |
2155 | 2162 | ||
@@ -2608,7 +2615,10 @@ int reiserfs_prepare_write(struct file *f, struct page *page, | |||
2608 | int ret; | 2615 | int ret; |
2609 | int old_ref = 0; | 2616 | int old_ref = 0; |
2610 | 2617 | ||
2618 | reiserfs_write_unlock(inode->i_sb); | ||
2611 | reiserfs_wait_on_write_block(inode->i_sb); | 2619 | reiserfs_wait_on_write_block(inode->i_sb); |
2620 | reiserfs_write_lock(inode->i_sb); | ||
2621 | |||
2612 | fix_tail_page_for_writing(page); | 2622 | fix_tail_page_for_writing(page); |
2613 | if (reiserfs_transaction_running(inode->i_sb)) { | 2623 | if (reiserfs_transaction_running(inode->i_sb)) { |
2614 | struct reiserfs_transaction_handle *th; | 2624 | struct reiserfs_transaction_handle *th; |
@@ -2664,6 +2674,8 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2664 | int update_sd = 0; | 2674 | int update_sd = 0; |
2665 | struct reiserfs_transaction_handle *th; | 2675 | struct reiserfs_transaction_handle *th; |
2666 | unsigned start; | 2676 | unsigned start; |
2677 | int lock_depth = 0; | ||
2678 | bool locked = false; | ||
2667 | 2679 | ||
2668 | if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) | 2680 | if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) |
2669 | pos ++; | 2681 | pos ++; |
@@ -2690,9 +2702,11 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2690 | ** to do the i_size updates here. | 2702 | ** to do the i_size updates here. |
2691 | */ | 2703 | */ |
2692 | pos += copied; | 2704 | pos += copied; |
2705 | |||
2693 | if (pos > inode->i_size) { | 2706 | if (pos > inode->i_size) { |
2694 | struct reiserfs_transaction_handle myth; | 2707 | struct reiserfs_transaction_handle myth; |
2695 | reiserfs_write_lock(inode->i_sb); | 2708 | lock_depth = reiserfs_write_lock_once(inode->i_sb); |
2709 | locked = true; | ||
2696 | /* If the file have grown beyond the border where it | 2710 | /* If the file have grown beyond the border where it |
2697 | can have a tail, unmark it as needing a tail | 2711 | can have a tail, unmark it as needing a tail |
2698 | packing */ | 2712 | packing */ |
@@ -2703,10 +2717,9 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2703 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; | 2717 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; |
2704 | 2718 | ||
2705 | ret = journal_begin(&myth, inode->i_sb, 1); | 2719 | ret = journal_begin(&myth, inode->i_sb, 1); |
2706 | if (ret) { | 2720 | if (ret) |
2707 | reiserfs_write_unlock(inode->i_sb); | ||
2708 | goto journal_error; | 2721 | goto journal_error; |
2709 | } | 2722 | |
2710 | reiserfs_update_inode_transaction(inode); | 2723 | reiserfs_update_inode_transaction(inode); |
2711 | inode->i_size = pos; | 2724 | inode->i_size = pos; |
2712 | /* | 2725 | /* |
@@ -2718,34 +2731,36 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2718 | reiserfs_update_sd(&myth, inode); | 2731 | reiserfs_update_sd(&myth, inode); |
2719 | update_sd = 1; | 2732 | update_sd = 1; |
2720 | ret = journal_end(&myth, inode->i_sb, 1); | 2733 | ret = journal_end(&myth, inode->i_sb, 1); |
2721 | reiserfs_write_unlock(inode->i_sb); | ||
2722 | if (ret) | 2734 | if (ret) |
2723 | goto journal_error; | 2735 | goto journal_error; |
2724 | } | 2736 | } |
2725 | if (th) { | 2737 | if (th) { |
2726 | reiserfs_write_lock(inode->i_sb); | 2738 | if (!locked) { |
2739 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | ||
2740 | locked = true; | ||
2741 | } | ||
2727 | if (!update_sd) | 2742 | if (!update_sd) |
2728 | mark_inode_dirty(inode); | 2743 | mark_inode_dirty(inode); |
2729 | ret = reiserfs_end_persistent_transaction(th); | 2744 | ret = reiserfs_end_persistent_transaction(th); |
2730 | reiserfs_write_unlock(inode->i_sb); | ||
2731 | if (ret) | 2745 | if (ret) |
2732 | goto out; | 2746 | goto out; |
2733 | } | 2747 | } |
2734 | 2748 | ||
2735 | out: | 2749 | out: |
2750 | if (locked) | ||
2751 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
2736 | unlock_page(page); | 2752 | unlock_page(page); |
2737 | page_cache_release(page); | 2753 | page_cache_release(page); |
2738 | return ret == 0 ? copied : ret; | 2754 | return ret == 0 ? copied : ret; |
2739 | 2755 | ||
2740 | journal_error: | 2756 | journal_error: |
2757 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
2758 | locked = false; | ||
2741 | if (th) { | 2759 | if (th) { |
2742 | reiserfs_write_lock(inode->i_sb); | ||
2743 | if (!update_sd) | 2760 | if (!update_sd) |
2744 | reiserfs_update_sd(th, inode); | 2761 | reiserfs_update_sd(th, inode); |
2745 | ret = reiserfs_end_persistent_transaction(th); | 2762 | ret = reiserfs_end_persistent_transaction(th); |
2746 | reiserfs_write_unlock(inode->i_sb); | ||
2747 | } | 2763 | } |
2748 | |||
2749 | goto out; | 2764 | goto out; |
2750 | } | 2765 | } |
2751 | 2766 | ||
@@ -2758,7 +2773,10 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2758 | int update_sd = 0; | 2773 | int update_sd = 0; |
2759 | struct reiserfs_transaction_handle *th = NULL; | 2774 | struct reiserfs_transaction_handle *th = NULL; |
2760 | 2775 | ||
2776 | reiserfs_write_unlock(inode->i_sb); | ||
2761 | reiserfs_wait_on_write_block(inode->i_sb); | 2777 | reiserfs_wait_on_write_block(inode->i_sb); |
2778 | reiserfs_write_lock(inode->i_sb); | ||
2779 | |||
2762 | if (reiserfs_transaction_running(inode->i_sb)) { | 2780 | if (reiserfs_transaction_running(inode->i_sb)) { |
2763 | th = current->journal_info; | 2781 | th = current->journal_info; |
2764 | } | 2782 | } |
@@ -2770,7 +2788,6 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2770 | */ | 2788 | */ |
2771 | if (pos > inode->i_size) { | 2789 | if (pos > inode->i_size) { |
2772 | struct reiserfs_transaction_handle myth; | 2790 | struct reiserfs_transaction_handle myth; |
2773 | reiserfs_write_lock(inode->i_sb); | ||
2774 | /* If the file have grown beyond the border where it | 2791 | /* If the file have grown beyond the border where it |
2775 | can have a tail, unmark it as needing a tail | 2792 | can have a tail, unmark it as needing a tail |
2776 | packing */ | 2793 | packing */ |
@@ -2781,10 +2798,9 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2781 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; | 2798 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; |
2782 | 2799 | ||
2783 | ret = journal_begin(&myth, inode->i_sb, 1); | 2800 | ret = journal_begin(&myth, inode->i_sb, 1); |
2784 | if (ret) { | 2801 | if (ret) |
2785 | reiserfs_write_unlock(inode->i_sb); | ||
2786 | goto journal_error; | 2802 | goto journal_error; |
2787 | } | 2803 | |
2788 | reiserfs_update_inode_transaction(inode); | 2804 | reiserfs_update_inode_transaction(inode); |
2789 | inode->i_size = pos; | 2805 | inode->i_size = pos; |
2790 | /* | 2806 | /* |
@@ -2796,16 +2812,13 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2796 | reiserfs_update_sd(&myth, inode); | 2812 | reiserfs_update_sd(&myth, inode); |
2797 | update_sd = 1; | 2813 | update_sd = 1; |
2798 | ret = journal_end(&myth, inode->i_sb, 1); | 2814 | ret = journal_end(&myth, inode->i_sb, 1); |
2799 | reiserfs_write_unlock(inode->i_sb); | ||
2800 | if (ret) | 2815 | if (ret) |
2801 | goto journal_error; | 2816 | goto journal_error; |
2802 | } | 2817 | } |
2803 | if (th) { | 2818 | if (th) { |
2804 | reiserfs_write_lock(inode->i_sb); | ||
2805 | if (!update_sd) | 2819 | if (!update_sd) |
2806 | mark_inode_dirty(inode); | 2820 | mark_inode_dirty(inode); |
2807 | ret = reiserfs_end_persistent_transaction(th); | 2821 | ret = reiserfs_end_persistent_transaction(th); |
2808 | reiserfs_write_unlock(inode->i_sb); | ||
2809 | if (ret) | 2822 | if (ret) |
2810 | goto out; | 2823 | goto out; |
2811 | } | 2824 | } |
@@ -2815,11 +2828,9 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2815 | 2828 | ||
2816 | journal_error: | 2829 | journal_error: |
2817 | if (th) { | 2830 | if (th) { |
2818 | reiserfs_write_lock(inode->i_sb); | ||
2819 | if (!update_sd) | 2831 | if (!update_sd) |
2820 | reiserfs_update_sd(th, inode); | 2832 | reiserfs_update_sd(th, inode); |
2821 | ret = reiserfs_end_persistent_transaction(th); | 2833 | ret = reiserfs_end_persistent_transaction(th); |
2822 | reiserfs_write_unlock(inode->i_sb); | ||
2823 | } | 2834 | } |
2824 | 2835 | ||
2825 | return ret; | 2836 | return ret; |