diff options
author | Joel Becker <joel.becker@oracle.com> | 2010-04-13 02:26:32 -0400 |
---|---|---|
committer | Tao Ma <tao.ma@oracle.com> | 2010-04-13 02:26:32 -0400 |
commit | 798db35f4649eac2778381c390ed7d12de9ec767 (patch) | |
tree | 988c30bd86d4913c2f9187bb8504135ec0b80f62 /fs/ocfs2/suballoc.c | |
parent | 4cbe4249d6586d5d88ef271e07302407a14c8443 (diff) |
ocfs2: Allocate discontiguous block groups.
If we cannot get a contiguous region for a block group, allocate a
discontiguous one when the filesystem supports it.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r-- | fs/ocfs2/suballoc.c | 304 |
1 files changed, 264 insertions, 40 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 1070f79fa068..2f753954a7a8 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -60,6 +60,7 @@ static int ocfs2_block_group_fill(handle_t *handle, | |||
60 | struct inode *alloc_inode, | 60 | struct inode *alloc_inode, |
61 | struct buffer_head *bg_bh, | 61 | struct buffer_head *bg_bh, |
62 | u64 group_blkno, | 62 | u64 group_blkno, |
63 | unsigned int group_clusters, | ||
63 | u16 my_chain, | 64 | u16 my_chain, |
64 | struct ocfs2_chain_list *cl); | 65 | struct ocfs2_chain_list *cl); |
65 | static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | 66 | static int ocfs2_block_group_alloc(struct ocfs2_super *osb, |
@@ -326,14 +327,36 @@ out: | |||
326 | return rc; | 327 | return rc; |
327 | } | 328 | } |
328 | 329 | ||
330 | static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, | ||
331 | struct ocfs2_group_desc *bg, | ||
332 | struct ocfs2_chain_list *cl, | ||
333 | u64 p_blkno, u32 clusters) | ||
334 | { | ||
335 | struct ocfs2_extent_list *el = &bg->bg_list; | ||
336 | struct ocfs2_extent_rec *rec; | ||
337 | |||
338 | BUG_ON(!ocfs2_supports_discontig_bh(osb)); | ||
339 | if (!el->l_next_free_rec) | ||
340 | el->l_count = cpu_to_le16(ocfs2_extent_recs_per_gd(osb->sb)); | ||
341 | rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec)]; | ||
342 | rec->e_blkno = p_blkno; | ||
343 | rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) / | ||
344 | le16_to_cpu(cl->cl_bpc)); | ||
345 | rec->e_leaf_clusters = cpu_to_le32(clusters); | ||
346 | le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc)); | ||
347 | le16_add_cpu(&el->l_next_free_rec, 1); | ||
348 | } | ||
349 | |||
329 | static int ocfs2_block_group_fill(handle_t *handle, | 350 | static int ocfs2_block_group_fill(handle_t *handle, |
330 | struct inode *alloc_inode, | 351 | struct inode *alloc_inode, |
331 | struct buffer_head *bg_bh, | 352 | struct buffer_head *bg_bh, |
332 | u64 group_blkno, | 353 | u64 group_blkno, |
354 | unsigned int group_clusters, | ||
333 | u16 my_chain, | 355 | u16 my_chain, |
334 | struct ocfs2_chain_list *cl) | 356 | struct ocfs2_chain_list *cl) |
335 | { | 357 | { |
336 | int status = 0; | 358 | int status = 0; |
359 | struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb); | ||
337 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; | 360 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
338 | struct super_block * sb = alloc_inode->i_sb; | 361 | struct super_block * sb = alloc_inode->i_sb; |
339 | 362 | ||
@@ -361,11 +384,16 @@ static int ocfs2_block_group_fill(handle_t *handle, | |||
361 | strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE); | 384 | strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE); |
362 | bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation); | 385 | bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation); |
363 | bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb, 1)); | 386 | bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb, 1)); |
364 | bg->bg_bits = cpu_to_le16(ocfs2_bits_per_group(cl)); | ||
365 | bg->bg_chain = cpu_to_le16(my_chain); | 387 | bg->bg_chain = cpu_to_le16(my_chain); |
366 | bg->bg_next_group = cl->cl_recs[my_chain].c_blkno; | 388 | bg->bg_next_group = cl->cl_recs[my_chain].c_blkno; |
367 | bg->bg_parent_dinode = cpu_to_le64(OCFS2_I(alloc_inode)->ip_blkno); | 389 | bg->bg_parent_dinode = cpu_to_le64(OCFS2_I(alloc_inode)->ip_blkno); |
368 | bg->bg_blkno = cpu_to_le64(group_blkno); | 390 | bg->bg_blkno = cpu_to_le64(group_blkno); |
391 | if (group_clusters == le16_to_cpu(cl->cl_cpg)) | ||
392 | bg->bg_bits = cpu_to_le16(ocfs2_bits_per_group(cl)); | ||
393 | else | ||
394 | ocfs2_bg_discontig_add_extent(osb, bg, cl, bg->bg_blkno, | ||
395 | group_clusters); | ||
396 | |||
369 | /* set the 1st bit in the bitmap to account for the descriptor block */ | 397 | /* set the 1st bit in the bitmap to account for the descriptor block */ |
370 | ocfs2_set_bit(0, (unsigned long *)bg->bg_bitmap); | 398 | ocfs2_set_bit(0, (unsigned long *)bg->bg_bitmap); |
371 | bg->bg_free_bits_count = cpu_to_le16(le16_to_cpu(bg->bg_bits) - 1); | 399 | bg->bg_free_bits_count = cpu_to_le16(le16_to_cpu(bg->bg_bits) - 1); |
@@ -396,6 +424,218 @@ static inline u16 ocfs2_find_smallest_chain(struct ocfs2_chain_list *cl) | |||
396 | return best; | 424 | return best; |
397 | } | 425 | } |
398 | 426 | ||
427 | static struct buffer_head * | ||
428 | ocfs2_block_group_alloc_contig(struct ocfs2_super *osb, handle_t *handle, | ||
429 | struct inode *alloc_inode, | ||
430 | struct ocfs2_alloc_context *ac, | ||
431 | struct ocfs2_chain_list *cl) | ||
432 | { | ||
433 | int status; | ||
434 | u32 bit_off, num_bits; | ||
435 | u64 bg_blkno; | ||
436 | struct buffer_head *bg_bh; | ||
437 | unsigned int alloc_rec = ocfs2_find_smallest_chain(cl); | ||
438 | |||
439 | status = ocfs2_claim_clusters(osb, handle, ac, | ||
440 | le16_to_cpu(cl->cl_cpg), &bit_off, | ||
441 | &num_bits); | ||
442 | if (status < 0) { | ||
443 | if (status != -ENOSPC) | ||
444 | mlog_errno(status); | ||
445 | goto bail; | ||
446 | } | ||
447 | |||
448 | /* setup the group */ | ||
449 | bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off); | ||
450 | mlog(0, "new descriptor, record %u, at block %llu\n", | ||
451 | alloc_rec, (unsigned long long)bg_blkno); | ||
452 | |||
453 | bg_bh = sb_getblk(osb->sb, bg_blkno); | ||
454 | if (!bg_bh) { | ||
455 | status = -EIO; | ||
456 | mlog_errno(status); | ||
457 | goto bail; | ||
458 | } | ||
459 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(alloc_inode), bg_bh); | ||
460 | |||
461 | status = ocfs2_block_group_fill(handle, alloc_inode, bg_bh, | ||
462 | bg_blkno, num_bits, alloc_rec, cl); | ||
463 | if (status < 0) { | ||
464 | brelse(bg_bh); | ||
465 | mlog_errno(status); | ||
466 | } | ||
467 | |||
468 | bail: | ||
469 | return status ? ERR_PTR(status) : bg_bh; | ||
470 | } | ||
471 | |||
472 | static int ocfs2_block_group_claim_bits(struct ocfs2_super *osb, | ||
473 | handle_t *handle, | ||
474 | struct ocfs2_alloc_context *ac, | ||
475 | unsigned int min_bits, | ||
476 | u32 *bit_off, u32 *num_bits) | ||
477 | { | ||
478 | int status; | ||
479 | |||
480 | while (min_bits) { | ||
481 | status = ocfs2_claim_clusters(osb, handle, ac, min_bits, | ||
482 | bit_off, num_bits); | ||
483 | if (status != -ENOSPC) | ||
484 | break; | ||
485 | |||
486 | min_bits >>= 1; | ||
487 | } | ||
488 | |||
489 | return status; | ||
490 | } | ||
491 | |||
492 | static int ocfs2_block_group_grow_discontig(handle_t *handle, | ||
493 | struct inode *alloc_inode, | ||
494 | struct buffer_head *bg_bh, | ||
495 | struct ocfs2_alloc_context *ac, | ||
496 | struct ocfs2_chain_list *cl, | ||
497 | unsigned int min_bits) | ||
498 | { | ||
499 | int status; | ||
500 | struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb); | ||
501 | struct ocfs2_group_desc *bg = | ||
502 | (struct ocfs2_group_desc *)bg_bh->b_data; | ||
503 | unsigned int needed = | ||
504 | ocfs2_bits_per_group(cl) - le16_to_cpu(bg->bg_bits); | ||
505 | u32 p_cpos, clusters; | ||
506 | u64 p_blkno; | ||
507 | struct ocfs2_extent_list *el = &bg->bg_list; | ||
508 | |||
509 | status = ocfs2_journal_access_gd(handle, | ||
510 | INODE_CACHE(alloc_inode), | ||
511 | bg_bh, | ||
512 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
513 | if (status < 0) { | ||
514 | mlog_errno(status); | ||
515 | goto bail; | ||
516 | } | ||
517 | |||
518 | while ((needed > 0) && (le16_to_cpu(el->l_next_free_rec) < | ||
519 | le16_to_cpu(el->l_count))) { | ||
520 | status = ocfs2_extend_trans(handle, OCFS2_SUBALLOC_ALLOC); | ||
521 | if (status) { | ||
522 | mlog_errno(status); | ||
523 | goto bail; | ||
524 | } | ||
525 | |||
526 | if (min_bits > needed) | ||
527 | min_bits = needed; | ||
528 | status = ocfs2_block_group_claim_bits(osb, handle, ac, | ||
529 | min_bits, &p_cpos, | ||
530 | &clusters); | ||
531 | if (status < 0) { | ||
532 | if (status != -ENOSPC) | ||
533 | mlog_errno(status); | ||
534 | goto bail; | ||
535 | } | ||
536 | p_blkno = ocfs2_clusters_to_blocks(osb->sb, p_cpos); | ||
537 | ocfs2_bg_discontig_add_extent(osb, bg, cl, p_blkno, | ||
538 | clusters); | ||
539 | |||
540 | min_bits = clusters; | ||
541 | needed = ocfs2_bits_per_group(cl) - le16_to_cpu(bg->bg_bits); | ||
542 | } | ||
543 | |||
544 | if (needed > 0) { | ||
545 | } | ||
546 | |||
547 | ocfs2_journal_dirty(handle, bg_bh); | ||
548 | |||
549 | bail: | ||
550 | return status; | ||
551 | } | ||
552 | |||
553 | static void ocfs2_bg_alloc_cleanup(struct inode *alloc_inode, | ||
554 | struct buffer_head *bg_bh, | ||
555 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
556 | { | ||
557 | int i; | ||
558 | struct ocfs2_group_desc *bg; | ||
559 | struct ocfs2_extent_list *el; | ||
560 | struct ocfs2_extent_rec *rec; | ||
561 | |||
562 | if (!bg_bh) | ||
563 | return; | ||
564 | |||
565 | bg = (struct ocfs2_group_desc *)bg_bh->b_data; | ||
566 | el = &bg->bg_list; | ||
567 | for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) { | ||
568 | rec = &el->l_recs[i]; | ||
569 | ocfs2_cache_cluster_dealloc(dealloc, | ||
570 | le64_to_cpu(rec->e_blkno), | ||
571 | le32_to_cpu(rec->e_leaf_clusters)); | ||
572 | } | ||
573 | |||
574 | ocfs2_remove_from_cache(INODE_CACHE(alloc_inode), bg_bh); | ||
575 | brelse(bg_bh); | ||
576 | } | ||
577 | |||
578 | static struct buffer_head * | ||
579 | ocfs2_block_group_alloc_discontig(handle_t *handle, | ||
580 | struct inode *alloc_inode, | ||
581 | struct ocfs2_alloc_context *ac, | ||
582 | struct ocfs2_chain_list *cl, | ||
583 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
584 | { | ||
585 | int status; | ||
586 | u32 bit_off, num_bits; | ||
587 | u64 bg_blkno; | ||
588 | unsigned int min_bits = le16_to_cpu(cl->cl_cpg) >> 1; | ||
589 | struct buffer_head *bg_bh = NULL; | ||
590 | unsigned int alloc_rec = ocfs2_find_smallest_chain(cl); | ||
591 | struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb); | ||
592 | |||
593 | if (!ocfs2_supports_discontig_bh(osb)) { | ||
594 | status = -ENOSPC; | ||
595 | goto bail; | ||
596 | } | ||
597 | |||
598 | /* Claim the first region */ | ||
599 | status = ocfs2_block_group_claim_bits(osb, handle, ac, min_bits, | ||
600 | &bit_off, &num_bits); | ||
601 | if (status < 0) { | ||
602 | if (status != -ENOSPC) | ||
603 | mlog_errno(status); | ||
604 | goto bail; | ||
605 | } | ||
606 | min_bits = num_bits; | ||
607 | |||
608 | /* setup the group */ | ||
609 | bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off); | ||
610 | mlog(0, "new descriptor, record %u, at block %llu\n", | ||
611 | alloc_rec, (unsigned long long)bg_blkno); | ||
612 | |||
613 | bg_bh = sb_getblk(osb->sb, bg_blkno); | ||
614 | if (!bg_bh) { | ||
615 | status = -EIO; | ||
616 | mlog_errno(status); | ||
617 | goto bail; | ||
618 | } | ||
619 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(alloc_inode), bg_bh); | ||
620 | |||
621 | status = ocfs2_block_group_fill(handle, alloc_inode, bg_bh, | ||
622 | bg_blkno, num_bits, alloc_rec, cl); | ||
623 | if (status < 0) { | ||
624 | mlog_errno(status); | ||
625 | goto bail; | ||
626 | } | ||
627 | |||
628 | status = ocfs2_block_group_grow_discontig(handle, alloc_inode, | ||
629 | bg_bh, ac, cl, min_bits); | ||
630 | if (status) | ||
631 | mlog_errno(status); | ||
632 | |||
633 | bail: | ||
634 | if (status) | ||
635 | ocfs2_bg_alloc_cleanup(alloc_inode, bg_bh, dealloc); | ||
636 | return status ? ERR_PTR(status) : bg_bh; | ||
637 | } | ||
638 | |||
399 | /* | 639 | /* |
400 | * We expect the block group allocator to already be locked. | 640 | * We expect the block group allocator to already be locked. |
401 | */ | 641 | */ |
@@ -411,16 +651,17 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
411 | struct ocfs2_chain_list *cl; | 651 | struct ocfs2_chain_list *cl; |
412 | struct ocfs2_alloc_context *ac = NULL; | 652 | struct ocfs2_alloc_context *ac = NULL; |
413 | handle_t *handle = NULL; | 653 | handle_t *handle = NULL; |
414 | u32 bit_off, num_bits; | ||
415 | u16 alloc_rec; | ||
416 | u64 bg_blkno; | 654 | u64 bg_blkno; |
417 | struct buffer_head *bg_bh = NULL; | 655 | struct buffer_head *bg_bh = NULL; |
418 | struct ocfs2_group_desc *bg; | 656 | struct ocfs2_group_desc *bg; |
657 | struct ocfs2_cached_dealloc_ctxt dealloc; | ||
419 | 658 | ||
420 | BUG_ON(ocfs2_is_cluster_bitmap(alloc_inode)); | 659 | BUG_ON(ocfs2_is_cluster_bitmap(alloc_inode)); |
421 | 660 | ||
422 | mlog_entry_void(); | 661 | mlog_entry_void(); |
423 | 662 | ||
663 | ocfs2_init_dealloc_ctxt(&dealloc); | ||
664 | |||
424 | cl = &fe->id2.i_chain; | 665 | cl = &fe->id2.i_chain; |
425 | status = ocfs2_reserve_clusters_with_limit(osb, | 666 | status = ocfs2_reserve_clusters_with_limit(osb, |
426 | le16_to_cpu(cl->cl_cpg), | 667 | le16_to_cpu(cl->cl_cpg), |
@@ -446,44 +687,21 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
446 | (unsigned long long)*last_alloc_group); | 687 | (unsigned long long)*last_alloc_group); |
447 | ac->ac_last_group = *last_alloc_group; | 688 | ac->ac_last_group = *last_alloc_group; |
448 | } | 689 | } |
449 | status = ocfs2_claim_clusters(osb, | 690 | |
450 | handle, | 691 | bg_bh = ocfs2_block_group_alloc_contig(osb, handle, alloc_inode, |
451 | ac, | 692 | ac, cl); |
452 | le16_to_cpu(cl->cl_cpg), | 693 | if (IS_ERR(bg_bh) && (PTR_ERR(bg_bh) == -ENOSPC)) |
453 | &bit_off, | 694 | bg_bh = ocfs2_block_group_alloc_discontig(handle, |
454 | &num_bits); | 695 | alloc_inode, |
455 | if (status < 0) { | 696 | ac, cl, |
697 | &dealloc); | ||
698 | if (IS_ERR(bg_bh)) { | ||
699 | status = PTR_ERR(bg_bh); | ||
700 | bg_bh = NULL; | ||
456 | if (status != -ENOSPC) | 701 | if (status != -ENOSPC) |
457 | mlog_errno(status); | 702 | mlog_errno(status); |
458 | goto bail; | 703 | goto bail; |
459 | } | 704 | } |
460 | |||
461 | alloc_rec = ocfs2_find_smallest_chain(cl); | ||
462 | |||
463 | /* setup the group */ | ||
464 | bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off); | ||
465 | mlog(0, "new descriptor, record %u, at block %llu\n", | ||
466 | alloc_rec, (unsigned long long)bg_blkno); | ||
467 | |||
468 | bg_bh = sb_getblk(osb->sb, bg_blkno); | ||
469 | if (!bg_bh) { | ||
470 | status = -EIO; | ||
471 | mlog_errno(status); | ||
472 | goto bail; | ||
473 | } | ||
474 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(alloc_inode), bg_bh); | ||
475 | |||
476 | status = ocfs2_block_group_fill(handle, | ||
477 | alloc_inode, | ||
478 | bg_bh, | ||
479 | bg_blkno, | ||
480 | alloc_rec, | ||
481 | cl); | ||
482 | if (status < 0) { | ||
483 | mlog_errno(status); | ||
484 | goto bail; | ||
485 | } | ||
486 | |||
487 | bg = (struct ocfs2_group_desc *) bg_bh->b_data; | 705 | bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
488 | 706 | ||
489 | status = ocfs2_journal_access_di(handle, INODE_CACHE(alloc_inode), | 707 | status = ocfs2_journal_access_di(handle, INODE_CACHE(alloc_inode), |
@@ -493,10 +711,11 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
493 | goto bail; | 711 | goto bail; |
494 | } | 712 | } |
495 | 713 | ||
496 | le32_add_cpu(&cl->cl_recs[alloc_rec].c_free, | 714 | le32_add_cpu(&cl->cl_recs[bg->bg_chain].c_free, |
497 | le16_to_cpu(bg->bg_free_bits_count)); | 715 | le16_to_cpu(bg->bg_free_bits_count)); |
498 | le32_add_cpu(&cl->cl_recs[alloc_rec].c_total, le16_to_cpu(bg->bg_bits)); | 716 | le32_add_cpu(&cl->cl_recs[bg->bg_chain].c_total, |
499 | cl->cl_recs[alloc_rec].c_blkno = cpu_to_le64(bg_blkno); | 717 | le16_to_cpu(bg->bg_bits)); |
718 | cl->cl_recs[bg->bg_chain].c_blkno = cpu_to_le64(bg_blkno); | ||
500 | if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count)) | 719 | if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count)) |
501 | le16_add_cpu(&cl->cl_next_free_rec, 1); | 720 | le16_add_cpu(&cl->cl_next_free_rec, 1); |
502 | 721 | ||
@@ -525,6 +744,11 @@ bail: | |||
525 | if (handle) | 744 | if (handle) |
526 | ocfs2_commit_trans(osb, handle); | 745 | ocfs2_commit_trans(osb, handle); |
527 | 746 | ||
747 | if (ocfs2_dealloc_has_cluster(&dealloc)) { | ||
748 | ocfs2_schedule_truncate_log_flush(osb, 1); | ||
749 | ocfs2_run_deallocs(osb, &dealloc); | ||
750 | } | ||
751 | |||
528 | if (ac) | 752 | if (ac) |
529 | ocfs2_free_alloc_context(ac); | 753 | ocfs2_free_alloc_context(ac); |
530 | 754 | ||