File: journal.c

package info (click to toggle)
reiser4progs 1.0.9-2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 5,608 kB
  • ctags: 3,844
  • sloc: ansic: 33,541; sh: 10,679; makefile: 1,010
file content (168 lines) | stat: -rw-r--r-- 4,509 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* Copyright 2001-2005 by Hans Reiser, licensing governed by 
   reiser4progs/COPYING.
   
   librepair/journal.c - methods are needed for the work with broken reiser4
   journals. */

#include <repair/librepair.h>
#include <fcntl.h>

/* Callback for journal check method - check if a block, pointed from the 
   journal, is of the special filesystem areas - skipped, block allocator,
   oid alocator, etc. */

static errno_t cb_journal_check(void *object, region_func_t func, void *data) {
	reiser4_fs_t *fs = (reiser4_fs_t *)object;
	
	aal_assert("vpf-737", fs != NULL);
	return reiser4_fs_layout(fs, func, data);
}

/* Checks the opened journal. */
static errno_t repair_journal_check_struct(reiser4_journal_t *journal) {
	aal_assert("vpf-460", journal != NULL);
	aal_assert("vpf-736", journal->fs != NULL);
	
	return reiser4call(journal, check_struct, 
			   cb_journal_check, journal->fs);
}

/* Open the journal and check it. */
errno_t repair_journal_open(reiser4_fs_t *fs, 
			    aal_device_t *journal_device,
			    uint8_t mode, uint32_t options)
{
	reiser4_plug_t *plug;
	errno_t res = 0;
	rid_t pid;
	
	aal_assert("vpf-445", fs != NULL);
	aal_assert("vpf-446", fs->format != NULL);
	aal_assert("vpf-476", journal_device != NULL);
	
	/* Try to open the journal. */
	if ((fs->journal = reiser4_journal_open(fs, journal_device)) == NULL) {
		/* failed to open a journal. Build a new one. */
		aal_error("Failed to open a journal by its id (0x%x).",
			  reiser4_format_journal_pid(fs->format));
		
		if (mode != RM_BUILD)
			return RE_FATAL;
		
		if ((pid = reiser4_format_journal_pid(fs->format)) == INVAL_PID) {
			aal_error("Invalid journal plugin id has been found.");
			return -EINVAL;
		}
		
		if (!(plug = reiser4_factory_ifind(JOURNAL_PLUG_TYPE, pid)))  {
			aal_error("Cannot find journal plugin by its id 0x%x.",
				  pid);
			return -EINVAL;
		}
		
		if (!(options & (1 << REPAIR_YES))) {
			if (aal_yesno("Do you want to create a new journal "
				      "(%s)?", plug->label) == EXCEPTION_OPT_NO)
			{
				return -EINVAL;
			}
		}
	    
		if (!(fs->journal = reiser4_journal_create(fs, journal_device))) {
			aal_error("Cannot create a journal by its id (0x%x).",
				  reiser4_format_journal_pid(fs->format));
			return -EINVAL;
		}
	} else {    
		/* Check the structure of the opened journal or rebuild it if needed. */
		if ((res = repair_journal_check_struct(fs->journal)))
			goto error_journal_close;
	}
	
	return 0;
	
 error_journal_close:
	reiser4_journal_close(fs->journal);
	fs->journal = NULL;
	
	return res;
}

void repair_journal_invalidate(reiser4_journal_t *journal) {
	aal_assert("vpf-1555", journal != NULL);

	reiser4call(journal, invalidate);
}

void repair_journal_print(reiser4_journal_t *journal, aal_stream_t *stream) {
	aal_assert("umka-1564", journal != NULL);

	reiser4call(journal, print, stream, 0);
}

errno_t repair_journal_pack(reiser4_journal_t *journal, aal_stream_t *stream) {
	rid_t pid;
	
	aal_assert("vpf-1747", journal != NULL);
	aal_assert("vpf-1748", stream != NULL);

	pid = journal->ent->plug->p.id.id;
	aal_stream_write(stream, &pid, sizeof(pid));
	
	return reiser4call(journal, pack, stream);
}

reiser4_journal_t *repair_journal_unpack(reiser4_fs_t *fs, 
					 aal_stream_t *stream) 
{
	reiser4_journal_t *journal;
	reiser4_plug_t *plug;
	uint32_t blksize;
	count_t blocks;
	uint32_t read;
	blk_t start;
	rid_t pid;
	
	aal_assert("vpf-1753", fs != NULL);
	aal_assert("vpf-1754", stream != NULL);

	read = aal_stream_read(stream, &pid, sizeof(pid));
	if (read != sizeof(pid)) {
		aal_error("Can't unpack the journal. Stream is over?");
		return NULL;
	}
	
	/* Getting needed plugin from plugin factory by its id */
	if (!(plug = reiser4_factory_ifind(JOURNAL_PLUG_TYPE, pid))) {
		aal_error("Can't find journal plugin "
			  "by its id 0x%x.", pid);
		return NULL;
	}

	/* Allocating memory and finding plugin */
	if (!(journal = aal_calloc(sizeof(*journal), 0)))
		return NULL;

	journal->fs = fs;
	journal->device = fs->device;
	
	start = reiser4_format_start(fs->format);
	blocks = reiser4_format_get_len(fs->format);
	blksize = reiser4_master_get_blksize(fs->master);

	/* Creating journal entity. */
	if (!(journal->ent = plugcall((reiser4_journal_plug_t *)plug, unpack,
				      fs->device, blksize, fs->format->ent,
				      fs->oid->ent, start, blocks, stream)))
	{
		aal_error("Can't unpack journal %s on %s.",
			  plug->label, fs->device->name);
		goto error;
	}

	return journal;
	
 error:
	aal_free(journal);
	return NULL;
}