# [PATCH 04/13] support rollback on writes to checksummed files

2 messages from 2007-04-05 to 2007-04-05. Participants: Dana How, Junio C Hamano.
Thread: https://gitlist.dev/t/7533

## Dana How, 2007-04-05 22:29

Subject: [PATCH 04/13] support rollback on writes to checksummed files
Message-ID: <56b7f5510704051529k55a96bdfy5b072b220f8269a7@mail.gmail.com>
URL: https://gitlist.dev/e/56b7f5510704051529k55a96bdfy5b072b220f8269a7%40mail.gmail.com

```
add struct sha1posn, sha1mark(), sha1undo() to csum-file.[ch]
---
 csum-file.c |   38 ++++++++++++++++++++++++++++++++++++++
 csum-file.h |    6 ++++++
 2 files changed, 44 insertions(+), 0 deletions(-)

-- 
Dana L. How  danahow@gmail.com  +1 650 804 5991 cell


From 1df9e443ce11365f955b83e70365670ff9ada8d6 Mon Sep 17 00:00:00 2001
From: Dana How <how@deathvalley.cswitch.com>
Date: Thu, 5 Apr 2007 13:13:42 -0700
Subject: [PATCH 04/13] support rollback on writes to checksummed files
add struct sha1posn, sha1mark(), sha1undo() to csum-file.[ch]
---
 csum-file.c |   38 ++++++++++++++++++++++++++++++++++++++
 csum-file.h |    6 ++++++
 2 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/csum-file.c b/csum-file.c
index e1ff769..e2bef75 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -72,6 +72,44 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
 	return 0;
 }
 
+/*
+ * Save current position/state in output file
+ * (needs to be fast -- no system calls!)
+ */
+void sha1mark(struct sha1file *f, struct sha1posn *p)
+{
+	p->offset = f->offset;
+	p->ctx = f->ctx;	/* larger than I'd like */
+}
+
+/*
+ * Restore previous position/state in output file
+ * (can be slow)
+ */
+void sha1undo(struct sha1file *f, struct sha1posn *p, long new, long old)
+{
+	if (new - old == (long)f->offset - (long)p->offset) {
+		f->ctx = p->ctx;
+		f->offset = p->offset;
+		return;
+	}
+	if (lseek(f->fd, (off_t)old - (off_t)p->offset, SEEK_SET) == (off_t)-1)
+		die("sha1 file '%s' undo seekback error (%s)", f->name, strerror(errno));
+	f->ctx = p->ctx;
+	while (p->offset) {
+		int ret = xread(f->fd, f->buffer, p->offset);
+		if (!ret)
+			die("sha1 file '%s' undo readback error. No data", f->name);
+		if (ret < 0)
+			die("sha1 file '%s' undo readback error (%s)", f->name, strerror(errno));
+		SHA1_Update(&f->ctx, f->buffer, ret);
+		p->offset -= ret;
+	}
+	if (ftruncate(f->fd, (off_t)old))
+		die("sha1 file '%s' undo truncate error (%s)", f->name, strerror(errno));
+	f->offset = 0;
+}
+
 struct sha1file *sha1create(const char *fmt, ...)
 {
 	struct sha1file *f;
diff --git a/csum-file.h b/csum-file.h
index 3ad1a99..780df17 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -9,11 +9,17 @@ struct sha1file {
 	char name[PATH_MAX];
 	unsigned char buffer[8192];
 };
+struct sha1posn {
+	unsigned int offset;
+	SHA_CTX ctx;
+};
 
 extern struct sha1file *sha1fd(int fd, const char *name);
 extern struct sha1file *sha1create(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
 extern int sha1close(struct sha1file *, unsigned char *, int);
 extern int sha1write(struct sha1file *, void *, unsigned int);
 extern int sha1write_compressed(struct sha1file *, void *, unsigned int);
+extern void sha1mark(struct sha1file *, struct sha1posn *);
+extern void sha1undo(struct sha1file *, struct sha1posn *, long, long);
 
 #endif
-- 
1.5.1.rc2.18.g9c88-dirty


```

## Junio C Hamano, 2007-04-05 22:58

Subject: Re: [PATCH 04/13] support rollback on writes to checksummed files
Message-ID: <7vhcrumnsh.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vhcrumnsh.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <56b7f5510704051529k55a96bdfy5b072b220f8269a7@mail.gmail.com>

```
"Dana How" <danahow@gmail.com> writes:

> From 1df9e443ce11365f955b83e70365670ff9ada8d6 Mon Sep 17 00:00:00 2001
> From: Dana How <how@deathvalley.cswitch.com>
> Date: Thu, 5 Apr 2007 13:13:42 -0700
> Subject: [PATCH 04/13] support rollback on writes to checksummed files
> add struct sha1posn, sha1mark(), sha1undo() to csum-file.[ch]

Have an empty line after "Subject:".  Begin a sentence with a
capital (i.e. "Add struct...").

Explain *why* these changes are needed, not just *what* the
patch does -- the latter can be read from the patch text.

```
