blob: d4e64f2e913fccea8e4d0286c160be052ea90789 [file] [log] [blame]
/*
* Copyright 2000-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#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");
}