📄 uobjectid.c
字号:
/* * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */#include "fsck.h"/* when --check fsck builds a map of objectids of files it finds in the tree when --rebuild-tree - fsck builds map of objectids it inserts into tree */#define ALLOC_SIZE 1024#define MAX_ID (~(__u32)0)/* 2 bytes for the counter */#define BM_SIZE (ALLOC_SIZE - sizeof(__u16))#define BM_INTERVAL (BM_SIZE * 8)#define INDEX_COUNT (MAX_ID / BM_INTERVAL)#define id_map_interval(map, id) (map->index + (id / BM_INTERVAL))#define id_map_local_count(interval) (interval + BM_SIZE)/*typedef struct sb_id_map { __u32 * m_begin; __u32 m_size, m_used_slot_count;} sb_id_map_t;*/id_map_t *id_map_init() { id_map_t *map; __u32 i; map = getmem(sizeof(id_map_t)); map->index = mem_alloc(INDEX_COUNT * sizeof(void *)); for (i = 0; i < INDEX_COUNT; i++) { if (map->index[i] != (void *)0) map->index[i] = (void *)0; } id_map_mark(map, 0); id_map_mark(map, 1); /* id == 0 should not be there, just for convinient usage */ map->count--; return map;}void id_map_free(id_map_t *map) { __u32 i; for (i = 0; i < INDEX_COUNT; i++) { if (map->index[i] != (void *)0 && map->index[i] != (void *)1) freemem(map->index[i]); } freemem(map->index); freemem(map);}int id_map_test(id_map_t *map, __u32 id) { void **interval = id_map_interval(map, id); if (*interval == (void *)0) return 0; if (*interval == (void *)1) return 1; return misc_test_bit(id % BM_INTERVAL, *interval);}int id_map_mark(id_map_t *map, __u32 id) { void **interval = id_map_interval(map, id); if (*interval == (void *)0) *interval = getmem(ALLOC_SIZE); if (*interval == (void *)1) return 1; if (misc_test_bit(id % BM_INTERVAL, *interval)) return 1; misc_set_bit(id % BM_INTERVAL, *interval); (*(__u16 *)id_map_local_count(*interval))++; map->count++; if ((*(__u16 *)id_map_local_count(*interval)) == BM_INTERVAL) { /* Dealloc fully used bitmap */ freemem(*interval); *interval = (void *)1; } if (map->last_used < (id / BM_INTERVAL)) map->last_used = id / BM_INTERVAL; return 0;}/* call this for proper_id_map only!! */__u32 id_map_alloc(id_map_t *map) { __u32 i, zero_count; __u32 id = 0, first = ~(__u32)0; for (i = 0, zero_count = 0; zero_count < 10 && i < INDEX_COUNT - 1; i++) { if (map->index[i] == (void *)0) { if (zero_count == 0) first = i; zero_count++; } else if (map->index[i] != (void *)1) break; } if (map->index[i] != (void *)1 && map->index[i] != (void *)0) { id = misc_find_first_zero_bit(map->index[i], BM_INTERVAL); if (id >= BM_INTERVAL) die ("Id is out of interval size, interval looks corrupted."); id += i * BM_INTERVAL; } else if (first != ~(__u32)0) { id = first * BM_INTERVAL; if (id == 0) id = 2; } else die ("%s: No more free objectid is available.", __FUNCTION__); id_map_mark(map, id); return id;}/* this could be used if some more sofisticated flushing will be needed. *//*static void sb_id_map_pack(sb_id_map_t *map) { map->m_begin[1] = map->m_begin[map->m_used_slot_count - 1]; memset(map->m_begin + 2, 0, map->m_used_slot_count - 2); map->m_used_slot_count = 2;}*/static __u32 id_map_next_bound(id_map_t *map, __u32 start) { __u32 index = start / BM_INTERVAL; __u32 offset = start % BM_INTERVAL; int look_for; if (map->index[index] == (void *)0) look_for = 1; else if (map->index[index] == (void *)1) look_for = 0; else look_for = !misc_test_bit(offset, map->index[index]); offset++;start_again: if (look_for) { while (index < INDEX_COUNT && map->index[index] == (void *)0) index++; if (index == INDEX_COUNT) return 0; if (map->index[index] == (void *)1) return index * BM_INTERVAL; offset = misc_find_next_set_bit(map->index[index], BM_INTERVAL, offset); if (offset >= BM_INTERVAL) { offset = 0; index++; goto start_again; } return index * BM_INTERVAL + offset; } else { while (index < INDEX_COUNT && map->index[index] == (void *)1) index++; if (index == INDEX_COUNT) return 0; if (map->index[index] == (void *)0) return index * BM_INTERVAL; offset = misc_find_next_zero_bit(map->index[index], BM_INTERVAL, offset); if (offset >= BM_INTERVAL) { offset = 0; index++; goto start_again; } return index * BM_INTERVAL + offset; }}void id_map_flush(struct id_map * map, reiserfs_filsys_t * fs) { int size, max, i; __u32 id, prev_id; __u32 * sb_objectid_map; size = reiserfs_super_block_size (fs->fs_ondisk_sb); sb_objectid_map = (__u32 *)((char *)(fs->fs_ondisk_sb) + size); max = ((fs->fs_blocksize - size) >> 3 << 1); set_sb_oid_maxsize (fs->fs_ondisk_sb, max); id = 1; sb_objectid_map[0] = cpu_to_le32(1); for (i = 1; i < max - 1; i++) { id = id_map_next_bound(map, id); sb_objectid_map[i] = cpu_to_le32(id); if (id == 0) { if (i % 2) die ("%s: Used interval is not closed on flushing.", __FUNCTION__); break; } } if (map->index[map->last_used] == (void *)0) die ("Object id map looks corrupted - last used interval cannot be zeroed."); i++; if (i == max) { if (id == 0) die ("Objectid interval does not contain any set bit what is expected."); if (map->index[map->last_used] == (void *)1) { prev_id = BM_INTERVAL - 1; } else { prev_id = ~(__u32)0; if (id < map->last_used * BM_INTERVAL) id = 0; else id %= BM_INTERVAL; if (misc_test_bit(id, map->index[map->last_used])) prev_id = id; while ((id = misc_find_next_set_bit(map->index[map->last_used], BM_INTERVAL, (id + 1))) != BM_INTERVAL) { prev_id = id; } if (prev_id == ~(__u32)0) die ("Objectid interval does not contain any set bit what is expected."); prev_id++; } sb_objectid_map[max - 1] = cpu_to_le32(prev_id + map->last_used * BM_INTERVAL); } else { i--; memset(sb_objectid_map + i, 0, (max - i) * sizeof (__u32)); } set_sb_oid_cursize (fs->fs_ondisk_sb, i);}/* FIXME: these 3 methods must be implemented also.void fetch_objectid_map (struct id_map * map, reiserfs_filsys_t * fs){ int sb_size; __u32 * sb_objectid_map; sb_size = reiserfs_super_block_size (fs->fs_ondisk_sb); sb_objectid_map = (__u32 *)((char *)(fs->fs_ondisk_sb) + sb_size); if (map->m_page_count != 1) die ("fetch_objectid_map: can not fetch long map"); make_id_space(map, 0); memcpy (map->m_begin, sb_objectid_map, get_sb_oid_cursize (fs->fs_ondisk_sb) * sizeof (__u32)); map->m_used_slot_count = get_sb_oid_cursize (fs->fs_ondisk_sb);}#define OBJMAP_START_MAGIC 375331#define OBJMAP_END_MAGIC 7700472void reiserfs_objectid_map_save (FILE * fp, struct id_map * id_map){ __u32 v; int i; v = OBJMAP_START_MAGIC; fwrite (&v, 4, 1, fp); v = id_map->m_used_slot_count; fwrite (&v, 4, 1, fp); for (i = 0; i < id_map->m_page_count - 1; i++) { fwrite ((char *)id_map->m_begin + MAP_SIZE * i, 4, 1, fp); } for (i = 0; i < id_map->m_used_slot_count * sizeof(__u32) - (id_map->m_page_count - 1) * MAP_SIZE; i++) { fwrite ((char *)id_map->m_begin + MAP_SIZE * (id_map->m_page_count - 1) + i, 4, 1, fp); } v = OBJMAP_END_MAGIC; fwrite (&v, 4, 1, fp);}struct id_map * reiserfs_objectid_map_load (FILE * fp){ __u32 v; int i; struct id_map * id_map; fread (&v, 4, 1, fp); if (v != OBJMAP_START_MAGIC) { reiserfs_warning (stderr, "reiserfs_objectid_map_load: no objectid map begin magic found"); return 0; } // read bit size of objectid map fread (&v, 4, 1, fp); id_map = init_id_map (MAP_NOT_PACKED); id_map->m_used_slot_count = v; id_map->m_page_count = v / MAP_SIZE + 1; id_map->m_begin = expandmem (id_map->m_begin, 0, id_map->m_page_count * MAP_SIZE); for (i = 0; i < id_map->m_page_count - 1; i++) { fread ((char *)id_map->m_begin + MAP_SIZE * i, 4, 1, fp); } for (i = 0; i < id_map->m_used_slot_count * sizeof(__u32) - (id_map->m_page_count - 1) * MAP_SIZE; i++) { fread ((char *)id_map->m_begin + MAP_SIZE * (id_map->m_page_count - 1) + i, 4, 1, fp); } fread (&v, 4, 1, fp); if (v != OBJMAP_END_MAGIC) { reiserfs_warning (stderr, "reiserfs_objectid_map_load: no objectid map end magic found"); return 0; } fflush (stderr); return id_map;}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -