undo.patch

joelkp, 03/23/2009 01:28 AM

Download (3.6 KB)

View differences:

undo/undo.c 2009-03-23 00:59:58 +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, oi;
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
	oi = optind;
125
	while ((c = getopt(ac, av, "adDiuvo:t:0123456789")) != -1) {
126
		if (c >= '0' && c <= '9') {
127
			c -= '0';
128
			i = (i >= 0) ? i*10 + c : c;
129
			if (oi != optind) {
130
				c = 0;
131
				goto INDEX_ARG;
132
			}
133
			continue;
134
		} else if (i >= 0) INDEX_ARG: {
135
			/* set placeholder IDs for later lookup */
136
			if (ts1.tid == 0 && !(flags & UNDO_FLAG_SETTID1))
137
				ts1.tid = i, flags |= UNDO_FLAG_SETTID1;
138
			else if (ts2.tid == 0 && !(flags & UNDO_FLAG_SETTID2))
139
				ts2.tid = i, flags |= UNDO_FLAG_SETTID2;
140
			else
141
				usage();
142
			i = -1;
143
			oi = optind;
144
			if (c == 0)
145
				continue;
146
			if (c == -1)
147
				/* got here after loop */
148
				break;
149
		} else
150
			oi = optind;
121 151
		switch(c) {
122 152
		case 'd':
123 153
			if (type != TYPE_FILE)
......
148 178
			outFileName = optarg;
149 179
			break;
150 180
		case 't':
151
			if (ts1.tid && ts2.tid)
152
				usage();
153
			else if (ts1.tid == 0)
181
			if (ts1.tid == 0 && !(flags & UNDO_FLAG_SETTID1))
154 182
				ts1.tid = parse_delta_time(optarg);
155
			else
183
			else if (ts2.tid == 0 && !(flags & UNDO_FLAG_SETTID2))
156 184
				ts2.tid = parse_delta_time(optarg);
185
			else
186
				usage();
157 187
			break;
158 188
		default:
159 189
			usage();
......
161 191
			break;
162 192
		}
163 193
	}
194
	if (i >= 0)
195
		/* last argument numerical index */
196
		goto INDEX_ARG;
164 197

  
165 198
	/*
166 199
	 * Option validation
......
172 205

  
173 206
	ac -= optind;
174 207
	av += optind;
175
	flags = 0;
176 208
	if (ac > 1)
177 209
		flags |= UNDO_FLAG_MULT;
178 210

  
......
215 247

  
216 248
/*
217 249
 * 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.
250
 * next-to-last transaction id unless another given.  Otherwise if
251
 * cmd == CMD_ITERATEALL we scan all transaction ids.
220 252
 *
221 253
 * Also iterate through the directory's history to locate other inodes that
222 254
 * used the particular file name.
......
258 290
		}
259 291
	}
260 292
	if (cmd == CMD_DUMP) {
261
		/*
262
		 * Single entry, most recent prior to current
263
		 */
264
		if (ts1.tid == 0 && RB_EMPTY(&tse_tree)) {
293
		if ((ts1.tid == 0 ||
294
		     flags & (UNDO_FLAG_SETTID1|UNDO_FLAG_SETTID2)) &&
295
		    RB_EMPTY(&tse_tree)) {
265 296
			if ((fd = open(filename, O_RDONLY)) > 0) {
266 297
				collect_history(fd, &error, &tse_tree);
267 298
				close(fd);
268 299
			}
269 300
		}
301
		/*
302
		 * Find entry if tid set to placeholder index 
303
		 */
304
		if (flags & UNDO_FLAG_SETTID1){
305
			tse1 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
306
			while (tse1 && ts1.tid--)
307
				tse1 = RB_PREV(undo_hist_entry_rb_tree,
308
					       &tse_tree, tse1);
309
			if (tse1)
310
				ts1 = tse1->tse;
311
			else
312
				ts1.tid = 0;
313
		}
314
		if (flags & UNDO_FLAG_SETTID2){
315
			tse2 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
316
			while (tse2 && ts2.tid--)
317
				tse2 = RB_PREV(undo_hist_entry_rb_tree,
318
					       &tse_tree, tse2);
319
			if (tse2)
320
				ts2 = tse2->tse;
321
			else
322
				ts2.tid = 0;
323
		}
324
		/*
325
		 * Single entry, most recent prior to current
326
		 */
270 327
		if (ts1.tid == 0) {
271 328
			tse2 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
272 329
			if (tse2) {