aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/localalloc.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-09-03 23:03:39 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-13 19:57:07 -0400
commit1187c968852e3c668f3b9376083851f81f6eee22 (patch)
tree23a34ab89f724cc015f9e4f6e8bc6ed0fc20ce51 /fs/ocfs2/localalloc.c
parent08413899db89d8d636c2a2d4ba5c356ab587d7ef (diff)
ocfs2: Limit inode allocation to 32bits.
ocfs2 inode numbers are block numbers. For any filesystem with less than 2^32 blocks, this is not a problem. However, when ocfs2 starts using JDB2, it will be able to support filesystems with more than 2^32 blocks. This would result in inode numbers higher than 2^32. The problem is that stat(2) can't handle those numbers on 32bit machines. The simple solution is to have ocfs2 allocate all inodes below that boundary. The suballoc code is changed to honor an optional block limit. Only the inode suballocator sets that limit - all other allocations stay unlimited. The biggest trick is to grow the inode suballocator beneath that limit. There's no point in allocating block groups that are above the limit, then rejecting their elements later on. We want to prevent the inode allocator from ever having block groups above the limit. This involves a little gyration with the local alloc code. If the local alloc window is above the limit, it signals the caller to try the global bitmap but does not disable the local alloc file (which can be used for other allocations). [ Minor cleanup - removed an ML_NOTICE comment. --Mark ] Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/localalloc.c')
-rw-r--r--fs/ocfs2/localalloc.c55
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 */
574static 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;