[Ocfs2-devel] [PATCH 1/5] ocfs2: modifiy reservation code to support discontiguous allocations
Srinivas Eeda
srinivas.eeda at oracle.com
Tue Sep 18 17:10:59 PDT 2012
Currently reservation code assumes that bitmap given to it is one contigous
chunk. This patch enhances it to handle a discontigous chunks. It adds new
fields m_bitmap_ext_cnt and m_bitmap_ext_arr. m_bitmap_ext_arr tracks the sizes
of each contigous chunk and m_bitmap_ext_cnt trackes size of m_bitmap_ext_arr
Callers should pass number of discontiguous chunks during ocfs2_resmap_restart
and later call ocfs2_resmap_set_extent_size for every chunk.
Signed-off-by: Srinivas Eeda <srinivas.eeda at oracle.com>
---
fs/ocfs2/localalloc.c | 4 +++-
fs/ocfs2/reservations.c | 39 ++++++++++++++++++++++++++++++++++-----
fs/ocfs2/reservations.h | 7 ++++++-
3 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index a9f78c7..53a162f 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -1191,9 +1191,11 @@ retry_enospc:
memset(OCFS2_LOCAL_ALLOC(alloc)->la_bitmap, 0,
le16_to_cpu(la->la_size));
- ocfs2_resmap_restart(&osb->osb_la_resmap, cluster_count,
+ ocfs2_resmap_restart(&osb->osb_la_resmap, 1, cluster_count,
OCFS2_LOCAL_ALLOC(alloc)->la_bitmap);
+ ocfs2_resmap_set_extent_size(&osb->osb_la_resmap, 0, cluster_count);
+
trace_ocfs2_local_alloc_new_window_result(
OCFS2_LOCAL_ALLOC(alloc)->la_bm_off,
le32_to_cpu(alloc->id1.bitmap1.i_total));
diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c
index 41ffd36..e1034ed 100644
--- a/fs/ocfs2/reservations.c
+++ b/fs/ocfs2/reservations.c
@@ -291,7 +291,7 @@ static void ocfs2_resmap_clear_all_resv(struct ocfs2_reservation_map *resmap)
}
}
-void ocfs2_resmap_restart(struct ocfs2_reservation_map *resmap,
+void ocfs2_resmap_restart(struct ocfs2_reservation_map *resmap, u32 ext_cnt,
unsigned int clen, char *disk_bitmap)
{
if (ocfs2_resmap_disabled(resmap))
@@ -300,12 +300,32 @@ void ocfs2_resmap_restart(struct ocfs2_reservation_map *resmap,
spin_lock(&resv_lock);
ocfs2_resmap_clear_all_resv(resmap);
+
+ /* free existing extent array */
+ kfree(resmap->m_bitmap_ext_arr);
+
resmap->m_bitmap_len = clen;
resmap->m_disk_bitmap = disk_bitmap;
+ resmap->m_bitmap_ext_cnt = ext_cnt;
+ resmap->m_bitmap_ext_arr = kmalloc((sizeof(u32) * ext_cnt), GFP_NOFS);
+ if (!resmap->m_bitmap_ext_arr) {
+ mlog_errno(-ENOMEM);
+ resmap->m_osb->osb_resv_level = 0; /* disable reservations */
+ }
+
spin_unlock(&resv_lock);
}
+void ocfs2_resmap_set_extent_size(struct ocfs2_reservation_map *resmap,
+ int indx, u32 sz)
+{
+ if (ocfs2_resmap_disabled(resmap))
+ return;
+
+ resmap->m_bitmap_ext_arr[indx] = sz;
+}
+
void ocfs2_resmap_uninit(struct ocfs2_reservation_map *resmap)
{
/* Does nothing for now. Keep this around for API symmetry */
@@ -419,21 +439,30 @@ static int ocfs2_resmap_find_free_bits(struct ocfs2_reservation_map *resmap,
unsigned int *rlen)
{
void *bitmap = resmap->m_disk_bitmap;
- unsigned int best_start, best_len = 0;
+ unsigned int best_start, len, ext, best_len = 0;
int offset, start, found;
trace_ocfs2_resmap_find_free_bits_begin(search_start, search_len,
wanted, resmap->m_bitmap_len);
- found = best_start = best_len = 0;
-
+ found = best_start = best_len = ext = 0;
start = search_start;
+ len = resmap->m_bitmap_ext_arr[ext++];
+
while ((offset = ocfs2_find_next_zero_bit(bitmap, resmap->m_bitmap_len,
- start)) != -1) {
+ start)) != -1) {
/* Search reached end of the region */
if (offset >= (search_start + search_len))
break;
+ if (offset >= len) {
+ if (ext >= resmap->m_bitmap_ext_cnt)
+ break;
+ len += resmap->m_bitmap_ext_arr[ext++];
+ found = 1;
+ start = offset + 1;
+ }
+
if (offset == start) {
/* we found a zero */
found++;
diff --git a/fs/ocfs2/reservations.h b/fs/ocfs2/reservations.h
index 42c2b80..fed3aae 100644
--- a/fs/ocfs2/reservations.h
+++ b/fs/ocfs2/reservations.h
@@ -56,6 +56,8 @@ struct ocfs2_reservation_map {
u32 m_bitmap_len; /* Number of valid
* bits available */
+ u32 m_bitmap_ext_cnt;
+ u32 *m_bitmap_ext_arr;
struct list_head m_lru; /* LRU of reservations
* structures. */
@@ -94,6 +96,9 @@ void ocfs2_resv_discard(struct ocfs2_reservation_map *resmap,
int ocfs2_resmap_init(struct ocfs2_super *osb,
struct ocfs2_reservation_map *resmap);
+void ocfs2_resmap_set_extent_size(struct ocfs2_reservation_map *resmap,
+ int indx, u32 sz);
+
/**
* ocfs2_resmap_restart() - "restart" a reservation bitmap
* @resmap: reservations bitmap
@@ -107,7 +112,7 @@ int ocfs2_resmap_init(struct ocfs2_super *osb,
* reservations. A future version will recalculate existing
* reservations based on the new bitmap.
*/
-void ocfs2_resmap_restart(struct ocfs2_reservation_map *resmap,
+void ocfs2_resmap_restart(struct ocfs2_reservation_map *resmap, u32 ext_cnt,
unsigned int clen, char *disk_bitmap);
/**
--
1.5.4.3
More information about the Ocfs2-devel
mailing list