Initial commit -- seeded with reiserfsprogs 3.x.0j
This commit is contained in:
commit
e7102bdb66
77 files changed
+33513
No files matched your search
+202
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 1998 Hans Reiser
|
||||
*/
|
||||
/*#include <stdio.h>
|
||||
#include <string.h>*/
|
||||
/*#include <asm/bitops.h>
|
||||
#include "../include/reiserfs_fs.h"
|
||||
#include "../include/reiserfs_fs_sb.h"
|
||||
#include "../include/reiserfslib.h"*/
|
||||
#include "fsck.h"
|
||||
|
||||
|
||||
/* there is a situation, when we overwrite contents of unformatted
|
||||
node with direct item. One unformatted node can be overwritten
|
||||
several times by direct items */
|
||||
/*
|
||||
struct overwritten_unfm_segment {
|
||||
int ous_begin;
|
||||
int ous_end;
|
||||
struct overwritten_unfm_segment * ous_next;
|
||||
};
|
||||
*/
|
||||
struct overwritten_unfm {
|
||||
unsigned long ou_unfm_ptr; /* block number of unfm node */
|
||||
unsigned long ou_dir_id;
|
||||
unsigned long ou_objectid; /* key corresponding to an unfm node */
|
||||
unsigned long ou_offset;
|
||||
|
||||
struct overwritten_unfm_segment * ou_segments; /* list of segmens, than have been overwritten in ths unfm node */
|
||||
};
|
||||
|
||||
struct overwritten_unfm ** g_overwritten_unfms;
|
||||
int g_overwritten_unfms_amount; /* number of unformatted nodes, which contain direct items */
|
||||
|
||||
|
||||
/* adds segment to the single linked list of segments sorted by begin
|
||||
field. Retuns pointer to first element of list */
|
||||
static struct overwritten_unfm_segment * add_segment (struct overwritten_unfm_segment * first, int begin, int end)
|
||||
{
|
||||
struct overwritten_unfm_segment * new, * next, * prev;
|
||||
|
||||
new = getmem (sizeof (struct overwritten_unfm_segment));
|
||||
new->ous_begin = begin;
|
||||
new->ous_end = end;
|
||||
new->ous_next = 0;
|
||||
|
||||
next = first;
|
||||
prev = 0;
|
||||
while (next) {
|
||||
if (next->ous_begin > begin)
|
||||
break;
|
||||
prev = next;
|
||||
next = next->ous_next;
|
||||
}
|
||||
|
||||
if (prev == 0) {
|
||||
/* insert into head of list */
|
||||
first = new;
|
||||
} else {
|
||||
prev->ous_next = new;
|
||||
}
|
||||
new->ous_next = next;
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
/* input parameter
|
||||
`list_head` - first element of overlapping segments sorted by left edge
|
||||
`unoverwritten_segment` - returned by previous call of get_unoverwritten_segment or (-2,-2) if called first time
|
||||
*/
|
||||
/* returns
|
||||
1 and segment unoverwritten by elements of list `list_head`
|
||||
0 if there isno such segment
|
||||
*/
|
||||
int get_unoverwritten_segment (struct overwritten_unfm_segment * list_head, struct overwritten_unfm_segment * unoverwritten_segment)
|
||||
{
|
||||
int end;
|
||||
|
||||
/* look for segment, which has begin field greater than end of previous interval */
|
||||
while (list_head->ous_begin <= unoverwritten_segment->ous_end) {
|
||||
list_head = list_head->ous_next;
|
||||
}
|
||||
/* look for the end of the continuous region covered by otrezkami */
|
||||
end = list_head->ous_end;
|
||||
while (list_head->ous_next) {
|
||||
if (list_head->ous_next->ous_begin > end + 1)
|
||||
/* intreval found */
|
||||
break;
|
||||
if (list_head->ous_next->ous_end > end)
|
||||
end = list_head->ous_next->ous_end;
|
||||
list_head = list_head->ous_next;
|
||||
}
|
||||
/* ok, between segment and segment->next we have an interval (segment->next != 0) */
|
||||
if (list_head->ous_next != 0) {
|
||||
unoverwritten_segment->ous_begin = end + 1;
|
||||
unoverwritten_segment->ous_end = list_head->ous_next->ous_begin - 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void print_segments (struct overwritten_unfm_segment * list_head)
|
||||
{
|
||||
struct overwritten_unfm_segment * cur;
|
||||
|
||||
cur = list_head;
|
||||
while (cur) {
|
||||
printf ("%s%d %d%s", cur == list_head ? "(" : "", cur->ous_begin, cur->ous_end, cur->ous_next ? ", " : ")\n");
|
||||
cur = cur->ous_next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* this prepare list of segments to extracting of unoverwritten segments */
|
||||
struct overwritten_unfm_segment * find_overwritten_unfm (unsigned long unfm, int length, struct overwritten_unfm_segment * segment_to_init)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g_overwritten_unfms_amount && g_overwritten_unfms[i] != 0; i ++)
|
||||
if (g_overwritten_unfms[i]->ou_unfm_ptr == unfm) {
|
||||
if (g_overwritten_unfms[i]->ou_segments == 0)
|
||||
die ("find_overwritten_unfm: no segment found");
|
||||
g_overwritten_unfms[i]->ou_segments = add_segment (g_overwritten_unfms[i]->ou_segments, -1, -1);
|
||||
add_segment (g_overwritten_unfms[i]->ou_segments, length, length);
|
||||
segment_to_init->ous_begin = -2;
|
||||
segment_to_init->ous_end = -2;
|
||||
return g_overwritten_unfms[i]->ou_segments;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct overwritten_unfm * look_for_overwritten_unfm (__u32 unfm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g_overwritten_unfms_amount && g_overwritten_unfms[i] != 0; i ++)
|
||||
if (g_overwritten_unfms[i]->ou_unfm_ptr == unfm)
|
||||
return g_overwritten_unfms[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GROW_BY 10
|
||||
struct overwritten_unfm * add_overwritten_unfm (unsigned long unfm, struct item_head * direct_ih)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g_overwritten_unfms_amount && g_overwritten_unfms[i] != 0; i ++) {
|
||||
if (g_overwritten_unfms[i]->ou_unfm_ptr == unfm)
|
||||
return g_overwritten_unfms[i];
|
||||
}
|
||||
|
||||
if (i == g_overwritten_unfms_amount) {
|
||||
g_overwritten_unfms = expandmem (g_overwritten_unfms, sizeof (struct overwritten_unfm *) * i,
|
||||
sizeof (struct overwritten_unfm *) * GROW_BY);
|
||||
g_overwritten_unfms_amount += GROW_BY;
|
||||
}
|
||||
g_overwritten_unfms[i] = getmem (sizeof (struct overwritten_unfm));
|
||||
g_overwritten_unfms[i]->ou_unfm_ptr = unfm;
|
||||
g_overwritten_unfms[i]->ou_dir_id = direct_ih->ih_key.k_dir_id;
|
||||
g_overwritten_unfms[i]->ou_objectid = direct_ih->ih_key.k_objectid;
|
||||
g_overwritten_unfms[i]->ou_offset = get_offset(&direct_ih->ih_key) - (get_offset(&direct_ih->ih_key) - 1) % fs->s_blocksize;
|
||||
return g_overwritten_unfms[i];
|
||||
}
|
||||
|
||||
|
||||
void save_unfm_overwriting (unsigned long unfm, struct item_head * direct_ih)
|
||||
{
|
||||
struct overwritten_unfm * ov_unfm;
|
||||
|
||||
/* add new overwritten unfm or return existing one */
|
||||
ov_unfm = add_overwritten_unfm (unfm, direct_ih);
|
||||
ov_unfm->ou_segments = add_segment (ov_unfm->ou_segments, (get_offset(&direct_ih->ih_key) - 1) % fs->s_blocksize,
|
||||
(get_offset(&direct_ih->ih_key) - 1) % fs->s_blocksize + ih_item_len (direct_ih) - 1);
|
||||
}
|
||||
|
||||
|
||||
void free_overwritten_unfms (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g_overwritten_unfms_amount && g_overwritten_unfms[i]; i ++) {
|
||||
/* free all segments */
|
||||
while (g_overwritten_unfms[i]->ou_segments) {
|
||||
struct overwritten_unfm_segment * tmp;
|
||||
|
||||
tmp = g_overwritten_unfms[i]->ou_segments->ous_next;
|
||||
freemem (g_overwritten_unfms[i]->ou_segments);
|
||||
g_overwritten_unfms[i]->ou_segments = tmp;
|
||||
}
|
||||
/* free struct overwritten_unfm */
|
||||
freemem (g_overwritten_unfms[i]);
|
||||
}
|
||||
|
||||
/* free array of pointers to overwritten unfms */
|
||||
if (g_overwritten_unfms)
|
||||
freemem (g_overwritten_unfms);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user