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; |
