/* * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ #ifdef HAVE_CONFIG_H # include #endif #include "reiserfs/libreiserfs.h" static int comp_ids (const void * p1, const void * p2) { __u32 id1 = le32_to_cpu(*(__u32 *)p1) ; __u32 id2 = le32_to_cpu(*(__u32 *)p2) ; if (id1 < id2) return -1; if (id1 > id2) return 1 ; return 0 ; } /* functions to manipulate with super block's objectid map */ int reiserfs_objmap_test (reiserfs_filsys_t * fs, __u32 objectid) { __u32 * objectid_map; __u32 count = reiserfs_sb_get_mapcur(fs->fs_ondisk_sb); int ret; int pos; objectid_map = (__u32 *)((char *)fs->fs_ondisk_sb + reiserfs_super_size (fs->fs_ondisk_sb)); ret = misc_bin_search(&objectid, objectid_map, count, sizeof(__u32), &pos, comp_ids); /* if the position returned is odd, the oid is in use */ if (ret == 0) return ((__u32)pos & 1); /* if the position returned is even, the oid is in use */ return !((__u32)pos & 1) ; } void reiserfs_objmap_set (reiserfs_filsys_t * fs, __u32 objectid) { int i; __u32 * objectid_map; int cursize; if (reiserfs_objmap_test (fs, objectid)) { return; } objectid_map = (__u32 *)((char *)fs->fs_ondisk_sb + reiserfs_super_size (fs->fs_ondisk_sb)); cursize = reiserfs_sb_get_mapcur (fs->fs_ondisk_sb); for (i = 0; i < cursize; i += 2) { if (objectid >= le32_to_cpu (objectid_map [i]) && objectid < le32_to_cpu (objectid_map [i + 1])) /* it is used */ return; if (objectid + 1 == le32_to_cpu (objectid_map[i])) { /* size of objectid map does not change */ objectid_map[i] = cpu_to_le32 (objectid); return; } if (objectid == le32_to_cpu (objectid_map[i + 1])) { /* size of objectid map is decreased */ objectid_map [i + 1] = cpu_to_le32 (le32_to_cpu (objectid_map [i + 1]) + 1); if (i + 2 < cursize) { if (objectid_map[i + 1] == objectid_map[i + 2]) { memmove (objectid_map + i + 1, objectid_map + i + 1 + 2, (cursize - (i + 2 + 2 - 1)) * sizeof (__u32)); reiserfs_sb_set_mapcur (fs->fs_ondisk_sb, cursize - 2); } } return; } if (objectid < le32_to_cpu (objectid_map[i])) { /* size of objectid map must be increased */ if (cursize == reiserfs_sb_get_mapmax (fs->fs_ondisk_sb)) { /* here all objectids between objectid and objectid_map[i] get used */ objectid_map[i] = cpu_to_le32 (objectid); return; } else { memmove (objectid_map + i + 2, objectid_map + i, (cursize - i) * sizeof (__u32)); reiserfs_sb_set_mapcur (fs->fs_ondisk_sb, cursize + 2); } objectid_map[i] = cpu_to_le32 (objectid); objectid_map[i+1] = cpu_to_le32 (objectid + 1); return; } } /* append to current objectid map, if we have space */ if (i < reiserfs_sb_get_mapmax (fs->fs_ondisk_sb)) { objectid_map[i] = cpu_to_le32 (objectid); objectid_map[i + 1] = cpu_to_le32 (objectid + 1); reiserfs_sb_set_mapcur (fs->fs_ondisk_sb, cursize + 2); } else if (i == reiserfs_sb_get_mapmax (fs->fs_ondisk_sb)) { objectid_map[i - 1] = cpu_to_le32 (objectid + 1); } else misc_die ("mark_objectid_as_used: objectid map corrupted"); return; } void reiserfs_objmap_print (FILE * fp, reiserfs_filsys_t * fs) { int i; reiserfs_sb_t * sb; __u32 * omap; sb = fs->fs_ondisk_sb; if (fs->fs_format == REISERFS_FORMAT_3_6) omap = (__u32 *)(sb + 1); else if (fs->fs_format == REISERFS_FORMAT_3_5) omap = (__u32 *)((reiserfs_sb_v1_t *)sb + 1); else { reiserfs_warning (fp, "reiserfs_objmap_print: proper " "signature is not found\n"); return; } reiserfs_warning (fp, "Map of objectids (super block size %d)\n", (char *)omap - (char *)sb); for (i = 0; i < reiserfs_sb_get_mapcur (sb); i ++) { if (i % 2 == 0) { reiserfs_warning(fp, "busy(%u-%u) ", le32_to_cpu (omap[i]), le32_to_cpu (omap[i+1]) - 1); } else { reiserfs_warning(fp, "free(%u-%u) ", le32_to_cpu (omap[i]), ((i+1) == reiserfs_sb_get_mapcur (sb)) ? ~(__u32)0 : (le32_to_cpu (omap[i+1]) - 1)); } } reiserfs_warning (fp, "\nObject id array has size %d (max %d):", reiserfs_sb_get_mapcur (sb), reiserfs_sb_get_mapmax (sb)); for (i = 0; i < reiserfs_sb_get_mapcur (sb); i ++) reiserfs_warning (fp, "%s%u ", i % 2 ? "" : "*", le32_to_cpu (omap[i])); reiserfs_warning (fp, "\n"); }