166 lines
4.5 KiB
C
166 lines
4.5 KiB
C
/*
|
|
* 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");
|
|
|
|
}
|
|
|