diff options
Diffstat (limited to 'fs/ocfs2/localalloc.c')
-rw-r--r-- | fs/ocfs2/localalloc.c | 126 |
1 files changed, 54 insertions, 72 deletions
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 1f17a4d08287..698d79a74ef8 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
@@ -58,19 +58,18 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, | |||
58 | static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc); | 58 | static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc); |
59 | 59 | ||
60 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, | 60 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, |
61 | struct ocfs2_journal_handle *handle, | 61 | handle_t *handle, |
62 | struct ocfs2_dinode *alloc, | 62 | struct ocfs2_dinode *alloc, |
63 | struct inode *main_bm_inode, | 63 | struct inode *main_bm_inode, |
64 | struct buffer_head *main_bm_bh); | 64 | struct buffer_head *main_bm_bh); |
65 | 65 | ||
66 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, | 66 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, |
67 | struct ocfs2_journal_handle *handle, | ||
68 | struct ocfs2_alloc_context **ac, | 67 | struct ocfs2_alloc_context **ac, |
69 | struct inode **bitmap_inode, | 68 | struct inode **bitmap_inode, |
70 | struct buffer_head **bitmap_bh); | 69 | struct buffer_head **bitmap_bh); |
71 | 70 | ||
72 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, | 71 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, |
73 | struct ocfs2_journal_handle *handle, | 72 | handle_t *handle, |
74 | struct ocfs2_alloc_context *ac); | 73 | struct ocfs2_alloc_context *ac); |
75 | 74 | ||
76 | static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | 75 | static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, |
@@ -196,7 +195,7 @@ bail: | |||
196 | void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | 195 | void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) |
197 | { | 196 | { |
198 | int status; | 197 | int status; |
199 | struct ocfs2_journal_handle *handle = NULL; | 198 | handle_t *handle; |
200 | struct inode *local_alloc_inode = NULL; | 199 | struct inode *local_alloc_inode = NULL; |
201 | struct buffer_head *bh = NULL; | 200 | struct buffer_head *bh = NULL; |
202 | struct buffer_head *main_bm_bh = NULL; | 201 | struct buffer_head *main_bm_bh = NULL; |
@@ -207,7 +206,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
207 | mlog_entry_void(); | 206 | mlog_entry_void(); |
208 | 207 | ||
209 | if (osb->local_alloc_state == OCFS2_LA_UNUSED) | 208 | if (osb->local_alloc_state == OCFS2_LA_UNUSED) |
210 | goto bail; | 209 | goto out; |
211 | 210 | ||
212 | local_alloc_inode = | 211 | local_alloc_inode = |
213 | ocfs2_get_system_file_inode(osb, | 212 | ocfs2_get_system_file_inode(osb, |
@@ -216,40 +215,34 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
216 | if (!local_alloc_inode) { | 215 | if (!local_alloc_inode) { |
217 | status = -ENOENT; | 216 | status = -ENOENT; |
218 | mlog_errno(status); | 217 | mlog_errno(status); |
219 | goto bail; | 218 | goto out; |
220 | } | 219 | } |
221 | 220 | ||
222 | osb->local_alloc_state = OCFS2_LA_DISABLED; | 221 | osb->local_alloc_state = OCFS2_LA_DISABLED; |
223 | 222 | ||
224 | handle = ocfs2_alloc_handle(osb); | ||
225 | if (!handle) { | ||
226 | status = -ENOMEM; | ||
227 | mlog_errno(status); | ||
228 | goto bail; | ||
229 | } | ||
230 | |||
231 | main_bm_inode = ocfs2_get_system_file_inode(osb, | 223 | main_bm_inode = ocfs2_get_system_file_inode(osb, |
232 | GLOBAL_BITMAP_SYSTEM_INODE, | 224 | GLOBAL_BITMAP_SYSTEM_INODE, |
233 | OCFS2_INVALID_SLOT); | 225 | OCFS2_INVALID_SLOT); |
234 | if (!main_bm_inode) { | 226 | if (!main_bm_inode) { |
235 | status = -EINVAL; | 227 | status = -EINVAL; |
236 | mlog_errno(status); | 228 | mlog_errno(status); |
237 | goto bail; | 229 | goto out; |
238 | } | 230 | } |
239 | 231 | ||
240 | ocfs2_handle_add_inode(handle, main_bm_inode); | 232 | mutex_lock(&main_bm_inode->i_mutex); |
241 | status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1); | 233 | |
234 | status = ocfs2_meta_lock(main_bm_inode, &main_bm_bh, 1); | ||
242 | if (status < 0) { | 235 | if (status < 0) { |
243 | mlog_errno(status); | 236 | mlog_errno(status); |
244 | goto bail; | 237 | goto out_mutex; |
245 | } | 238 | } |
246 | 239 | ||
247 | /* WINDOW_MOVE_CREDITS is a bit heavy... */ | 240 | /* WINDOW_MOVE_CREDITS is a bit heavy... */ |
248 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 241 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
249 | if (IS_ERR(handle)) { | 242 | if (IS_ERR(handle)) { |
250 | mlog_errno(PTR_ERR(handle)); | 243 | mlog_errno(PTR_ERR(handle)); |
251 | handle = NULL; | 244 | handle = NULL; |
252 | goto bail; | 245 | goto out_unlock; |
253 | } | 246 | } |
254 | 247 | ||
255 | bh = osb->local_alloc_bh; | 248 | bh = osb->local_alloc_bh; |
@@ -258,7 +251,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
258 | alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); | 251 | alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); |
259 | if (!alloc_copy) { | 252 | if (!alloc_copy) { |
260 | status = -ENOMEM; | 253 | status = -ENOMEM; |
261 | goto bail; | 254 | goto out_commit; |
262 | } | 255 | } |
263 | memcpy(alloc_copy, alloc, bh->b_size); | 256 | memcpy(alloc_copy, alloc, bh->b_size); |
264 | 257 | ||
@@ -266,7 +259,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
266 | OCFS2_JOURNAL_ACCESS_WRITE); | 259 | OCFS2_JOURNAL_ACCESS_WRITE); |
267 | if (status < 0) { | 260 | if (status < 0) { |
268 | mlog_errno(status); | 261 | mlog_errno(status); |
269 | goto bail; | 262 | goto out_commit; |
270 | } | 263 | } |
271 | 264 | ||
272 | ocfs2_clear_local_alloc(alloc); | 265 | ocfs2_clear_local_alloc(alloc); |
@@ -274,7 +267,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
274 | status = ocfs2_journal_dirty(handle, bh); | 267 | status = ocfs2_journal_dirty(handle, bh); |
275 | if (status < 0) { | 268 | if (status < 0) { |
276 | mlog_errno(status); | 269 | mlog_errno(status); |
277 | goto bail; | 270 | goto out_commit; |
278 | } | 271 | } |
279 | 272 | ||
280 | brelse(bh); | 273 | brelse(bh); |
@@ -286,16 +279,20 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
286 | if (status < 0) | 279 | if (status < 0) |
287 | mlog_errno(status); | 280 | mlog_errno(status); |
288 | 281 | ||
289 | bail: | 282 | out_commit: |
290 | if (handle) | 283 | ocfs2_commit_trans(osb, handle); |
291 | ocfs2_commit_trans(handle); | ||
292 | 284 | ||
285 | out_unlock: | ||
293 | if (main_bm_bh) | 286 | if (main_bm_bh) |
294 | brelse(main_bm_bh); | 287 | brelse(main_bm_bh); |
295 | 288 | ||
296 | if (main_bm_inode) | 289 | ocfs2_meta_unlock(main_bm_inode, 1); |
297 | iput(main_bm_inode); | ||
298 | 290 | ||
291 | out_mutex: | ||
292 | mutex_unlock(&main_bm_inode->i_mutex); | ||
293 | iput(main_bm_inode); | ||
294 | |||
295 | out: | ||
299 | if (local_alloc_inode) | 296 | if (local_alloc_inode) |
300 | iput(local_alloc_inode); | 297 | iput(local_alloc_inode); |
301 | 298 | ||
@@ -385,61 +382,59 @@ int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb, | |||
385 | struct ocfs2_dinode *alloc) | 382 | struct ocfs2_dinode *alloc) |
386 | { | 383 | { |
387 | int status; | 384 | int status; |
388 | struct ocfs2_journal_handle *handle = NULL; | 385 | handle_t *handle; |
389 | struct buffer_head *main_bm_bh = NULL; | 386 | struct buffer_head *main_bm_bh = NULL; |
390 | struct inode *main_bm_inode = NULL; | 387 | struct inode *main_bm_inode; |
391 | 388 | ||
392 | mlog_entry_void(); | 389 | mlog_entry_void(); |
393 | 390 | ||
394 | handle = ocfs2_alloc_handle(osb); | ||
395 | if (!handle) { | ||
396 | status = -ENOMEM; | ||
397 | mlog_errno(status); | ||
398 | goto bail; | ||
399 | } | ||
400 | |||
401 | main_bm_inode = ocfs2_get_system_file_inode(osb, | 391 | main_bm_inode = ocfs2_get_system_file_inode(osb, |
402 | GLOBAL_BITMAP_SYSTEM_INODE, | 392 | GLOBAL_BITMAP_SYSTEM_INODE, |
403 | OCFS2_INVALID_SLOT); | 393 | OCFS2_INVALID_SLOT); |
404 | if (!main_bm_inode) { | 394 | if (!main_bm_inode) { |
405 | status = -EINVAL; | 395 | status = -EINVAL; |
406 | mlog_errno(status); | 396 | mlog_errno(status); |
407 | goto bail; | 397 | goto out; |
408 | } | 398 | } |
409 | 399 | ||
410 | ocfs2_handle_add_inode(handle, main_bm_inode); | 400 | mutex_lock(&main_bm_inode->i_mutex); |
411 | status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1); | 401 | |
402 | status = ocfs2_meta_lock(main_bm_inode, &main_bm_bh, 1); | ||
412 | if (status < 0) { | 403 | if (status < 0) { |
413 | mlog_errno(status); | 404 | mlog_errno(status); |
414 | goto bail; | 405 | goto out_mutex; |
415 | } | 406 | } |
416 | 407 | ||
417 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 408 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
418 | if (IS_ERR(handle)) { | 409 | if (IS_ERR(handle)) { |
419 | status = PTR_ERR(handle); | 410 | status = PTR_ERR(handle); |
420 | handle = NULL; | 411 | handle = NULL; |
421 | mlog_errno(status); | 412 | mlog_errno(status); |
422 | goto bail; | 413 | goto out_unlock; |
423 | } | 414 | } |
424 | 415 | ||
425 | /* we want the bitmap change to be recorded on disk asap */ | 416 | /* we want the bitmap change to be recorded on disk asap */ |
426 | ocfs2_handle_set_sync(handle, 1); | 417 | handle->h_sync = 1; |
427 | 418 | ||
428 | status = ocfs2_sync_local_to_main(osb, handle, alloc, | 419 | status = ocfs2_sync_local_to_main(osb, handle, alloc, |
429 | main_bm_inode, main_bm_bh); | 420 | main_bm_inode, main_bm_bh); |
430 | if (status < 0) | 421 | if (status < 0) |
431 | mlog_errno(status); | 422 | mlog_errno(status); |
432 | 423 | ||
433 | bail: | 424 | ocfs2_commit_trans(osb, handle); |
434 | if (handle) | 425 | |
435 | ocfs2_commit_trans(handle); | 426 | out_unlock: |
427 | ocfs2_meta_unlock(main_bm_inode, 1); | ||
428 | |||
429 | out_mutex: | ||
430 | mutex_unlock(&main_bm_inode->i_mutex); | ||
436 | 431 | ||
437 | if (main_bm_bh) | 432 | if (main_bm_bh) |
438 | brelse(main_bm_bh); | 433 | brelse(main_bm_bh); |
439 | 434 | ||
440 | if (main_bm_inode) | 435 | iput(main_bm_inode); |
441 | iput(main_bm_inode); | ||
442 | 436 | ||
437 | out: | ||
443 | mlog_exit(status); | 438 | mlog_exit(status); |
444 | return status; | 439 | return status; |
445 | } | 440 | } |
@@ -452,7 +447,6 @@ bail: | |||
452 | * our own in order to shift windows. | 447 | * our own in order to shift windows. |
453 | */ | 448 | */ |
454 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | 449 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, |
455 | struct ocfs2_journal_handle *passed_handle, | ||
456 | u32 bits_wanted, | 450 | u32 bits_wanted, |
457 | struct ocfs2_alloc_context *ac) | 451 | struct ocfs2_alloc_context *ac) |
458 | { | 452 | { |
@@ -463,9 +457,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
463 | 457 | ||
464 | mlog_entry_void(); | 458 | mlog_entry_void(); |
465 | 459 | ||
466 | BUG_ON(!passed_handle); | ||
467 | BUG_ON(!ac); | 460 | BUG_ON(!ac); |
468 | BUG_ON(passed_handle->flags & OCFS2_HANDLE_STARTED); | ||
469 | 461 | ||
470 | local_alloc_inode = | 462 | local_alloc_inode = |
471 | ocfs2_get_system_file_inode(osb, | 463 | ocfs2_get_system_file_inode(osb, |
@@ -476,7 +468,11 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
476 | mlog_errno(status); | 468 | mlog_errno(status); |
477 | goto bail; | 469 | goto bail; |
478 | } | 470 | } |
479 | ocfs2_handle_add_inode(passed_handle, local_alloc_inode); | 471 | |
472 | mutex_lock(&local_alloc_inode->i_mutex); | ||
473 | |||
474 | ac->ac_inode = local_alloc_inode; | ||
475 | ac->ac_which = OCFS2_AC_USE_LOCAL; | ||
480 | 476 | ||
481 | if (osb->local_alloc_state != OCFS2_LA_ENABLED) { | 477 | if (osb->local_alloc_state != OCFS2_LA_ENABLED) { |
482 | status = -ENOSPC; | 478 | status = -ENOSPC; |
@@ -515,21 +511,17 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
515 | } | 511 | } |
516 | } | 512 | } |
517 | 513 | ||
518 | ac->ac_inode = igrab(local_alloc_inode); | ||
519 | get_bh(osb->local_alloc_bh); | 514 | get_bh(osb->local_alloc_bh); |
520 | ac->ac_bh = osb->local_alloc_bh; | 515 | ac->ac_bh = osb->local_alloc_bh; |
521 | ac->ac_which = OCFS2_AC_USE_LOCAL; | ||
522 | status = 0; | 516 | status = 0; |
523 | bail: | 517 | bail: |
524 | if (local_alloc_inode) | ||
525 | iput(local_alloc_inode); | ||
526 | 518 | ||
527 | mlog_exit(status); | 519 | mlog_exit(status); |
528 | return status; | 520 | return status; |
529 | } | 521 | } |
530 | 522 | ||
531 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | 523 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, |
532 | struct ocfs2_journal_handle *handle, | 524 | handle_t *handle, |
533 | struct ocfs2_alloc_context *ac, | 525 | struct ocfs2_alloc_context *ac, |
534 | u32 min_bits, | 526 | u32 min_bits, |
535 | u32 *bit_off, | 527 | u32 *bit_off, |
@@ -707,7 +699,7 @@ static void ocfs2_verify_zero_bits(unsigned long *bitmap, | |||
707 | * passed is used for caching. | 699 | * passed is used for caching. |
708 | */ | 700 | */ |
709 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, | 701 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, |
710 | struct ocfs2_journal_handle *handle, | 702 | handle_t *handle, |
711 | struct ocfs2_dinode *alloc, | 703 | struct ocfs2_dinode *alloc, |
712 | struct inode *main_bm_inode, | 704 | struct inode *main_bm_inode, |
713 | struct buffer_head *main_bm_bh) | 705 | struct buffer_head *main_bm_bh) |
@@ -778,7 +770,6 @@ bail: | |||
778 | } | 770 | } |
779 | 771 | ||
780 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, | 772 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, |
781 | struct ocfs2_journal_handle *handle, | ||
782 | struct ocfs2_alloc_context **ac, | 773 | struct ocfs2_alloc_context **ac, |
783 | struct inode **bitmap_inode, | 774 | struct inode **bitmap_inode, |
784 | struct buffer_head **bitmap_bh) | 775 | struct buffer_head **bitmap_bh) |
@@ -792,7 +783,6 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, | |||
792 | goto bail; | 783 | goto bail; |
793 | } | 784 | } |
794 | 785 | ||
795 | (*ac)->ac_handle = handle; | ||
796 | (*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb); | 786 | (*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb); |
797 | 787 | ||
798 | status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac); | 788 | status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac); |
@@ -821,7 +811,7 @@ bail: | |||
821 | * pass it the bitmap lock in lock_bh if you have it. | 811 | * pass it the bitmap lock in lock_bh if you have it. |
822 | */ | 812 | */ |
823 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, | 813 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, |
824 | struct ocfs2_journal_handle *handle, | 814 | handle_t *handle, |
825 | struct ocfs2_alloc_context *ac) | 815 | struct ocfs2_alloc_context *ac) |
826 | { | 816 | { |
827 | int status = 0; | 817 | int status = 0; |
@@ -888,23 +878,15 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
888 | int status = 0; | 878 | int status = 0; |
889 | struct buffer_head *main_bm_bh = NULL; | 879 | struct buffer_head *main_bm_bh = NULL; |
890 | struct inode *main_bm_inode = NULL; | 880 | struct inode *main_bm_inode = NULL; |
891 | struct ocfs2_journal_handle *handle = NULL; | 881 | handle_t *handle = NULL; |
892 | struct ocfs2_dinode *alloc; | 882 | struct ocfs2_dinode *alloc; |
893 | struct ocfs2_dinode *alloc_copy = NULL; | 883 | struct ocfs2_dinode *alloc_copy = NULL; |
894 | struct ocfs2_alloc_context *ac = NULL; | 884 | struct ocfs2_alloc_context *ac = NULL; |
895 | 885 | ||
896 | mlog_entry_void(); | 886 | mlog_entry_void(); |
897 | 887 | ||
898 | handle = ocfs2_alloc_handle(osb); | ||
899 | if (!handle) { | ||
900 | status = -ENOMEM; | ||
901 | mlog_errno(status); | ||
902 | goto bail; | ||
903 | } | ||
904 | |||
905 | /* This will lock the main bitmap for us. */ | 888 | /* This will lock the main bitmap for us. */ |
906 | status = ocfs2_local_alloc_reserve_for_window(osb, | 889 | status = ocfs2_local_alloc_reserve_for_window(osb, |
907 | handle, | ||
908 | &ac, | 890 | &ac, |
909 | &main_bm_inode, | 891 | &main_bm_inode, |
910 | &main_bm_bh); | 892 | &main_bm_bh); |
@@ -914,7 +896,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
914 | goto bail; | 896 | goto bail; |
915 | } | 897 | } |
916 | 898 | ||
917 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 899 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
918 | if (IS_ERR(handle)) { | 900 | if (IS_ERR(handle)) { |
919 | status = PTR_ERR(handle); | 901 | status = PTR_ERR(handle); |
920 | handle = NULL; | 902 | handle = NULL; |
@@ -972,7 +954,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
972 | status = 0; | 954 | status = 0; |
973 | bail: | 955 | bail: |
974 | if (handle) | 956 | if (handle) |
975 | ocfs2_commit_trans(handle); | 957 | ocfs2_commit_trans(osb, handle); |
976 | 958 | ||
977 | if (main_bm_bh) | 959 | if (main_bm_bh) |
978 | brelse(main_bm_bh); | 960 | brelse(main_bm_bh); |