[Ocfs2-commits] mfasheh commits r1625 - branches/cluster-groups/src
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu Nov 4 19:37:42 CST 2004
Author: mfasheh
Date: 2004-11-04 19:37:41 -0600 (Thu, 04 Nov 2004)
New Revision: 1625
Modified:
branches/cluster-groups/src/alloc.c
branches/cluster-groups/src/localalloc.c
branches/cluster-groups/src/ocfs_journal.h
branches/cluster-groups/src/suballoc.c
branches/cluster-groups/src/suballoc.h
Log:
* factor out the descriptor search stuff into seperate functions for
metadata and data.
* teach the suballocation stuff how to try other chains if the one it picked
winds up being empty (this will only ever really happen with data
allocation).
* clean up and rework some of the journal credits affected by this stuff.
Modified: branches/cluster-groups/src/alloc.c
===================================================================
--- branches/cluster-groups/src/alloc.c 2004-11-04 22:14:37 UTC (rev 1624)
+++ branches/cluster-groups/src/alloc.c 2004-11-05 01:37:41 UTC (rev 1625)
@@ -1125,7 +1125,7 @@
}
OCFS_ASSERT(delete_blk);
- status = ocfs_free_clusters(osb, handle, tc->tc_bitmap_inode,
+ status = ocfs_free_clusters(handle, tc->tc_bitmap_inode,
tc->tc_bitmap_bh, delete_blk,
clusters_to_del);
if (status < 0) {
Modified: branches/cluster-groups/src/localalloc.c
===================================================================
--- branches/cluster-groups/src/localalloc.c 2004-11-04 22:14:37 UTC (rev 1624)
+++ branches/cluster-groups/src/localalloc.c 2004-11-05 01:37:41 UTC (rev 1625)
@@ -770,7 +770,7 @@
"%u (la_start_blk = %llu, blkno = %llu)\n",
count, start, la_start_blk, blkno);
- status = ocfs_free_clusters(osb, handle, main_bm_inode,
+ status = ocfs_free_clusters(handle, main_bm_inode,
main_bm_bh, blkno, count);
if (status < 0) {
LOG_ERROR_STATUS(status);
Modified: branches/cluster-groups/src/ocfs_journal.h
===================================================================
--- branches/cluster-groups/src/ocfs_journal.h 2004-11-04 22:14:37 UTC (rev 1624)
+++ branches/cluster-groups/src/ocfs_journal.h 2004-11-05 01:37:41 UTC (rev 1625)
@@ -319,6 +319,9 @@
* prev. group desc. if we relink. */
#define OCFS_SUBALLOC_ALLOC (3)
+/* dinode + group descriptor update. We don't relink on free yet. */
+#define OCFS_SUBALLOC_FREE (2)
+
/* data block for new dir/symlink, 2 for bitmap updates (bitmap fe +
* bitmap block for the new bit) */
#define OCFS_DIR_LINK_ADDITIONAL_CREDITS (1 + 2)
@@ -329,7 +332,8 @@
+ OCFS_DIR_LINK_ADDITIONAL_CREDITS)
/* local alloc metadata change + main bitmap updates */
-#define OCFS_WINDOW_MOVE_CREDITS (OCFS_INODE_UPDATE_CREDITS + 8 + 5)
+#define OCFS_WINDOW_MOVE_CREDITS (OCFS_INODE_UPDATE_CREDITS \
+ + OCFS_SUBALLOC_ALLOC + OCFS_SUBALLOC_FREE)
/* used when we don't need an allocation change for a dir extend. One
* for the dinode, one for the new block. */
@@ -358,16 +362,17 @@
u32 bits_wanted)
{
int bitmap_blocks, sysfile_bitmap_blocks, dinode_blocks;
- /* take advantage of the fact that we always allocate in one
- * large chunk. */
- bitmap_blocks = ocfs_blocks_for_bits(sb, bits_wanted) + 1;
+ /* bitmap dinode, group desc. + relinked group. */
+ bitmap_blocks = OCFS_SUBALLOC_ALLOC;
+
/* we might need to shift tree depth so lets assume an
- * absolute worst case of complete fragmentation so for each
- * new metadata block we have a descriptor and the actual
- * block and of course 1 credit for the metadata dinode
- * update. */
- sysfile_bitmap_blocks = 1 + 3 * ocfs2_extend_meta_needed(fe);
+ * absolute worst case of complete fragmentation. Even with
+ * that, we only need one update for the dinode, and then
+ * however many metadata chunks needed * a remaining suballoc
+ * alloc. */
+ sysfile_bitmap_blocks = 1 +
+ (OCFS_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(fe);
/* this does not include *new* metadata blocks, which are
* accounted for in sysfile_bitmap_blocks. fe +
@@ -394,7 +399,7 @@
unsigned int cpg)
{
int blocks;
- int bitmap_blocks = ocfs_blocks_for_bits(sb, cpg) + 1;
+ int bitmap_blocks = OCFS_SUBALLOC_ALLOC + 1;
/* parent inode update + new block group header + bitmap inode update
+ bitmap blocks affected */
blocks = 1 + 1 + 1 + bitmap_blocks;
@@ -420,9 +425,9 @@
&& ((last_el->l_recs[i].e_clusters - clusters_to_del) == 0))
credits += 1 + fe->id2.i_list.l_tree_depth;
- /* bitmap fe + bitmap blocks covered by this extent */
- bitmap_blocks = 1 + ocfs_blocks_for_bits(sb,
- clusters_to_del);
+ /* bitmap fe + group descriptor */
+ bitmap_blocks = OCFS_SUBALLOC_FREE;
+
credits += bitmap_blocks;
return(credits);
Modified: branches/cluster-groups/src/suballoc.c
===================================================================
--- branches/cluster-groups/src/suballoc.c 2004-11-04 22:14:37 UTC (rev 1624)
+++ branches/cluster-groups/src/suballoc.c 2004-11-05 01:37:41 UTC (rev 1625)
@@ -59,8 +59,21 @@
static int ocfs_block_group_alloc(ocfs_super *osb,
struct inode *alloc_inode,
struct buffer_head *bh);
+static int ocfs2_cluster_group_search(struct inode *inode,
+ struct buffer_head *group_bh,
+ u32 bits_wanted, u32 min_bits,
+ u16 *bit_off, u16 *bits_found);
+static int ocfs2_block_group_search(struct inode *inode,
+ struct buffer_head *group_bh,
+ u32 bits_wanted, u32 min_bits,
+ u16 *bit_off, u16 *bits_found);
+static int ocfs_search_suballoc_chain(ocfs2_alloc_context *ac,
+ u32 bits_wanted,
+ u32 min_bits,
+ u16 *bit_off,
+ unsigned int *num_bits,
+ u64 *bg_blkno);
static int ocfs_claim_suballoc_bits(ocfs_super *osb,
- ocfs_journal_handle *handle,
ocfs2_alloc_context *ac,
u32 bits_wanted,
u32 min_bits,
@@ -488,6 +501,7 @@
}
(*ac)->ac_inode = igrab(alloc_inode);
+ (*ac)->ac_group_search = ocfs2_block_group_search;
status = ocfs_reserve_suballoc_bits(osb, (*ac));
if (status < 0) {
@@ -535,6 +549,7 @@
}
(*ac)->ac_inode = igrab(alloc_inode);
+ (*ac)->ac_group_search = &ocfs2_block_group_search;
status = ocfs_reserve_suballoc_bits(osb, *ac);
if (status < 0) {
@@ -612,6 +627,7 @@
}
(*ac)->ac_which = OCFS_AC_USE_MAIN;
(*ac)->ac_inode = igrab(main_bitmap_inode);
+ (*ac)->ac_group_search = &ocfs2_cluster_group_search;
status = ocfs_reserve_suballoc_bits(osb, *ac);
if (status < 0) {
LOG_ERROR_STATUS(status);
@@ -885,41 +901,89 @@
return bg->bg_free_bits_count > wanted;
}
-/* will give out up to bits_wanted contiguous bits. */
-static int ocfs_claim_suballoc_bits(ocfs_super *osb,
- ocfs_journal_handle *handle,
- ocfs2_alloc_context *ac,
- u32 bits_wanted,
- u32 min_bits,
- u16 *bit_off,
- unsigned int *num_bits,
- u64 *bg_blkno)
+/* return 0 to keep searching, > 0 on succes (and populate the return
+ * values) and < 0 on failure. -ENOSPC means that we hit the end of
+ * the chain without finding anything. */
+static int ocfs2_cluster_group_search(struct inode *inode,
+ struct buffer_head *group_bh,
+ u32 bits_wanted, u32 min_bits,
+ u16 *bit_off, u16 *bits_found)
{
+ int ret = 0;
+ ocfs2_group_desc *bg = (ocfs2_group_desc *) group_bh->b_data;
+ u16 tmp_off, tmp_found;
+
+ OCFS_ASSERT(ocfs2_is_cluster_bitmap(inode));
+
+ if (bg->bg_free_bits_count) {
+ ret = ocfs_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
+ group_bh, bits_wanted,
+ &tmp_off, &tmp_found);
+ if (ret == -ENOSPC)
+ ret = 0;
+ else if (!ret) {
+ if (min_bits <= tmp_found) {
+ *bit_off = tmp_off;
+ *bits_found = tmp_found;
+ ret = 1; /* success */
+ }
+ }
+ }
+
+ if (!ret && !bg->bg_next_group)
+ ret = -ENOSPC;
+ return ret;
+}
+
+static int ocfs2_block_group_search(struct inode *inode,
+ struct buffer_head *group_bh,
+ u32 bits_wanted, u32 min_bits,
+ u16 *bit_off, u16 *bits_found)
+{
+ int ret = 0;
+ ocfs2_group_desc *bg = (ocfs2_group_desc *) group_bh->b_data;
+
+ OCFS_ASSERT(min_bits == 1);
+ OCFS_ASSERT(!ocfs2_is_cluster_bitmap(inode));
+
+ if (bg->bg_free_bits_count) {
+ ret = ocfs_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
+ group_bh, bits_wanted,
+ bit_off, bits_found);
+ if (ret == -ENOSPC)
+ ret = 0;
+ else if (!ret)
+ ret = 1; /* success */
+ } else if (!bg->bg_next_group) {
+ /* This really shouldn't happen... */
+ LOG_ERROR_ARGS("Failure to find free space in suballoc "
+ "chain!\n");
+ ret = -ENOSPC;
+ }
+ return ret;
+}
+
+static int ocfs_search_suballoc_chain(ocfs2_alloc_context *ac,
+ u32 bits_wanted,
+ u32 min_bits,
+ u16 *bit_off,
+ unsigned int *num_bits,
+ u64 *bg_blkno)
+{
int status;
+ ocfs_journal_handle *handle = ac->ac_handle;
struct inode *alloc_inode = ac->ac_inode;
+ ocfs_super *osb = OCFS2_SB(alloc_inode->i_sb);
struct buffer_head *group_bh = NULL;
struct buffer_head *prev_group_bh = NULL;
- ocfs2_chain_list *cl;
- ocfs2_dinode *fe;
+ ocfs2_dinode *fe = (ocfs2_dinode *) ac->ac_bh->b_data;
+ ocfs2_chain_list *cl = (ocfs2_chain_list *) &fe->id2.i_chain;
ocfs2_group_desc *bg;
u16 chain, tmp_bits;
u64 next_group;
- LOG_ENTRY();
- OCFS_ASSERT(ac->ac_bits_given < ac->ac_bits_wanted);
- OCFS_ASSERT(ac->ac_handle == handle);
- OCFS_ASSERT(bits_wanted <= (ac->ac_bits_wanted - ac->ac_bits_given));
- OCFS_ASSERT(ac->ac_bh);
-
- fe = (ocfs2_dinode *) ac->ac_bh->b_data;
- OCFS_ASSERT_RO(IS_VALID_FILE_ENTRY(fe));
- OCFS_ASSERT_RO(fe->id1.bitmap1.i_used < fe->id1.bitmap1.i_total);
-
- cl = (ocfs2_chain_list *) &fe->id2.i_chain;
-
- chain = ocfs2_find_victim_chain(cl);
-
+ chain = ac->ac_chain;
LOG_TRACE_ARGS("trying to alloc %u bits from chain %u, inode %llu\n",
bits_wanted, chain, OCFS_I(alloc_inode)->ip_blkno);
@@ -929,13 +993,14 @@
LOG_ERROR_STATUS(status);
goto bail;
}
-
bg = (ocfs2_group_desc *) group_bh->b_data;
OCFS_ASSERT_RO(IS_VALID_GROUP_DESC(bg));
/* for now, the chain search is a bit simplistic. We just use
* the 1st group with any empty bits. */
- while (!bg->bg_free_bits_count) {
+ while ((status = ac->ac_group_search(alloc_inode, group_bh,
+ bits_wanted, min_bits, bit_off,
+ &tmp_bits)) == 0) {
/*
* This means we've walked off the end of a chain that
* we thought had bits, but didn't. While this
@@ -960,21 +1025,11 @@
bg = (ocfs2_group_desc *) group_bh->b_data;
OCFS_ASSERT_RO(IS_VALID_GROUP_DESC(bg));
}
-
- status = ocfs_block_group_find_clear_bits(osb,
- group_bh,
- bits_wanted,
- bit_off,
- &tmp_bits);
if (status < 0) {
- LOG_ERROR_STATUS(status);
+ if (status != -ENOSPC)
+ LOG_ERROR_STATUS(status);
goto bail;
}
- if (tmp_bits < min_bits) {
-#warning need to search another chain here.
- status = -ENOSPC;
- goto bail;
- }
*num_bits = tmp_bits;
@@ -993,8 +1048,9 @@
* Do this *after* figuring out how many bits we're taking out
* of our target group.
*/
- if ((prev_group_bh)
- && (ocfs_block_group_reasonably_empty(bg, *num_bits))) {
+ if (ac->ac_allow_chain_relink &&
+ (prev_group_bh) &&
+ (ocfs_block_group_reasonably_empty(bg, *num_bits))) {
status = ocfs_relink_block_group(handle, alloc_inode,
ac->ac_bh, group_bh,
prev_group_bh, chain);
@@ -1054,6 +1110,73 @@
return status;
}
+/* will give out up to bits_wanted contiguous bits. */
+static int ocfs_claim_suballoc_bits(ocfs_super *osb,
+ ocfs2_alloc_context *ac,
+ u32 bits_wanted,
+ u32 min_bits,
+ u16 *bit_off,
+ unsigned int *num_bits,
+ u64 *bg_blkno)
+{
+ int status;
+ u16 victim, i;
+ ocfs2_chain_list *cl;
+ ocfs2_dinode *fe;
+
+ LOG_ENTRY();
+
+ OCFS_ASSERT(ac->ac_bits_given < ac->ac_bits_wanted);
+ OCFS_ASSERT(bits_wanted <= (ac->ac_bits_wanted - ac->ac_bits_given));
+ OCFS_ASSERT(ac->ac_bh);
+
+ fe = (ocfs2_dinode *) ac->ac_bh->b_data;
+ OCFS_ASSERT_RO(IS_VALID_FILE_ENTRY(fe));
+ OCFS_ASSERT_RO(fe->id1.bitmap1.i_used < fe->id1.bitmap1.i_total);
+
+ cl = (ocfs2_chain_list *) &fe->id2.i_chain;
+
+ victim = ocfs2_find_victim_chain(cl);
+ ac->ac_chain = victim;
+ ac->ac_allow_chain_relink = 1;
+
+ status = ocfs_search_suballoc_chain(ac, bits_wanted, min_bits, bit_off,
+ num_bits, bg_blkno);
+ if (!status)
+ goto bail;
+ if (status < 0 && status != -ENOSPC) {
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+
+ /* If we didn't pick a good victim, then just default to
+ * searching each chain in order. Don't allow chain relinking
+ * because we only calculate enough journal credits for one
+ * relink per alloc. */
+ ac->ac_allow_chain_relink = 0;
+ for (i = 0; i < cl->cl_next_free_rec; i ++) {
+ if (i == victim)
+ continue;
+ if (!cl->cl_recs[i].c_free)
+ continue;
+
+ ac->ac_chain = i;
+ status = ocfs_search_suballoc_chain(ac, bits_wanted, min_bits,
+ bit_off, num_bits,
+ bg_blkno);
+ if (!status)
+ break;
+ if (status < 0 && status != -ENOSPC) {
+ LOG_ERROR_STATUS(status);
+ goto bail;
+ }
+ }
+bail:
+
+ LOG_EXIT_STATUS(status);
+ return status;
+}
+
int ocfs_claim_metadata(ocfs_super *osb,
ocfs_journal_handle *handle,
ocfs2_alloc_context *ac,
@@ -1071,7 +1194,6 @@
OCFS_ASSERT(ac->ac_handle == handle);
status = ocfs_claim_suballoc_bits(osb,
- handle,
ac,
bits_wanted,
1,
@@ -1110,7 +1232,6 @@
OCFS_ASSERT(ac->ac_handle == handle);
status = ocfs_claim_suballoc_bits(osb,
- handle,
ac,
1,
1,
@@ -1167,12 +1288,19 @@
cluster_start,
num_clusters);
} else {
- /* clamp this down to a realistic size. */
+ if (min_clusters > (osb->bitmap_cpg - 1)) {
+ /* The only paths asking for contiguousness
+ * should know about this already. */
+ LOG_ERROR_ARGS("minimum allocation requested exceeds "
+ "group bitmap size!");
+ status = -ENOSPC;
+ goto bail;
+ }
+ /* clamp the current request down to a realistic size. */
if (bits_wanted > (osb->bitmap_cpg - 1))
bits_wanted = osb->bitmap_cpg - 1;
status = ocfs_claim_suballoc_bits(osb,
- handle,
ac,
bits_wanted,
min_clusters,
@@ -1411,8 +1539,7 @@
data_blkno - *bg_blkno);
}
-int ocfs_free_clusters(ocfs_super *osb,
- ocfs_journal_handle *handle,
+int ocfs_free_clusters(ocfs_journal_handle *handle,
struct inode *bitmap_inode,
struct buffer_head *bitmap_bh,
u64 start_blk,
Modified: branches/cluster-groups/src/suballoc.h
===================================================================
--- branches/cluster-groups/src/suballoc.h 2004-11-04 22:14:37 UTC (rev 1624)
+++ branches/cluster-groups/src/suballoc.h 2004-11-05 01:37:41 UTC (rev 1625)
@@ -26,6 +26,13 @@
#ifndef _CHAINALLOC_H_
#define _CHAINALLOC_H_
+typedef int (group_search_t)(struct inode *,
+ struct buffer_head *,
+ u32,
+ u32,
+ u16 *,
+ u16 *);
+
typedef struct _ocfs2_alloc_context {
struct inode *ac_inode; /* which bitmap are we allocating from? */
struct buffer_head *ac_bh; /* file entry bh */
@@ -36,7 +43,12 @@
#define OCFS_AC_USE_INODE 3
#define OCFS_AC_USE_META 4
u32 ac_which;
- ocfs_journal_handle *ac_handle; /* debugging mostly. */
+ ocfs_journal_handle *ac_handle;
+
+ /* these are used by the chain search */
+ u16 ac_chain;
+ int ac_allow_chain_relink;
+ group_search_t *ac_group_search;
} ocfs2_alloc_context;
void ocfs_free_alloc_context(ocfs2_alloc_context *ac);
@@ -84,8 +96,7 @@
struct inode *eb_alloc_inode,
struct buffer_head *eb_alloc_bh,
ocfs2_extent_block *eb);
-int ocfs_free_clusters(ocfs_super *osb,
- ocfs_journal_handle *handle,
+int ocfs_free_clusters(ocfs_journal_handle *handle,
struct inode *bitmap_inode,
struct buffer_head *bitmap_bh,
u64 start_blk,
More information about the Ocfs2-commits
mailing list