[Ocfs2-tools-commits] mfasheh commits r1169 - in trunk/libocfs2: . include
svn-commits@oss.oracle.com
svn-commits at oss.oracle.com
Mon Feb 27 17:23:54 CST 2006
Author: mfasheh
Date: 2006-02-27 17:23:53 -0600 (Mon, 27 Feb 2006)
New Revision: 1169
Modified:
trunk/libocfs2/alloc.c
trunk/libocfs2/bitmap.c
trunk/libocfs2/chainalloc.c
trunk/libocfs2/extend_file.c
trunk/libocfs2/include/bitmap.h
trunk/libocfs2/include/ocfs2.h
Log:
* Teach libocfs2 about discontiguous allocation.
Modified: trunk/libocfs2/alloc.c
===================================================================
--- trunk/libocfs2/alloc.c 2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/alloc.c 2006-02-27 23:23:53 UTC (rev 1169)
@@ -409,38 +409,38 @@
return ret;
}
-/* This function needs to be filled out. Essentially, it should be
- * calling a function in chainalloc.c. Something like
- * "ocfs2_chain_alloc_range()". The difference between that and
- * ocfs2_chain_alloc() is that the range can return a number of bits.
- * That function should take a 'required' number of bits, and return
- * the biggest chunk available. It will need some sort of
- * "find_clear_bit_range()" function for the bitmaps.
- *
- * XXX what to do about local allocs?
+/* XXX what to do about local allocs?
* XXX Well, we shouldn't use local allocs to allocate, as we are
* userspace and we have the entire bitmap in memory. However, this
* doesn't solve the issue of "is space still in dirty local
* allocs?"
*/
errcode_t ocfs2_new_clusters(ocfs2_filesys *fs,
+ uint32_t min,
uint32_t requested,
- uint64_t *start_blkno)
+ uint64_t *start_blkno,
+ uint32_t *clusters_found)
+
{
errcode_t ret;
uint64_t start_bit;
+ uint64_t found;
ret = ocfs2_load_allocator(fs, GLOBAL_BITMAP_SYSTEM_INODE,
0, &fs->fs_cluster_alloc);
if (ret)
goto out;
- ret = ocfs2_chain_alloc_range(fs, fs->fs_cluster_alloc, requested,
- &start_bit);
+ ret = ocfs2_chain_alloc_range(fs, fs->fs_cluster_alloc, min, requested,
+ &start_bit, &found);
if (ret)
goto out;
*start_blkno = ocfs2_clusters_to_blocks(fs, start_bit);
+ /* We never have enough bits that can be allocated
+ * contiguously to overflow this. The lower level API needs
+ * fixing. */
+ *clusters_found = (uint32_t) found;
ret = ocfs2_write_chain_allocator(fs, fs->fs_cluster_alloc);
if (ret)
Modified: trunk/libocfs2/bitmap.c
===================================================================
--- trunk/libocfs2/bitmap.c 2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/bitmap.c 2006-02-27 23:23:53 UTC (rev 1169)
@@ -138,13 +138,21 @@
}
/* kind of poorly named, but I couldn't come up with something nicer */
-errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t len,
- uint64_t *first_bit)
+errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t min,
+ uint64_t len, uint64_t *first_bit,
+ uint64_t *bits_found)
{
- if (len == 0 || len >= bitmap->b_total_bits)
+ errcode_t ret;
+
+ if (min == 0 || len == 0 || len >= bitmap->b_total_bits || min > len)
return OCFS2_ET_INVALID_ARGUMENT;
- return (*bitmap->b_ops->alloc_range)(bitmap, len, first_bit);
+ ret = (*bitmap->b_ops->alloc_range)(bitmap, min, len, first_bit,
+ bits_found);
+ if (ret == 0 && *bits_found < min)
+ abort();
+
+ return ret;
}
errcode_t ocfs2_bitmap_clear_range(ocfs2_bitmap *bitmap, uint64_t len,
@@ -631,62 +639,85 @@
struct alloc_range_args {
ocfs2_bitmap *ar_bitmap;
+ uint64_t ar_min_len;
uint64_t ar_len;
uint64_t ar_first_bit;
+ uint64_t ar_bits_found;
errcode_t ar_ret;
};
+/* Our strategy here to aid discontiguous allocation is to track the
+ * largest free regions (which still fit within ar_min_len) and if the
+ * max allocation fails, fall back to returning one of those. */
static errcode_t alloc_range_func(struct ocfs2_bitmap_region *br,
void *private_data)
{
struct alloc_range_args *ar = private_data;
errcode_t ret = 0;
+ uint64_t best_start, best_len = 0;
int start, end;
- if ((br->br_total_bits - br->br_set_bits) < ar->ar_len)
+ if ((br->br_total_bits - br->br_set_bits) < ar->ar_min_len)
goto out;
- for (start = 0; start + ar->ar_len <= br->br_total_bits; ) {
+ for (start = 0; start + ar->ar_min_len <= br->br_total_bits; ) {
start = ocfs2_find_next_bit_clear(br->br_bitmap,
br->br_total_bits,
start);
if (start == br->br_total_bits)
- goto out;
+ break;
/* avoiding start + 1 here so that start at total_bits - 1
* just works out */
end = ocfs2_find_next_bit_set(br->br_bitmap,
br->br_total_bits,
start);
- if ((end - start) < ar->ar_len) {
- start = end + 1;
- continue;
- }
- if ((end - start) > ar->ar_len)
+ /* We've found a region large enough to hold our max. */
+ if ((end - start) >= ar->ar_len) {
end = start + ar->ar_len;
+ goto found;
+ }
- ar->ar_first_bit = br->br_start_bit + start;
- for (; start < end; start++)
- set_generic_shared(ar->ar_bitmap, br,
- start + br->br_start_bit);
+ if ((end - start) > best_len) {
+ best_len = end - start;
+ best_start = start;
+ }
- ar->ar_ret = 0;
- ret = OCFS2_ET_ITERATION_COMPLETE;
- break;
+ start = end + 1;
}
+ /* Nothing found at all */
+ if (best_len < ar->ar_min_len)
+ goto out;
+
+ /* Best fit works */
+ start = best_start;
+ end = best_start + best_len;
+found:
+ ar->ar_first_bit = br->br_start_bit + start;
+ ar->ar_bits_found = end - start;
+
+ for (; start < end; start++)
+ set_generic_shared(ar->ar_bitmap, br,
+ start + br->br_start_bit);
+
+ ar->ar_ret = 0;
+ ret = OCFS2_ET_ITERATION_COMPLETE;
out:
return ret;
}
errcode_t ocfs2_bitmap_alloc_range_generic(ocfs2_bitmap *bitmap,
+ uint64_t min_len,
uint64_t len,
- uint64_t *first_bit)
+ uint64_t *first_bit,
+ uint64_t *bits_found)
{
errcode_t ret;
struct alloc_range_args ar = {
.ar_bitmap = bitmap,
+ .ar_min_len = min_len,
.ar_len = len,
.ar_ret = OCFS2_ET_BIT_NOT_FOUND,
};
@@ -696,8 +727,10 @@
if (ret == 0)
ret = ar.ar_ret;
- if (ret == 0)
+ if (ret == 0) {
*first_bit = ar.ar_first_bit;
+ *bits_found = ar.ar_bits_found;
+ }
return ret;
}
Modified: trunk/libocfs2/chainalloc.c
===================================================================
--- trunk/libocfs2/chainalloc.c 2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/chainalloc.c 2006-02-27 23:23:53 UTC (rev 1169)
@@ -342,14 +342,16 @@
/* FIXME: Better name, too */
errcode_t ocfs2_chain_alloc_range(ocfs2_filesys *fs,
ocfs2_cached_inode *cinode,
+ uint64_t min,
uint64_t requested,
- uint64_t *start_bit)
+ uint64_t *start_bit,
+ uint64_t *bits_found)
{
if (!cinode->ci_chains)
return OCFS2_ET_INVALID_ARGUMENT;
- return ocfs2_bitmap_alloc_range(cinode->ci_chains, requested,
- start_bit);
+ return ocfs2_bitmap_alloc_range(cinode->ci_chains, min, requested,
+ start_bit, bits_found);
}
errcode_t ocfs2_chain_free_range(ocfs2_filesys *fs,
@@ -502,6 +504,7 @@
{
errcode_t ret;
uint64_t blkno = 0, old_blkno = 0;
+ uint32_t found;
struct ocfs2_group_desc *gd;
char *buf = NULL;
struct ocfs2_chain_rec *rec = NULL;
@@ -513,10 +516,14 @@
gd = (struct ocfs2_group_desc *)buf;
ret = ocfs2_new_clusters(fs, cinode->ci_inode->id2.i_chain.cl_cpg,
- &blkno);
+ cinode->ci_inode->id2.i_chain.cl_cpg,
+ &blkno, &found);
if (ret)
goto out;
+ if (found != cinode->ci_inode->id2.i_chain.cl_cpg)
+ abort();
+
ocfs2_init_group_desc(fs, gd, blkno, fs->fs_super->i_fs_generation,
cinode->ci_inode->i_blkno,
cinode->ci_inode->id2.i_chain.cl_cpg *
Modified: trunk/libocfs2/extend_file.c
===================================================================
--- trunk/libocfs2/extend_file.c 2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/extend_file.c 2006-02-27 23:23:53 UTC (rev 1169)
@@ -357,7 +357,8 @@
while (new_clusters) {
n_clusters = 1;
- ret = ocfs2_new_clusters(fs, n_clusters, &blkno);
+ ret = ocfs2_new_clusters(fs, 1, new_clusters, &blkno,
+ &n_clusters);
if (ret)
break;
Modified: trunk/libocfs2/include/bitmap.h
===================================================================
--- trunk/libocfs2/include/bitmap.h 2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/include/bitmap.h 2006-02-27 23:23:53 UTC (rev 1169)
@@ -65,8 +65,9 @@
struct ocfs2_bitmap_region *br,
uint64_t bitno,
int new_val);
- errcode_t (*alloc_range)(ocfs2_bitmap *bitmap, uint64_t len,
- uint64_t *first_bit);
+ errcode_t (*alloc_range)(ocfs2_bitmap *bitmap, uint64_t min_len,
+ uint64_t len, uint64_t *first_bit,
+ uint64_t *bits_found);
errcode_t (*clear_range)(ocfs2_bitmap *bitmap, uint64_t len,
uint64_t first_bit);
};
@@ -116,8 +117,10 @@
uint64_t start,
uint64_t *found);
errcode_t ocfs2_bitmap_alloc_range_generic(ocfs2_bitmap *bitmap,
+ uint64_t min_len,
uint64_t len,
- uint64_t *first_bit);
+ uint64_t *first_bit,
+ uint64_t *bits_found);
errcode_t ocfs2_bitmap_clear_range_generic(ocfs2_bitmap *bitmap,
uint64_t len,
uint64_t first_bit);
Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h 2006-02-25 01:24:10 UTC (rev 1168)
+++ trunk/libocfs2/include/ocfs2.h 2006-02-27 23:23:53 UTC (rev 1169)
@@ -430,8 +430,9 @@
errcode_t ocfs2_bitmap_read(ocfs2_bitmap *bitmap);
errcode_t ocfs2_bitmap_write(ocfs2_bitmap *bitmap);
uint64_t ocfs2_bitmap_get_set_bits(ocfs2_bitmap *bitmap);
-errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t len,
- uint64_t *first_bit);
+errcode_t ocfs2_bitmap_alloc_range(ocfs2_bitmap *bitmap, uint64_t min,
+ uint64_t len, uint64_t *first_bit,
+ uint64_t *bits_found);
errcode_t ocfs2_bitmap_clear_range(ocfs2_bitmap *bitmap, uint64_t len,
uint64_t first_bit);
@@ -484,8 +485,10 @@
uint64_t bitno);
errcode_t ocfs2_chain_alloc_range(ocfs2_filesys *fs,
ocfs2_cached_inode *cinode,
+ uint64_t min,
uint64_t requested,
- uint64_t *start_bit);
+ uint64_t *start_bit,
+ uint64_t *bits_found);
errcode_t ocfs2_chain_free_range(ocfs2_filesys *fs,
ocfs2_cached_inode *cinode,
uint64_t len,
@@ -531,8 +534,10 @@
uint32_t new_clusters);
errcode_t ocfs2_truncate(ocfs2_filesys *fs, uint64_t ino, uint64_t new_i_size);
errcode_t ocfs2_new_clusters(ocfs2_filesys *fs,
+ uint32_t min,
uint32_t requested,
- uint64_t *start_blkno);
+ uint64_t *start_blkno,
+ uint32_t *clusters_found);
errcode_t ocfs2_free_clusters(ocfs2_filesys *fs,
uint32_t len,
uint64_t start_blkno);
More information about the Ocfs2-tools-commits
mailing list