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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx  +1 650 804 5991 cell
From 1df9e443ce11365f955b83e70365670ff9ada8d6 Mon Sep 17 00:00:00 2001
From: Dana How <how@xxxxxxxxxxxxxxxxxxxxxxx>
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


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]