undo.patch

joelkp, 03/29/2009 03:40 AM

Download (4.73 KB)

View differences:

undo/undo.c 2009-03-29 03:19:33 +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);
76 78
static void doiterate(const char *filename, const char *outFileName,
77 79
		   const char *outFilePostfix, int flags,
78 80
		   struct hammer_ioc_hist_entry ts1,
81
		   struct hammer_ioc_hist_entry ts2,
79 82
		   enum undo_cmd cmd, enum undo_type type);
80 83
static void dogenerate(const char *filename, const char *outFileName,
81 84
		   const char *outFilePostfix,
......
87 90
static void collect_dir_history(const char *filename, int *error,
88 91
		   struct undo_hist_entry_rb_tree *dir_tree);
89 92
static void clean_tree(struct undo_hist_entry_rb_tree *tree);
90
static hammer_tid_t parse_delta_time(const char *timeStr);
93
static hammer_tid_t parse_delta_time(const char *timeStr, int *flags,
94
		   int ind_flag);
91 95
static void runcmd(int fd, const char *cmd, ...);
92 96
static char *timestamp(hammer_ioc_hist_entry_t hen);
93 97
static void usage(void);
......
108 112
	struct hammer_ioc_hist_entry ts1;
109 113
	struct hammer_ioc_hist_entry ts2;
110 114
	int c;
115
	int count_t;
111 116
	int flags;
112 117

  
113 118
	bzero(&ts1, sizeof(ts1));
......
115 120

  
116 121
	cmd = CMD_DUMP;
117 122
	type = TYPE_FILE;
123
	count_t = 0;
124
	flags = 0;
118 125

  
119 126
	while ((c = getopt(ac, av, "adDiuvo:t:")) != -1) {
120 127
		switch(c) {
......
147 154
			outFileName = optarg;
148 155
			break;
149 156
		case 't':
150
			if (ts1.tid && ts2.tid)
151
				usage();
152
			else if (ts1.tid == 0)
153
				ts1.tid = parse_delta_time(optarg);
157
			++count_t;
158
			if (count_t == 1)
159
				ts1.tid = parse_delta_time(optarg, &flags,
160
				                           UNDO_FLAG_SETTID1);
161
			else if (count_t == 2)
162
				ts2.tid = parse_delta_time(optarg, &flags,
163
				                           UNDO_FLAG_SETTID2);
154 164
			else
155
				ts2.tid = parse_delta_time(optarg);
165
				usage();
156 166
			break;
157 167
		default:
158 168
			usage();
......
171 181

  
172 182
	ac -= optind;
173 183
	av += optind;
174
	flags = 0;
175 184
	if (ac > 1)
176 185
		flags |= UNDO_FLAG_MULT;
177 186

  
......
205 214

  
206 215
	while (ac) {
207 216
		doiterate(*av, outFileName, outFilePostfix,
208
			  flags, ts1, cmd, type);
217
			  flags, ts1, ts2, cmd, type);
209 218
		++av;
210 219
		--ac;
211 220
	}
......
214 223

  
215 224
/*
216 225
 * Iterate through a file's history.  If cmd == CMD_DUMP we take the
217
 * next-to-last transaction id.  Otherwise if cmd == CMD_ITERATEALL
218
 * we scan all transaction ids.
226
 * next-to-last transaction id, unless another given.  Otherwise if
227
 * cmd == CMD_ITERATEALL we scan all transaction ids.
219 228
 *
220 229
 * Also iterate through the directory's history to locate other inodes that
221 230
 * used the particular file name.
......
225 234
doiterate(const char *filename, const char *outFileName,
226 235
	  const char *outFilePostfix, int flags,
227 236
	  struct hammer_ioc_hist_entry ts1,
237
	  struct hammer_ioc_hist_entry ts2,
228 238
	  enum undo_cmd cmd, enum undo_type type)
229 239
{
230 240
	struct undo_hist_entry_rb_tree dir_tree;
231 241
	struct undo_hist_entry_rb_tree tse_tree;
232 242
	struct undo_hist_entry *tse1;
233 243
	struct undo_hist_entry *tse2;
234
	struct hammer_ioc_hist_entry ts2, tid_max;
244
	struct hammer_ioc_hist_entry tid_max;
235 245
	char *path = NULL;
236 246
	int i;
237 247
	int fd;
......
256 266
		}
257 267
	}
258 268
	if (cmd == CMD_DUMP) {
259
		/*
260
		 * Single entry, most recent prior to current
261
		 */
262
		if (ts1.tid == 0 && RB_EMPTY(&tse_tree)) {
269
		if ((ts1.tid == 0 ||
270
		     flags & (UNDO_FLAG_SETTID1|UNDO_FLAG_SETTID2)) &&
271
		    RB_EMPTY(&tse_tree)) {
263 272
			if ((fd = open(filename, O_RDONLY)) > 0) {
264 273
				collect_history(fd, &error, &tse_tree);
265 274
				close(fd);
266 275
			}
267 276
		}
277
		/*
278
		 * Find entry if tid set to placeholder index 
279
		 */
280
		if (flags & UNDO_FLAG_SETTID1){
281
			tse1 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
282
			while (tse1 && ts1.tid--)
283
				tse1 = RB_PREV(undo_hist_entry_rb_tree,
284
					       &tse_tree, tse1);
285
			if (tse1)
286
				ts1 = tse1->tse;
287
			else
288
				ts1.tid = 0;
289
		}
290
		if (flags & UNDO_FLAG_SETTID2){
291
			tse2 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
292
			while (tse2 && ts2.tid--)
293
				tse2 = RB_PREV(undo_hist_entry_rb_tree,
294
					       &tse_tree, tse2);
295
			if (tse2)
296
				ts2 = tse2->tse;
297
			else
298
				ts2.tid = 0;
299
		}
300
		/*
301
		 * Single entry, most recent prior to current
302
		 */
268 303
		if (ts1.tid == 0) {
269 304
			tse2 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
270 305
			if (tse2) {
......
582 617

  
583 618
static
584 619
hammer_tid_t
585
parse_delta_time(const char *timeStr)
620
parse_delta_time(const char *timeStr, int *flags, int ind_flag)
586 621
{
587 622
	hammer_tid_t tid;
588 623

  
589 624
	tid = strtoull(timeStr, NULL, 0);
625
	if (timeStr[0] == '+')
626
		++timeStr;
627
	if (timeStr[0] >= '0' && timeStr[0] <= '9' && timeStr[1] != 'x')
628
		*flags |= ind_flag;
590 629
	return(tid);
591 630
}
592 631