[Ocfs2-commits] mfasheh commits r1486 - branches/dlm-changes/src
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Sep 24 18:18:20 CDT 2004
Author: mfasheh
Date: 2004-09-24 18:18:19 -0500 (Fri, 24 Sep 2004)
New Revision: 1486
Modified:
branches/dlm-changes/src/bitmap.c
branches/dlm-changes/src/bitmap.h
Log:
* make bitmap functions support discontiguous allocation of bits by
returning a "best fit" based on what you asked for.
Modified: branches/dlm-changes/src/bitmap.c
===================================================================
--- branches/dlm-changes/src/bitmap.c 2004-09-24 23:16:03 UTC (rev 1485)
+++ branches/dlm-changes/src/bitmap.c 2004-09-24 23:18:19 UTC (rev 1486)
@@ -165,24 +165,40 @@
/*
* ocfs_find_clear_bits()
*
- * sysonly is passed # bits in bitmap that are rserved for system file space
- * in case we have a disk full.
+ * if you don't pass in best_fit_bits, we only try contig and give you
+ * -ENOSPC otherwise.
*
+ * if you pass in best_fit_bits we return -ENOSPC only if we're
+ * completely full, otherwise we'll always set best_fit_bits to at max
+ * numBits, and of course *bitoff to your starting offset.
*/
int ocfs_find_clear_bits(ocfs_super *osb, ocfs_alloc_bm * bitmap,
- __u32 numBits, __u32 offset, __u32 sysonly)
+ u32 numBits, u32 offset, u32 *bitoff,
+ u32 *best_fit_bits)
{
+ int status = 0;
__u32 globalsize, globaloff, localstart, lastbh;
__u32 size = OCFS_BITS_IN_CHUNK(osb->sb);
- __u32 bitoff = 0, count = 0;
+ __u32 count = 0;
+ u32 largest_start, largest_size;
void *buffer;
int c;
struct buffer_head *currbh = NULL;
- LOG_ENTRY_ARGS ("(0x%p, 0x%p, %u, %u, %u)\n", osb, bitmap, numBits,
- offset, sysonly);
+ LOG_ENTRY_ARGS ("(0x%p, 0x%p, %u, %u)\n", osb, bitmap, numBits,
+ offset);
- globalsize = bitmap->validbits - sysonly;
+ /* We keep track of the biggest contiguous chunk we've seen so
+ * far in these two variables. If we never completely fulfull
+ * the request, we can pass them back for a best try. */
+ largest_start = offset;
+ largest_size = 0;
+
+ if (best_fit_bits)
+ *best_fit_bits = 0;
+
+ *bitoff = 0;
+ globalsize = bitmap->validbits;
lastbh = ocfs_blocks_for_bits(osb->sb, globalsize) - 1;
globaloff = offset;
@@ -199,11 +215,11 @@
"localstart=%u\n", c, lastbh, size, localstart);*/
buffer = currbh->b_data;
- while ((bitoff = find_next_zero_bit(buffer,
+ while ((*bitoff = find_next_zero_bit(buffer,
OCFS_BITS_IN_CHUNK(osb->sb),
localstart)) != -1) {
- /*LOG_TRACE_ARGS("c=%u, globaloff=%u, bitoff=%u, "
- "localstart=%u\n", c, globaloff, bitoff,
+ /*LOG_TRACE_ARGS("c=%u, globaloff=%u, *bitoff=%u, "
+ "localstart=%u\n", c, globaloff, *bitoff,
localstart);*/
/* find_next_zero_bit returns:
@@ -211,10 +227,10 @@
some number < size: at the next zero bit
localstart: if the current one is a zero
*/
- if (bitoff >= size) {
+ if (*bitoff >= size) {
nextbh:
/* we've hit the end of our bh. */
- /*LOG_TRACE_ARGS("bitoff >= size (%u)\n", bitoff,c);*/
+ /*LOG_TRACE_ARGS("*bitoff >= size (%u)\n", *bitoff,c);*/
/* if it's the last bh, then quit the loop */
if (c == lastbh) {
@@ -224,7 +240,7 @@
}
/* otherwise, reset localstart and switch bhs
* and continue */
- localstart = bitoff = 0;
+ localstart = *bitoff = 0;
c++;
currbh = bitmap->chunk[c];
buffer = currbh->b_data;
@@ -236,34 +252,38 @@
continue;
}
- if (!ocfs_test_allocatable(bitoff, currbh)) {
+ if (!ocfs_test_allocatable(*bitoff, currbh)) {
/* We found a zero, but we can't use it as it
* hasn't been put to disk yet! */
count = 0;
- localstart = bitoff + 1;
+ localstart = *bitoff + 1;
/* In doing this, we might go over our current bh. */
if (localstart >= size)
goto nextbh;
globaloff =
ocfs_bitmap_off_for_block(osb->sb, c,
- bitoff) + 1;
- } else if (bitoff == localstart) {
- /*LOG_TRACE_ARGS("bitoff == localstart (%u)\n",
- bitoff);*/
+ *bitoff) + 1;
+ } else if (*bitoff == localstart) {
+ /*LOG_TRACE_ARGS("*bitoff == localstart (%u)\n",
+ *bitoff);*/
/* cool, we have another zero! */
count++;
localstart++;
globaloff++;
+ if (count > largest_size) {
+ largest_size = count;
+ largest_start = globaloff - count;
+ }
} else {
- /*LOG_TRACE_ARGS("bitoff (%u) != localstart (%u)\n",
- bitoff, localstart);*/
+ /*LOG_TRACE_ARGS("*bitoff (%u) != localstart (%u)\n",
+ *bitoff, localstart);*/
/* we had to skip over some ones */
count = 1;
globaloff =
ocfs_bitmap_off_for_block(osb->sb, c,
- bitoff) + 1;
- localstart = bitoff + 1;
+ *bitoff) + 1;
+ localstart = *bitoff + 1;
}
if (count == numBits) {
@@ -274,13 +294,19 @@
}
}
- if (count == numBits)
- bitoff = globaloff - count;
- else
- bitoff = -1;
+ if (count == numBits) {
+ *bitoff = globaloff - count;
+ if (best_fit_bits)
+ *best_fit_bits = numBits;
+ } else if (best_fit_bits && largest_size) {
+#warning "can we go off the end of the bitmap here?"
+ *best_fit_bits = largest_size;
+ *bitoff = largest_start;
+ } else
+ status = -ENOSPC;
- LOG_EXIT_ULONG ((unsigned long)bitoff);
- return bitoff;
+ LOG_EXIT_STATUS(status);
+ return(status);
} /* ocfs_find_clear_bits */
/*
Modified: branches/dlm-changes/src/bitmap.h
===================================================================
--- branches/dlm-changes/src/bitmap.h 2004-09-24 23:16:03 UTC (rev 1485)
+++ branches/dlm-changes/src/bitmap.h 2004-09-24 23:18:19 UTC (rev 1486)
@@ -33,8 +33,9 @@
void ocfs_clear_bits(struct super_block *sb,
ocfs_journal_handle *handle, ocfs_alloc_bm *bitmap,
__u32 start, __u32 num);
-int ocfs_find_clear_bits(ocfs_super *osb, ocfs_alloc_bm *bitmap,
- __u32 numBits, __u32 offset, __u32 sysonly);
+int ocfs_find_clear_bits(ocfs_super *osb, ocfs_alloc_bm * bitmap,
+ u32 numBits, u32 offset, u32 *bitoff,
+ u32 *best_fit_bits);
void ocfs_initialize_bitmap(struct super_block *sb,
ocfs_alloc_bm *bitmap, __u32 validbits,
__u32 allocbits);
More information about the Ocfs2-commits
mailing list