diff options
author | Jeff Mahoney <jeffm@suse.com> | 2013-08-08 17:34:46 -0400 |
---|---|---|
committer | Jeff Mahoney <jeffm@suse.de> | 2013-08-08 17:34:46 -0400 |
commit | 278f6679f454bf185a07d9a4ca355b153482d17a (patch) | |
tree | ffead073e67cfdc1ddfc3949ebc93c06dcaaab8f /fs/reiserfs/inode.c | |
parent | 4c05141df57f4ffc1a9a28f1925434924179bfe4 (diff) |
reiserfs: locking, handle nested locks properly
The reiserfs write lock replaced the BKL and uses similar semantics.
Frederic's locking code makes a distinction between when the lock is nested
and when it's being acquired/released, but I don't think that's the right
distinction to make.
The right distinction is between the lock being released at end-of-use and
the lock being released for a schedule. The unlock should return the depth
and the lock should restore it, rather than the other way around as it is now.
This patch implements that and adds a number of places where the lock
should be dropped.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Diffstat (limited to 'fs/reiserfs/inode.c')
-rw-r--r-- | fs/reiserfs/inode.c | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index bf1331a0f04b..4a3a57c66820 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -41,11 +41,10 @@ void reiserfs_evict_inode(struct inode *inode) | |||
41 | 41 | ||
42 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ | 42 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ |
43 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ | 43 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ |
44 | int depth; | ||
45 | 44 | ||
46 | reiserfs_delete_xattrs(inode); | 45 | reiserfs_delete_xattrs(inode); |
47 | 46 | ||
48 | depth = reiserfs_write_lock_once(inode->i_sb); | 47 | reiserfs_write_lock(inode->i_sb); |
49 | 48 | ||
50 | if (journal_begin(&th, inode->i_sb, jbegin_count)) | 49 | if (journal_begin(&th, inode->i_sb, jbegin_count)) |
51 | goto out; | 50 | goto out; |
@@ -74,7 +73,7 @@ void reiserfs_evict_inode(struct inode *inode) | |||
74 | remove_save_link(inode, 0 /* not truncate */ ); /* we can't do anything | 73 | remove_save_link(inode, 0 /* not truncate */ ); /* we can't do anything |
75 | * about an error here */ | 74 | * about an error here */ |
76 | out: | 75 | out: |
77 | reiserfs_write_unlock_once(inode->i_sb, depth); | 76 | reiserfs_write_unlock(inode->i_sb); |
78 | } else { | 77 | } else { |
79 | /* no object items are in the tree */ | 78 | /* no object items are in the tree */ |
80 | ; | 79 | ; |
@@ -611,7 +610,6 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
611 | __le32 *item; | 610 | __le32 *item; |
612 | int done; | 611 | int done; |
613 | int fs_gen; | 612 | int fs_gen; |
614 | int lock_depth; | ||
615 | struct reiserfs_transaction_handle *th = NULL; | 613 | struct reiserfs_transaction_handle *th = NULL; |
616 | /* space reserved in transaction batch: | 614 | /* space reserved in transaction batch: |
617 | . 3 balancings in direct->indirect conversion | 615 | . 3 balancings in direct->indirect conversion |
@@ -627,11 +625,11 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
627 | loff_t new_offset = | 625 | loff_t new_offset = |
628 | (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1; | 626 | (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1; |
629 | 627 | ||
630 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | 628 | reiserfs_write_lock(inode->i_sb); |
631 | version = get_inode_item_key_version(inode); | 629 | version = get_inode_item_key_version(inode); |
632 | 630 | ||
633 | if (!file_capable(inode, block)) { | 631 | if (!file_capable(inode, block)) { |
634 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 632 | reiserfs_write_unlock(inode->i_sb); |
635 | return -EFBIG; | 633 | return -EFBIG; |
636 | } | 634 | } |
637 | 635 | ||
@@ -643,7 +641,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
643 | /* find number of block-th logical block of the file */ | 641 | /* find number of block-th logical block of the file */ |
644 | ret = _get_block_create_0(inode, block, bh_result, | 642 | ret = _get_block_create_0(inode, block, bh_result, |
645 | create | GET_BLOCK_READ_DIRECT); | 643 | create | GET_BLOCK_READ_DIRECT); |
646 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 644 | reiserfs_write_unlock(inode->i_sb); |
647 | return ret; | 645 | return ret; |
648 | } | 646 | } |
649 | /* | 647 | /* |
@@ -761,7 +759,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
761 | if (!dangle && th) | 759 | if (!dangle && th) |
762 | retval = reiserfs_end_persistent_transaction(th); | 760 | retval = reiserfs_end_persistent_transaction(th); |
763 | 761 | ||
764 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 762 | reiserfs_write_unlock(inode->i_sb); |
765 | 763 | ||
766 | /* the item was found, so new blocks were not added to the file | 764 | /* the item was found, so new blocks were not added to the file |
767 | ** there is no need to make sure the inode is updated with this | 765 | ** there is no need to make sure the inode is updated with this |
@@ -1012,11 +1010,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
1012 | * long time. reschedule if needed and also release the write | 1010 | * long time. reschedule if needed and also release the write |
1013 | * lock for others. | 1011 | * lock for others. |
1014 | */ | 1012 | */ |
1015 | if (need_resched()) { | 1013 | reiserfs_cond_resched(inode->i_sb); |
1016 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
1017 | schedule(); | ||
1018 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | ||
1019 | } | ||
1020 | 1014 | ||
1021 | retval = search_for_position_by_key(inode->i_sb, &key, &path); | 1015 | retval = search_for_position_by_key(inode->i_sb, &key, &path); |
1022 | if (retval == IO_ERROR) { | 1016 | if (retval == IO_ERROR) { |
@@ -1051,7 +1045,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
1051 | retval = err; | 1045 | retval = err; |
1052 | } | 1046 | } |
1053 | 1047 | ||
1054 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 1048 | reiserfs_write_unlock(inode->i_sb); |
1055 | reiserfs_check_path(&path); | 1049 | reiserfs_check_path(&path); |
1056 | return retval; | 1050 | return retval; |
1057 | } | 1051 | } |
@@ -1510,14 +1504,15 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key) | |||
1510 | { | 1504 | { |
1511 | struct inode *inode; | 1505 | struct inode *inode; |
1512 | struct reiserfs_iget_args args; | 1506 | struct reiserfs_iget_args args; |
1507 | int depth; | ||
1513 | 1508 | ||
1514 | args.objectid = key->on_disk_key.k_objectid; | 1509 | args.objectid = key->on_disk_key.k_objectid; |
1515 | args.dirid = key->on_disk_key.k_dir_id; | 1510 | args.dirid = key->on_disk_key.k_dir_id; |
1516 | reiserfs_write_unlock(s); | 1511 | depth = reiserfs_write_unlock_nested(s); |
1517 | inode = iget5_locked(s, key->on_disk_key.k_objectid, | 1512 | inode = iget5_locked(s, key->on_disk_key.k_objectid, |
1518 | reiserfs_find_actor, reiserfs_init_locked_inode, | 1513 | reiserfs_find_actor, reiserfs_init_locked_inode, |
1519 | (void *)(&args)); | 1514 | (void *)(&args)); |
1520 | reiserfs_write_lock(s); | 1515 | reiserfs_write_lock_nested(s, depth); |
1521 | if (!inode) | 1516 | if (!inode) |
1522 | return ERR_PTR(-ENOMEM); | 1517 | return ERR_PTR(-ENOMEM); |
1523 | 1518 | ||
@@ -1781,6 +1776,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1781 | struct stat_data sd; | 1776 | struct stat_data sd; |
1782 | int retval; | 1777 | int retval; |
1783 | int err; | 1778 | int err; |
1779 | int depth; | ||
1784 | 1780 | ||
1785 | BUG_ON(!th->t_trans_id); | 1781 | BUG_ON(!th->t_trans_id); |
1786 | 1782 | ||
@@ -1813,10 +1809,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1813 | memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); | 1809 | memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); |
1814 | args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); | 1810 | args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); |
1815 | 1811 | ||
1816 | reiserfs_write_unlock(inode->i_sb); | 1812 | depth = reiserfs_write_unlock_nested(inode->i_sb); |
1817 | err = insert_inode_locked4(inode, args.objectid, | 1813 | err = insert_inode_locked4(inode, args.objectid, |
1818 | reiserfs_find_actor, &args); | 1814 | reiserfs_find_actor, &args); |
1819 | reiserfs_write_lock(inode->i_sb); | 1815 | reiserfs_write_lock_nested(inode->i_sb, depth); |
1820 | if (err) { | 1816 | if (err) { |
1821 | err = -EINVAL; | 1817 | err = -EINVAL; |
1822 | goto out_bad_inode; | 1818 | goto out_bad_inode; |
@@ -2108,9 +2104,8 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps) | |||
2108 | int error; | 2104 | int error; |
2109 | struct buffer_head *bh = NULL; | 2105 | struct buffer_head *bh = NULL; |
2110 | int err2; | 2106 | int err2; |
2111 | int lock_depth; | ||
2112 | 2107 | ||
2113 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | 2108 | reiserfs_write_lock(inode->i_sb); |
2114 | 2109 | ||
2115 | if (inode->i_size > 0) { | 2110 | if (inode->i_size > 0) { |
2116 | error = grab_tail_page(inode, &page, &bh); | 2111 | error = grab_tail_page(inode, &page, &bh); |
@@ -2179,7 +2174,7 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps) | |||
2179 | page_cache_release(page); | 2174 | page_cache_release(page); |
2180 | } | 2175 | } |
2181 | 2176 | ||
2182 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 2177 | reiserfs_write_unlock(inode->i_sb); |
2183 | 2178 | ||
2184 | return 0; | 2179 | return 0; |
2185 | out: | 2180 | out: |
@@ -2188,7 +2183,7 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps) | |||
2188 | page_cache_release(page); | 2183 | page_cache_release(page); |
2189 | } | 2184 | } |
2190 | 2185 | ||
2191 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 2186 | reiserfs_write_unlock(inode->i_sb); |
2192 | 2187 | ||
2193 | return error; | 2188 | return error; |
2194 | } | 2189 | } |
@@ -2653,10 +2648,11 @@ int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len) | |||
2653 | struct inode *inode = page->mapping->host; | 2648 | struct inode *inode = page->mapping->host; |
2654 | int ret; | 2649 | int ret; |
2655 | int old_ref = 0; | 2650 | int old_ref = 0; |
2651 | int depth; | ||
2656 | 2652 | ||
2657 | reiserfs_write_unlock(inode->i_sb); | 2653 | depth = reiserfs_write_unlock_nested(inode->i_sb); |
2658 | reiserfs_wait_on_write_block(inode->i_sb); | 2654 | reiserfs_wait_on_write_block(inode->i_sb); |
2659 | reiserfs_write_lock(inode->i_sb); | 2655 | reiserfs_write_lock_nested(inode->i_sb, depth); |
2660 | 2656 | ||
2661 | fix_tail_page_for_writing(page); | 2657 | fix_tail_page_for_writing(page); |
2662 | if (reiserfs_transaction_running(inode->i_sb)) { | 2658 | if (reiserfs_transaction_running(inode->i_sb)) { |
@@ -2713,7 +2709,6 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2713 | int update_sd = 0; | 2709 | int update_sd = 0; |
2714 | struct reiserfs_transaction_handle *th; | 2710 | struct reiserfs_transaction_handle *th; |
2715 | unsigned start; | 2711 | unsigned start; |
2716 | int lock_depth = 0; | ||
2717 | bool locked = false; | 2712 | bool locked = false; |
2718 | 2713 | ||
2719 | if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) | 2714 | if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) |
@@ -2742,7 +2737,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2742 | */ | 2737 | */ |
2743 | if (pos + copied > inode->i_size) { | 2738 | if (pos + copied > inode->i_size) { |
2744 | struct reiserfs_transaction_handle myth; | 2739 | struct reiserfs_transaction_handle myth; |
2745 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | 2740 | reiserfs_write_lock(inode->i_sb); |
2746 | locked = true; | 2741 | locked = true; |
2747 | /* If the file have grown beyond the border where it | 2742 | /* If the file have grown beyond the border where it |
2748 | can have a tail, unmark it as needing a tail | 2743 | can have a tail, unmark it as needing a tail |
@@ -2773,7 +2768,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2773 | } | 2768 | } |
2774 | if (th) { | 2769 | if (th) { |
2775 | if (!locked) { | 2770 | if (!locked) { |
2776 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | 2771 | reiserfs_write_lock(inode->i_sb); |
2777 | locked = true; | 2772 | locked = true; |
2778 | } | 2773 | } |
2779 | if (!update_sd) | 2774 | if (!update_sd) |
@@ -2785,7 +2780,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2785 | 2780 | ||
2786 | out: | 2781 | out: |
2787 | if (locked) | 2782 | if (locked) |
2788 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 2783 | reiserfs_write_unlock(inode->i_sb); |
2789 | unlock_page(page); | 2784 | unlock_page(page); |
2790 | page_cache_release(page); | 2785 | page_cache_release(page); |
2791 | 2786 | ||
@@ -2795,7 +2790,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2795 | return ret == 0 ? copied : ret; | 2790 | return ret == 0 ? copied : ret; |
2796 | 2791 | ||
2797 | journal_error: | 2792 | journal_error: |
2798 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 2793 | reiserfs_write_unlock(inode->i_sb); |
2799 | locked = false; | 2794 | locked = false; |
2800 | if (th) { | 2795 | if (th) { |
2801 | if (!update_sd) | 2796 | if (!update_sd) |
@@ -2813,10 +2808,11 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2813 | int ret = 0; | 2808 | int ret = 0; |
2814 | int update_sd = 0; | 2809 | int update_sd = 0; |
2815 | struct reiserfs_transaction_handle *th = NULL; | 2810 | struct reiserfs_transaction_handle *th = NULL; |
2811 | int depth; | ||
2816 | 2812 | ||
2817 | reiserfs_write_unlock(inode->i_sb); | 2813 | depth = reiserfs_write_unlock_nested(inode->i_sb); |
2818 | reiserfs_wait_on_write_block(inode->i_sb); | 2814 | reiserfs_wait_on_write_block(inode->i_sb); |
2819 | reiserfs_write_lock(inode->i_sb); | 2815 | reiserfs_write_lock_nested(inode->i_sb, depth); |
2820 | 2816 | ||
2821 | if (reiserfs_transaction_running(inode->i_sb)) { | 2817 | if (reiserfs_transaction_running(inode->i_sb)) { |
2822 | th = current->journal_info; | 2818 | th = current->journal_info; |
@@ -3115,7 +3111,6 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3115 | { | 3111 | { |
3116 | struct inode *inode = dentry->d_inode; | 3112 | struct inode *inode = dentry->d_inode; |
3117 | unsigned int ia_valid; | 3113 | unsigned int ia_valid; |
3118 | int depth; | ||
3119 | int error; | 3114 | int error; |
3120 | 3115 | ||
3121 | error = inode_change_ok(inode, attr); | 3116 | error = inode_change_ok(inode, attr); |
@@ -3127,14 +3122,14 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3127 | 3122 | ||
3128 | if (is_quota_modification(inode, attr)) | 3123 | if (is_quota_modification(inode, attr)) |
3129 | dquot_initialize(inode); | 3124 | dquot_initialize(inode); |
3130 | depth = reiserfs_write_lock_once(inode->i_sb); | 3125 | reiserfs_write_lock(inode->i_sb); |
3131 | if (attr->ia_valid & ATTR_SIZE) { | 3126 | if (attr->ia_valid & ATTR_SIZE) { |
3132 | /* version 2 items will be caught by the s_maxbytes check | 3127 | /* version 2 items will be caught by the s_maxbytes check |
3133 | ** done for us in vmtruncate | 3128 | ** done for us in vmtruncate |
3134 | */ | 3129 | */ |
3135 | if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 && | 3130 | if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 && |
3136 | attr->ia_size > MAX_NON_LFS) { | 3131 | attr->ia_size > MAX_NON_LFS) { |
3137 | reiserfs_write_unlock_once(inode->i_sb, depth); | 3132 | reiserfs_write_unlock(inode->i_sb); |
3138 | error = -EFBIG; | 3133 | error = -EFBIG; |
3139 | goto out; | 3134 | goto out; |
3140 | } | 3135 | } |
@@ -3157,7 +3152,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3157 | error = err; | 3152 | error = err; |
3158 | } | 3153 | } |
3159 | if (error) { | 3154 | if (error) { |
3160 | reiserfs_write_unlock_once(inode->i_sb, depth); | 3155 | reiserfs_write_unlock(inode->i_sb); |
3161 | goto out; | 3156 | goto out; |
3162 | } | 3157 | } |
3163 | /* | 3158 | /* |
@@ -3167,7 +3162,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3167 | attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME); | 3162 | attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME); |
3168 | } | 3163 | } |
3169 | } | 3164 | } |
3170 | reiserfs_write_unlock_once(inode->i_sb, depth); | 3165 | reiserfs_write_unlock(inode->i_sb); |
3171 | 3166 | ||
3172 | if ((((attr->ia_valid & ATTR_UID) && (from_kuid(&init_user_ns, attr->ia_uid) & ~0xffff)) || | 3167 | if ((((attr->ia_valid & ATTR_UID) && (from_kuid(&init_user_ns, attr->ia_uid) & ~0xffff)) || |
3173 | ((attr->ia_valid & ATTR_GID) && (from_kgid(&init_user_ns, attr->ia_gid) & ~0xffff))) && | 3168 | ((attr->ia_valid & ATTR_GID) && (from_kgid(&init_user_ns, attr->ia_gid) & ~0xffff))) && |
@@ -3192,16 +3187,16 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3192 | return error; | 3187 | return error; |
3193 | 3188 | ||
3194 | /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ | 3189 | /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ |
3195 | depth = reiserfs_write_lock_once(inode->i_sb); | 3190 | reiserfs_write_lock(inode->i_sb); |
3196 | error = journal_begin(&th, inode->i_sb, jbegin_count); | 3191 | error = journal_begin(&th, inode->i_sb, jbegin_count); |
3197 | reiserfs_write_unlock_once(inode->i_sb, depth); | 3192 | reiserfs_write_unlock(inode->i_sb); |
3198 | if (error) | 3193 | if (error) |
3199 | goto out; | 3194 | goto out; |
3200 | error = dquot_transfer(inode, attr); | 3195 | error = dquot_transfer(inode, attr); |
3201 | depth = reiserfs_write_lock_once(inode->i_sb); | 3196 | reiserfs_write_lock(inode->i_sb); |
3202 | if (error) { | 3197 | if (error) { |
3203 | journal_end(&th, inode->i_sb, jbegin_count); | 3198 | journal_end(&th, inode->i_sb, jbegin_count); |
3204 | reiserfs_write_unlock_once(inode->i_sb, depth); | 3199 | reiserfs_write_unlock(inode->i_sb); |
3205 | goto out; | 3200 | goto out; |
3206 | } | 3201 | } |
3207 | 3202 | ||
@@ -3213,7 +3208,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3213 | inode->i_gid = attr->ia_gid; | 3208 | inode->i_gid = attr->ia_gid; |
3214 | mark_inode_dirty(inode); | 3209 | mark_inode_dirty(inode); |
3215 | error = journal_end(&th, inode->i_sb, jbegin_count); | 3210 | error = journal_end(&th, inode->i_sb, jbegin_count); |
3216 | reiserfs_write_unlock_once(inode->i_sb, depth); | 3211 | reiserfs_write_unlock(inode->i_sb); |
3217 | if (error) | 3212 | if (error) |
3218 | goto out; | 3213 | goto out; |
3219 | } | 3214 | } |