Project

General

Profile

Bug #1319 » undo.patch

joelkp, 03/22/2009 08:17 PM

View differences:

undo/undo.c 2009-03-22 18:33:21 +0000
#define UNDO_FLAG_MULT 0x0001
#define UNDO_FLAG_INOCHG 0x0002
#define UNDO_FLAG_SETTID1 0x0004
#define UNDO_FLAG_SETTID2 0x0008
static int undo_hist_entry_compare(struct undo_hist_entry *he1,
struct undo_hist_entry *he2);
......
enum undo_type type;
struct hammer_ioc_hist_entry ts1;
struct hammer_ioc_hist_entry ts2;
int c;
int c, i;
int flags;
bzero(&ts1, sizeof(ts1));
......
cmd = CMD_DUMP;
type = TYPE_FILE;
flags = 0;
while ((c = getopt(ac, av, "adDiuvo:t:")) != -1) {
i = -1;
while ((c = getopt(ac, av, "adDiuvo:t:0123456789")) != -1) {
if (c >= '0' && c <= '9') {
c -= '0';
i = (i >= 0) ? i*10 + c : c;
continue;
} else if (i >= 0) INDEX_ARG: {
/* set placeholder IDs for later lookup */
if (ts1.tid == 0 && !(flags & UNDO_FLAG_SETTID1))
ts1.tid = i, flags |= UNDO_FLAG_SETTID1;
else if (ts2.tid == 0 && !(flags & UNDO_FLAG_SETTID2))
ts2.tid = i, flags |= UNDO_FLAG_SETTID2;
else
usage();
i = -1;
if (c == -1)
/* got here after loop */
break;
}
switch(c) {
case 'd':
if (type != TYPE_FILE)
......
outFileName = optarg;
break;
case 't':
if (ts1.tid && ts2.tid)
usage();
else if (ts1.tid == 0)
if (ts1.tid == 0 && !(flags & UNDO_FLAG_SETTID1))
ts1.tid = parse_delta_time(optarg);
else
else if (ts2.tid == 0 && !(flags & UNDO_FLAG_SETTID2))
ts2.tid = parse_delta_time(optarg);
else
usage();
break;
default:
usage();
......
break;
}
}
if (i >= 0)
/* last argument numerical index */
goto INDEX_ARG;
/*
* Option validation
......
ac -= optind;
av += optind;
flags = 0;
if (ac > 1)
flags |= UNDO_FLAG_MULT;
......
/*
* Iterate through a file's history. If cmd == CMD_DUMP we take the
* next-to-last transaction id. Otherwise if cmd == CMD_ITERATEALL
* we scan all transaction ids.
* next-to-last transaction id unless another given. Otherwise if
* cmd == CMD_ITERATEALL we scan all transaction ids.
*
* Also iterate through the directory's history to locate other inodes that
* used the particular file name.
......
}
}
if (cmd == CMD_DUMP) {
/*
* Single entry, most recent prior to current
*/
if (ts1.tid == 0 && RB_EMPTY(&tse_tree)) {
if ((ts1.tid == 0 ||
flags & (UNDO_FLAG_SETTID1|UNDO_FLAG_SETTID2)) &&
RB_EMPTY(&tse_tree)) {
if ((fd = open(filename, O_RDONLY)) > 0) {
collect_history(fd, &error, &tse_tree);
close(fd);
}
}
/*
* Find entry if tid set to placeholder index
*/
if (flags & UNDO_FLAG_SETTID1){
tse1 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
while (tse1 && ts1.tid--)
tse1 = RB_PREV(undo_hist_entry_rb_tree,
&tse_tree, tse1);
if (tse1)
ts1 = tse1->tse;
else
ts1.tid = 0;
}
if (flags & UNDO_FLAG_SETTID2){
tse2 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
while (tse2 && ts2.tid--)
tse2 = RB_PREV(undo_hist_entry_rb_tree,
&tse_tree, tse2);
if (tse2)
ts2 = tse2->tse;
else
ts2.tid = 0;
}
/*
* Single entry, most recent prior to current
*/
if (ts1.tid == 0) {
tse2 = RB_MAX(undo_hist_entry_rb_tree, &tse_tree);
if (tse2) {
(1-1/4)