diff options
Diffstat (limited to 'fs/ocfs2/localalloc.c')
-rw-r--r-- | fs/ocfs2/localalloc.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index b889f10d8090..02227c392510 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
@@ -570,6 +570,46 @@ out: | |||
570 | return status; | 570 | return status; |
571 | } | 571 | } |
572 | 572 | ||
573 | /* Check to see if the local alloc window is within ac->ac_max_block */ | ||
574 | static int ocfs2_local_alloc_in_range(struct inode *inode, | ||
575 | struct ocfs2_alloc_context *ac, | ||
576 | u32 bits_wanted) | ||
577 | { | ||
578 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
579 | struct ocfs2_dinode *alloc; | ||
580 | struct ocfs2_local_alloc *la; | ||
581 | int start; | ||
582 | u64 block_off; | ||
583 | |||
584 | if (!ac->ac_max_block) | ||
585 | return 1; | ||
586 | |||
587 | alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; | ||
588 | la = OCFS2_LOCAL_ALLOC(alloc); | ||
589 | |||
590 | start = ocfs2_local_alloc_find_clear_bits(osb, alloc, bits_wanted); | ||
591 | if (start == -1) { | ||
592 | mlog_errno(-ENOSPC); | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * Converting (bm_off + start + bits_wanted) to blocks gives us | ||
598 | * the blkno just past our actual allocation. This is perfect | ||
599 | * to compare with ac_max_block. | ||
600 | */ | ||
601 | block_off = ocfs2_clusters_to_blocks(inode->i_sb, | ||
602 | le32_to_cpu(la->la_bm_off) + | ||
603 | start + bits_wanted); | ||
604 | mlog(0, "Checking %llu against %llu\n", | ||
605 | (unsigned long long)block_off, | ||
606 | (unsigned long long)ac->ac_max_block); | ||
607 | if (block_off > ac->ac_max_block) | ||
608 | return 0; | ||
609 | |||
610 | return 1; | ||
611 | } | ||
612 | |||
573 | /* | 613 | /* |
574 | * make sure we've got at least bits_wanted contiguous bits in the | 614 | * make sure we've got at least bits_wanted contiguous bits in the |
575 | * local alloc. You lose them when you drop i_mutex. | 615 | * local alloc. You lose them when you drop i_mutex. |
@@ -658,6 +698,21 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
658 | goto bail; | 698 | goto bail; |
659 | } | 699 | } |
660 | 700 | ||
701 | if (ac->ac_max_block) | ||
702 | mlog(0, "Calling in_range for max block %llu\n", | ||
703 | (unsigned long long)ac->ac_max_block); | ||
704 | |||
705 | if (!ocfs2_local_alloc_in_range(local_alloc_inode, ac, | ||
706 | bits_wanted)) { | ||
707 | /* | ||
708 | * The window is outside ac->ac_max_block. | ||
709 | * This errno tells the caller to keep localalloc enabled | ||
710 | * but to get the allocation from the main bitmap. | ||
711 | */ | ||
712 | status = -EFBIG; | ||
713 | goto bail; | ||
714 | } | ||
715 | |||
661 | ac->ac_inode = local_alloc_inode; | 716 | ac->ac_inode = local_alloc_inode; |
662 | /* We should never use localalloc from another slot */ | 717 | /* We should never use localalloc from another slot */ |
663 | ac->ac_alloc_slot = osb->slot_num; | 718 | ac->ac_alloc_slot = osb->slot_num; |