diff options
Diffstat (limited to 'fs/reiserfs/journal.c')
-rw-r--r-- | fs/reiserfs/journal.c | 140 |
1 files changed, 71 insertions, 69 deletions
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 4491fcf2a0e6..b7a179560ab4 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -152,18 +152,16 @@ static struct reiserfs_bitmap_node *allocate_bitmap_node(struct super_block | |||
152 | struct reiserfs_bitmap_node *bn; | 152 | struct reiserfs_bitmap_node *bn; |
153 | static int id; | 153 | static int id; |
154 | 154 | ||
155 | bn = reiserfs_kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS, | 155 | bn = kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS); |
156 | p_s_sb); | ||
157 | if (!bn) { | 156 | if (!bn) { |
158 | return NULL; | 157 | return NULL; |
159 | } | 158 | } |
160 | bn->data = reiserfs_kmalloc(p_s_sb->s_blocksize, GFP_NOFS, p_s_sb); | 159 | bn->data = kzalloc(p_s_sb->s_blocksize, GFP_NOFS); |
161 | if (!bn->data) { | 160 | if (!bn->data) { |
162 | reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb); | 161 | kfree(bn); |
163 | return NULL; | 162 | return NULL; |
164 | } | 163 | } |
165 | bn->id = id++; | 164 | bn->id = id++; |
166 | memset(bn->data, 0, p_s_sb->s_blocksize); | ||
167 | INIT_LIST_HEAD(&bn->list); | 165 | INIT_LIST_HEAD(&bn->list); |
168 | return bn; | 166 | return bn; |
169 | } | 167 | } |
@@ -197,8 +195,8 @@ static inline void free_bitmap_node(struct super_block *p_s_sb, | |||
197 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); | 195 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); |
198 | journal->j_used_bitmap_nodes--; | 196 | journal->j_used_bitmap_nodes--; |
199 | if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) { | 197 | if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) { |
200 | reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb); | 198 | kfree(bn->data); |
201 | reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb); | 199 | kfree(bn); |
202 | } else { | 200 | } else { |
203 | list_add(&bn->list, &journal->j_bitmap_nodes); | 201 | list_add(&bn->list, &journal->j_bitmap_nodes); |
204 | journal->j_free_bitmap_nodes++; | 202 | journal->j_free_bitmap_nodes++; |
@@ -276,8 +274,8 @@ static int free_bitmap_nodes(struct super_block *p_s_sb) | |||
276 | while (next != &journal->j_bitmap_nodes) { | 274 | while (next != &journal->j_bitmap_nodes) { |
277 | bn = list_entry(next, struct reiserfs_bitmap_node, list); | 275 | bn = list_entry(next, struct reiserfs_bitmap_node, list); |
278 | list_del(next); | 276 | list_del(next); |
279 | reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb); | 277 | kfree(bn->data); |
280 | reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb); | 278 | kfree(bn); |
281 | next = journal->j_bitmap_nodes.next; | 279 | next = journal->j_bitmap_nodes.next; |
282 | journal->j_free_bitmap_nodes--; | 280 | journal->j_free_bitmap_nodes--; |
283 | } | 281 | } |
@@ -581,7 +579,7 @@ static inline void put_journal_list(struct super_block *s, | |||
581 | jl->j_trans_id, jl->j_refcount); | 579 | jl->j_trans_id, jl->j_refcount); |
582 | } | 580 | } |
583 | if (--jl->j_refcount == 0) | 581 | if (--jl->j_refcount == 0) |
584 | reiserfs_kfree(jl, sizeof(struct reiserfs_journal_list), s); | 582 | kfree(jl); |
585 | } | 583 | } |
586 | 584 | ||
587 | /* | 585 | /* |
@@ -848,6 +846,14 @@ static int write_ordered_buffers(spinlock_t * lock, | |||
848 | spin_lock(lock); | 846 | spin_lock(lock); |
849 | goto loop_next; | 847 | goto loop_next; |
850 | } | 848 | } |
849 | /* in theory, dirty non-uptodate buffers should never get here, | ||
850 | * but the upper layer io error paths still have a few quirks. | ||
851 | * Handle them here as gracefully as we can | ||
852 | */ | ||
853 | if (!buffer_uptodate(bh) && buffer_dirty(bh)) { | ||
854 | clear_buffer_dirty(bh); | ||
855 | ret = -EIO; | ||
856 | } | ||
851 | if (buffer_dirty(bh)) { | 857 | if (buffer_dirty(bh)) { |
852 | list_del_init(&jh->list); | 858 | list_del_init(&jh->list); |
853 | list_add(&jh->list, &tmp); | 859 | list_add(&jh->list, &tmp); |
@@ -879,6 +885,19 @@ static int write_ordered_buffers(spinlock_t * lock, | |||
879 | if (!buffer_uptodate(bh)) { | 885 | if (!buffer_uptodate(bh)) { |
880 | ret = -EIO; | 886 | ret = -EIO; |
881 | } | 887 | } |
888 | /* ugly interaction with invalidatepage here. | ||
889 | * reiserfs_invalidate_page will pin any buffer that has a valid | ||
890 | * journal head from an older transaction. If someone else sets | ||
891 | * our buffer dirty after we write it in the first loop, and | ||
892 | * then someone truncates the page away, nobody will ever write | ||
893 | * the buffer. We're safe if we write the page one last time | ||
894 | * after freeing the journal header. | ||
895 | */ | ||
896 | if (buffer_dirty(bh) && unlikely(bh->b_page->mapping == NULL)) { | ||
897 | spin_unlock(lock); | ||
898 | ll_rw_block(WRITE, 1, &bh); | ||
899 | spin_lock(lock); | ||
900 | } | ||
882 | put_bh(bh); | 901 | put_bh(bh); |
883 | cond_resched_lock(lock); | 902 | cond_resched_lock(lock); |
884 | } | 903 | } |
@@ -977,6 +996,7 @@ static int flush_commit_list(struct super_block *s, | |||
977 | struct reiserfs_journal *journal = SB_JOURNAL(s); | 996 | struct reiserfs_journal *journal = SB_JOURNAL(s); |
978 | int barrier = 0; | 997 | int barrier = 0; |
979 | int retval = 0; | 998 | int retval = 0; |
999 | int write_len; | ||
980 | 1000 | ||
981 | reiserfs_check_lock_depth(s, "flush_commit_list"); | 1001 | reiserfs_check_lock_depth(s, "flush_commit_list"); |
982 | 1002 | ||
@@ -1018,24 +1038,35 @@ static int flush_commit_list(struct super_block *s, | |||
1018 | } | 1038 | } |
1019 | 1039 | ||
1020 | if (!list_empty(&jl->j_bh_list)) { | 1040 | if (!list_empty(&jl->j_bh_list)) { |
1041 | int ret; | ||
1021 | unlock_kernel(); | 1042 | unlock_kernel(); |
1022 | write_ordered_buffers(&journal->j_dirty_buffers_lock, | 1043 | ret = write_ordered_buffers(&journal->j_dirty_buffers_lock, |
1023 | journal, jl, &jl->j_bh_list); | 1044 | journal, jl, &jl->j_bh_list); |
1045 | if (ret < 0 && retval == 0) | ||
1046 | retval = ret; | ||
1024 | lock_kernel(); | 1047 | lock_kernel(); |
1025 | } | 1048 | } |
1026 | BUG_ON(!list_empty(&jl->j_bh_list)); | 1049 | BUG_ON(!list_empty(&jl->j_bh_list)); |
1027 | /* | 1050 | /* |
1028 | * for the description block and all the log blocks, submit any buffers | 1051 | * for the description block and all the log blocks, submit any buffers |
1029 | * that haven't already reached the disk | 1052 | * that haven't already reached the disk. Try to write at least 256 |
1053 | * log blocks. later on, we will only wait on blocks that correspond | ||
1054 | * to this transaction, but while we're unplugging we might as well | ||
1055 | * get a chunk of data on there. | ||
1030 | */ | 1056 | */ |
1031 | atomic_inc(&journal->j_async_throttle); | 1057 | atomic_inc(&journal->j_async_throttle); |
1032 | for (i = 0; i < (jl->j_len + 1); i++) { | 1058 | write_len = jl->j_len + 1; |
1059 | if (write_len < 256) | ||
1060 | write_len = 256; | ||
1061 | for (i = 0 ; i < write_len ; i++) { | ||
1033 | bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % | 1062 | bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % |
1034 | SB_ONDISK_JOURNAL_SIZE(s); | 1063 | SB_ONDISK_JOURNAL_SIZE(s); |
1035 | tbh = journal_find_get_block(s, bn); | 1064 | tbh = journal_find_get_block(s, bn); |
1036 | if (buffer_dirty(tbh)) /* redundant, ll_rw_block() checks */ | 1065 | if (tbh) { |
1037 | ll_rw_block(SWRITE, 1, &tbh); | 1066 | if (buffer_dirty(tbh)) |
1038 | put_bh(tbh); | 1067 | ll_rw_block(WRITE, 1, &tbh) ; |
1068 | put_bh(tbh) ; | ||
1069 | } | ||
1039 | } | 1070 | } |
1040 | atomic_dec(&journal->j_async_throttle); | 1071 | atomic_dec(&journal->j_async_throttle); |
1041 | 1072 | ||
@@ -1818,8 +1849,7 @@ void remove_journal_hash(struct super_block *sb, | |||
1818 | static void free_journal_ram(struct super_block *p_s_sb) | 1849 | static void free_journal_ram(struct super_block *p_s_sb) |
1819 | { | 1850 | { |
1820 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); | 1851 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); |
1821 | reiserfs_kfree(journal->j_current_jl, | 1852 | kfree(journal->j_current_jl); |
1822 | sizeof(struct reiserfs_journal_list), p_s_sb); | ||
1823 | journal->j_num_lists--; | 1853 | journal->j_num_lists--; |
1824 | 1854 | ||
1825 | vfree(journal->j_cnode_free_orig); | 1855 | vfree(journal->j_cnode_free_orig); |
@@ -2093,21 +2123,15 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2093 | } | 2123 | } |
2094 | trans_id = get_desc_trans_id(desc); | 2124 | trans_id = get_desc_trans_id(desc); |
2095 | /* now we know we've got a good transaction, and it was inside the valid time ranges */ | 2125 | /* now we know we've got a good transaction, and it was inside the valid time ranges */ |
2096 | log_blocks = | 2126 | log_blocks = kmalloc(get_desc_trans_len(desc) * |
2097 | reiserfs_kmalloc(get_desc_trans_len(desc) * | 2127 | sizeof(struct buffer_head *), GFP_NOFS); |
2098 | sizeof(struct buffer_head *), GFP_NOFS, p_s_sb); | 2128 | real_blocks = kmalloc(get_desc_trans_len(desc) * |
2099 | real_blocks = | 2129 | sizeof(struct buffer_head *), GFP_NOFS); |
2100 | reiserfs_kmalloc(get_desc_trans_len(desc) * | ||
2101 | sizeof(struct buffer_head *), GFP_NOFS, p_s_sb); | ||
2102 | if (!log_blocks || !real_blocks) { | 2130 | if (!log_blocks || !real_blocks) { |
2103 | brelse(c_bh); | 2131 | brelse(c_bh); |
2104 | brelse(d_bh); | 2132 | brelse(d_bh); |
2105 | reiserfs_kfree(log_blocks, | 2133 | kfree(log_blocks); |
2106 | get_desc_trans_len(desc) * | 2134 | kfree(real_blocks); |
2107 | sizeof(struct buffer_head *), p_s_sb); | ||
2108 | reiserfs_kfree(real_blocks, | ||
2109 | get_desc_trans_len(desc) * | ||
2110 | sizeof(struct buffer_head *), p_s_sb); | ||
2111 | reiserfs_warning(p_s_sb, | 2135 | reiserfs_warning(p_s_sb, |
2112 | "journal-1169: kmalloc failed, unable to mount FS"); | 2136 | "journal-1169: kmalloc failed, unable to mount FS"); |
2113 | return -1; | 2137 | return -1; |
@@ -2145,12 +2169,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2145 | brelse_array(real_blocks, i); | 2169 | brelse_array(real_blocks, i); |
2146 | brelse(c_bh); | 2170 | brelse(c_bh); |
2147 | brelse(d_bh); | 2171 | brelse(d_bh); |
2148 | reiserfs_kfree(log_blocks, | 2172 | kfree(log_blocks); |
2149 | get_desc_trans_len(desc) * | 2173 | kfree(real_blocks); |
2150 | sizeof(struct buffer_head *), p_s_sb); | ||
2151 | reiserfs_kfree(real_blocks, | ||
2152 | get_desc_trans_len(desc) * | ||
2153 | sizeof(struct buffer_head *), p_s_sb); | ||
2154 | return -1; | 2174 | return -1; |
2155 | } | 2175 | } |
2156 | } | 2176 | } |
@@ -2166,12 +2186,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2166 | brelse_array(real_blocks, get_desc_trans_len(desc)); | 2186 | brelse_array(real_blocks, get_desc_trans_len(desc)); |
2167 | brelse(c_bh); | 2187 | brelse(c_bh); |
2168 | brelse(d_bh); | 2188 | brelse(d_bh); |
2169 | reiserfs_kfree(log_blocks, | 2189 | kfree(log_blocks); |
2170 | get_desc_trans_len(desc) * | 2190 | kfree(real_blocks); |
2171 | sizeof(struct buffer_head *), p_s_sb); | ||
2172 | reiserfs_kfree(real_blocks, | ||
2173 | get_desc_trans_len(desc) * | ||
2174 | sizeof(struct buffer_head *), p_s_sb); | ||
2175 | return -1; | 2191 | return -1; |
2176 | } | 2192 | } |
2177 | memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data, | 2193 | memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data, |
@@ -2193,12 +2209,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2193 | get_desc_trans_len(desc) - i); | 2209 | get_desc_trans_len(desc) - i); |
2194 | brelse(c_bh); | 2210 | brelse(c_bh); |
2195 | brelse(d_bh); | 2211 | brelse(d_bh); |
2196 | reiserfs_kfree(log_blocks, | 2212 | kfree(log_blocks); |
2197 | get_desc_trans_len(desc) * | 2213 | kfree(real_blocks); |
2198 | sizeof(struct buffer_head *), p_s_sb); | ||
2199 | reiserfs_kfree(real_blocks, | ||
2200 | get_desc_trans_len(desc) * | ||
2201 | sizeof(struct buffer_head *), p_s_sb); | ||
2202 | return -1; | 2214 | return -1; |
2203 | } | 2215 | } |
2204 | brelse(real_blocks[i]); | 2216 | brelse(real_blocks[i]); |
@@ -2217,12 +2229,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2217 | journal->j_trans_id = trans_id + 1; | 2229 | journal->j_trans_id = trans_id + 1; |
2218 | brelse(c_bh); | 2230 | brelse(c_bh); |
2219 | brelse(d_bh); | 2231 | brelse(d_bh); |
2220 | reiserfs_kfree(log_blocks, | 2232 | kfree(log_blocks); |
2221 | le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), | 2233 | kfree(real_blocks); |
2222 | p_s_sb); | ||
2223 | reiserfs_kfree(real_blocks, | ||
2224 | le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), | ||
2225 | p_s_sb); | ||
2226 | return 0; | 2234 | return 0; |
2227 | } | 2235 | } |
2228 | 2236 | ||
@@ -2471,14 +2479,8 @@ static int journal_read(struct super_block *p_s_sb) | |||
2471 | static struct reiserfs_journal_list *alloc_journal_list(struct super_block *s) | 2479 | static struct reiserfs_journal_list *alloc_journal_list(struct super_block *s) |
2472 | { | 2480 | { |
2473 | struct reiserfs_journal_list *jl; | 2481 | struct reiserfs_journal_list *jl; |
2474 | retry: | 2482 | jl = kzalloc(sizeof(struct reiserfs_journal_list), |
2475 | jl = reiserfs_kmalloc(sizeof(struct reiserfs_journal_list), GFP_NOFS, | 2483 | GFP_NOFS | __GFP_NOFAIL); |
2476 | s); | ||
2477 | if (!jl) { | ||
2478 | yield(); | ||
2479 | goto retry; | ||
2480 | } | ||
2481 | memset(jl, 0, sizeof(*jl)); | ||
2482 | INIT_LIST_HEAD(&jl->j_list); | 2484 | INIT_LIST_HEAD(&jl->j_list); |
2483 | INIT_LIST_HEAD(&jl->j_working_list); | 2485 | INIT_LIST_HEAD(&jl->j_working_list); |
2484 | INIT_LIST_HEAD(&jl->j_tail_bh_list); | 2486 | INIT_LIST_HEAD(&jl->j_tail_bh_list); |
@@ -2821,6 +2823,9 @@ int journal_transaction_should_end(struct reiserfs_transaction_handle *th, | |||
2821 | journal->j_cnode_free < (journal->j_trans_max * 3)) { | 2823 | journal->j_cnode_free < (journal->j_trans_max * 3)) { |
2822 | return 1; | 2824 | return 1; |
2823 | } | 2825 | } |
2826 | /* protected by the BKL here */ | ||
2827 | journal->j_len_alloc += new_alloc; | ||
2828 | th->t_blocks_allocated += new_alloc ; | ||
2824 | return 0; | 2829 | return 0; |
2825 | } | 2830 | } |
2826 | 2831 | ||
@@ -3042,14 +3047,12 @@ struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct | |||
3042 | } | 3047 | } |
3043 | return th; | 3048 | return th; |
3044 | } | 3049 | } |
3045 | th = reiserfs_kmalloc(sizeof(struct reiserfs_transaction_handle), | 3050 | th = kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS); |
3046 | GFP_NOFS, s); | ||
3047 | if (!th) | 3051 | if (!th) |
3048 | return NULL; | 3052 | return NULL; |
3049 | ret = journal_begin(th, s, nblocks); | 3053 | ret = journal_begin(th, s, nblocks); |
3050 | if (ret) { | 3054 | if (ret) { |
3051 | reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle), | 3055 | kfree(th); |
3052 | s); | ||
3053 | return NULL; | 3056 | return NULL; |
3054 | } | 3057 | } |
3055 | 3058 | ||
@@ -3067,8 +3070,7 @@ int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *th) | |||
3067 | ret = -EIO; | 3070 | ret = -EIO; |
3068 | if (th->t_refcount == 0) { | 3071 | if (th->t_refcount == 0) { |
3069 | SB_JOURNAL(s)->j_persistent_trans--; | 3072 | SB_JOURNAL(s)->j_persistent_trans--; |
3070 | reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle), | 3073 | kfree(th); |
3071 | s); | ||
3072 | } | 3074 | } |
3073 | return ret; | 3075 | return ret; |
3074 | } | 3076 | } |