undo.patch

joelkp, 03/22/2009 08:17 PM

Download (3.45 KB)

View differences:

undo/undo.c 2009-03-22 18:33:21 +0000
70 70

  
71 71
#define UNDO_FLAG_MULT		0x0001
72 72
#define UNDO_FLAG_INOCHG	0x0002
73
#define UNDO_FLAG_SETTID1	0x0004
74
#define UNDO_FLAG_SETTID2	0x0008
73 75

  
74 76
static int undo_hist_entry_compare(struct undo_hist_entry *he1,
75 77
		    struct undo_hist_entry *he2);
......
108 110
	enum undo_type type;
109 111
	struct hammer_ioc_hist_entry ts1;
110 112
	struct hammer_ioc_hist_entry ts2;
111
	int c;
113
	int c, i;
112 114
	int flags;
113 115

  
114 116
	bzero(&ts1, sizeof(ts1));
......
116 118

  
117 119
	cmd = CMD_DUMP;
118 120
	type = TYPE_FILE;
121
	flags = 0;
119 122

  
120
	while ((c = getopt(ac, av, "adDiuvo:t:")) != -1) {
123
	i = -1;
124
	while ((c = getopt(ac, av, "adDiuvo:t:0123456789")) != -1) {
125
		if (c >= '0' && c <= '9') {
126
			c -= '0';
127
			i = (i >= 0) ? i*10 + c : c;
128
			continue;
129
		} else if (i >= 0) INDEX_ARG: {
130
			/* set placeholder IDs for later lookup */
131
			if (ts1.tid == 0 && !(flags & UNDO_FLAG_SETTID1))
132
				ts1.tid = i, flags |= UNDO_FLAG_SETTID1;
133
			else if (ts2.tid == 0 && !(flags & UNDO_FLAG_SETTID2))
134
				ts2.tid = i, flags |= UNDO_FLAG_SETTID2;
135
			else
136
				usage();
137
			i = -1;
138
			if (c == -1)
139
				/* got here after loop */
140
				break;
141
		}
121 142
		switch(c) {
122 143
		case 'd':
123 144
			if (type != TYPE_FILE)
......
148 169
			outFileName = optarg;
149 170
			break;
150 171
		case 't':
151
			if (ts1.tid && ts2.tid)
152
				usage();
153
			else if (ts1.tid == 0)
172
			if (ts1.tid == 0 && !(flags & UNDO_FLAG_SETTID1))
154 173
				ts1.tid = parse_delta_time(optarg);
155
			else
174
			else if (ts2.tid == 0 && !(flags & UNDO_FLAG_SETTID2))
156 175
				ts2.tid = parse_delta_time(optarg);
176
			else
177
				usage();
157 178
			break;
158 179
		default:
159 180
			usage();
......
161 182
			break;
162 183
		}
163 184
	}
185
	if (i >= 0)
186
		/* last argument numerical index */
187
		goto INDEX_ARG;
164 188

  
165 189
	/*
166 190
	 * Option validation
......
172 196

  
173 197
	ac -= optind;
174 198
	av += optind;
175
	flags = 0;
176 199
	if (ac > 1)
177 200
		flags |= UNDO_FLAG_MULT;
178 201

  
......
215 238

  
216 239
/*
217 240
 * Iterate through a file's history.  If cmd == CMD_DUMP we take the
218
 * next-to-last transaction id.  Otherwise if cmd == CMD_ITERATEALL
219
 * we scan all transaction ids.
241
 * next-to-last transaction id unless another given.  Otherwise if
242
 * cmd == CMD_ITERATEALL we scan all transaction ids.
220 243
 *
221 244
 * Also iterate through the directory's history to locate other inodes that
222 245
 * used the particular file name.
......
258 281
		}
259 282
	}
260 283
	if (cmd == CMD_DUMP) {
261
		/*
262
		 * Single entry, most recent prior to current
263
		 */
264
		if (ts1.tid == 0 && RB_EMPTY(&tse_tree)) {
284
		if ((ts1.tid == 0 ||
285
		     flags & (UNDO_FLAG_SETTID1|UNDO_FLAG_SETTID2)) &&
286
		    RB_EMPTY(&tse_tree)) {
265 287
			if ((fd = open(filename, O_RDONLY)) > 0) {
266 288
				collect_history(fd, &error, &tse_tree);
267 289
				close(fd);
268 290
			}
269 291
		}
292
		/*
293
		 * Find entry if tid set to placeholder index 
294
		 */
295
		if (flags & UNDO_FLAG_SETTID1){
296
			tse1 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
297
			while (tse1 && ts1.tid--)
298
				tse1 = RB_PREV(undo_hist_entry_rb_tree,
299
					       &tse_tree, tse1);
300
			if (tse1)
301
				ts1 = tse1->tse;
302
			else
303
				ts1.tid = 0;
304
		}
305
		if (flags & UNDO_FLAG_SETTID2){
306
			tse2 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
307
			while (tse2 && ts2.tid--)
308
				tse2 = RB_PREV(undo_hist_entry_rb_tree,
309
					       &tse_tree, tse2);
310
			if (tse2)
311
				ts2 = tse2->tse;
312
			else
313
				ts2.tid = 0;
314
		}
315
		/*
316
		 * Single entry, most recent prior to current
317
		 */
270 318
		if (ts1.tid == 0) {
271 319
			tse2 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
272 320
			if (tse2) {