svn commit: r272283 - user/marcel/mkimg

Marcel Moolenaar marcel at FreeBSD.org
Mon Sep 29 16:24:49 UTC 2014


Author: marcel
Date: Mon Sep 29 16:24:48 2014
New Revision: 272283
URL: http://svnweb.freebsd.org/changeset/base/272283

Log:
  o   In image_set_size(), don't truncate the swap file. It isn't holding
      the entire image data anymore.
  o   Prepare for changes to image_write(): partitioning schemes call
      image_write() to fill in the sectors they reserved from themselves.
      Since we're talking about a handful of sectors, there's no need to
      have them in the swap file. Change struct chunk to accomodate for
      that. A chunk now has a type. That type can be "zeroes", "file" or
      "memory".
  o   Flesh out the cleanup function: iterate over the chunks and close
      or free the corresponding data container. Free the chunk as well.

Modified:
  user/marcel/mkimg/image.c

Modified: user/marcel/mkimg/image.c
==============================================================================
--- user/marcel/mkimg/image.c	Mon Sep 29 15:05:23 2014	(r272282)
+++ user/marcel/mkimg/image.c	Mon Sep 29 16:24:48 2014	(r272283)
@@ -45,14 +45,22 @@ __FBSDID("$FreeBSD$");
 #include "mkimg.h"
 
 struct chunk {
-	lba_t	ch_block;		/* Block address in image. */
-	off_t	ch_ofs;			/* Offset in backing file. */
 	STAILQ_ENTRY(chunk) ch_list;
 	size_t	ch_size;		/* Size of chunk in bytes. */
-	int	ch_fd;			/* FD of backing file. */
-	u_int	ch_flags;
-#define	CH_FLAGS_GAP		1	/* Chunk is a gap (no FD). */
-#define	CH_FLAGS_DIRTY		2	/* Data modified/only in memory. */
+	lba_t	ch_block;		/* Block address in image. */
+	union {
+		struct {
+			off_t	ofs;	/* Offset in backing file. */
+			int	fd;	/* FD of backing file. */
+		} file;
+		struct {
+			void	*ptr;	/* Pointer to data in memory */
+		} mem;
+	} ch_u;
+	u_int	ch_type;
+#define	CH_TYPE_ZEROES		0	/* Chunk is a gap (no data). */
+#define	CH_TYPE_FILE		1	/* File-backed chunk. */
+#define	CH_TYPE_MEMORY		2	/* Memory-backed chunk */
 };
 
 static STAILQ_HEAD(chunk_head, chunk) image_chunks;
@@ -100,9 +108,22 @@ image_chunk_dump(void)
 
 	fprintf(stderr, "%u chunks:\n", image_nchunks);
 	STAILQ_FOREACH(ch, &image_chunks, ch_list) {
-		fprintf(stderr, "\tblk=%jd, ofs=%jd, fd=%d, sz=%zu, fl=%u\n",
-		    (intmax_t)ch->ch_block, (intmax_t)ch->ch_ofs, ch->ch_fd,
-		    ch->ch_size, ch->ch_flags);
+		fprintf(stderr, "\tblk=%jd, sz=%zu, type=%u",
+		    (intmax_t)ch->ch_block, ch->ch_size, ch->ch_type);
+		switch (ch->ch_type) {
+		case CH_TYPE_ZEROES:
+			fputc('\n', stderr);
+			break;
+		case CH_TYPE_FILE:
+			fprintf(stderr, "; ofs=%jd, fd=%d\n",
+			    (intmax_t)ch->ch_u.file.ofs, ch->ch_u.file.fd);
+			break;
+		case CH_TYPE_MEMORY:
+			fprintf(stderr, "; ptr=%p\n", ch->ch_u.mem.ptr);
+			break;
+		default:
+			abort();
+		}
 	}
 }
 
@@ -142,7 +163,7 @@ image_chunk_skipto(lba_t to)
 	if ((uintmax_t)(to - from) > (uintmax_t)(SIZE_MAX / secsz))
 		return (EFBIG);
 	sz = (to - from) * secsz;
-	if (ch != NULL && (ch->ch_flags & CH_FLAGS_GAP)) {
+	if (ch != NULL && ch->ch_type == CH_TYPE_ZEROES) {
 		sz = image_chunk_grow(ch, sz);
 		if (sz == 0)
 			return (0);
@@ -154,8 +175,7 @@ image_chunk_skipto(lba_t to)
 	memset(ch, 0, sizeof(*ch));
 	ch->ch_block = from;
 	ch->ch_size = sz;
-	ch->ch_fd = -1;
-	ch->ch_flags |= CH_FLAGS_GAP;
+	ch->ch_type = CH_TYPE_ZEROES;
 	STAILQ_INSERT_TAIL(&image_chunks, ch, ch_list);
 	image_nchunks++;
 	return (0);
@@ -167,15 +187,15 @@ image_chunk_append(lba_t blk, size_t sz,
 	struct chunk *ch;
 
 	ch = STAILQ_LAST(&image_chunks, chunk, ch_list);
-	if (ch != NULL && (ch->ch_flags & CH_FLAGS_GAP) == 0) {
-		if (fd == ch->ch_fd &&
+	if (ch != NULL && ch->ch_type == CH_TYPE_FILE) {
+		if (fd == ch->ch_u.file.fd &&
 		    blk == (lba_t)(ch->ch_block + (ch->ch_size / secsz)) &&
-		    ofs == (off_t)(ch->ch_ofs + ch->ch_size)) {
+		    ofs == (off_t)(ch->ch_u.file.ofs + ch->ch_size)) {
 			sz = image_chunk_grow(ch, sz);
 			if (sz == 0)
 				return (0);
 			blk = ch->ch_block + (ch->ch_size / secsz);
-			ofs = ch->ch_ofs + ch->ch_size;
+			ofs = ch->ch_u.file.ofs + ch->ch_size;
 		}
 	}
 	ch = malloc(sizeof(*ch));
@@ -183,9 +203,10 @@ image_chunk_append(lba_t blk, size_t sz,
 		return (ENOMEM);
 	memset(ch, 0, sizeof(*ch));
 	ch->ch_block = blk;
-	ch->ch_ofs = ofs;
 	ch->ch_size = sz;
-	ch->ch_fd = fd;
+	ch->ch_type = CH_TYPE_FILE;
+	ch->ch_u.file.ofs = ofs;
+	ch->ch_u.file.fd = fd;
 	STAILQ_INSERT_TAIL(&image_chunks, ch, ch_list);
 	image_nchunks++;
 	return (0);
@@ -513,13 +534,12 @@ image_get_size(void)
 int
 image_set_size(lba_t blk)
 {
+	int error;
 
-	image_chunk_skipto(blk);
-
-	image_size = blk;
-	if (ftruncate(image_swap_fd, blk * secsz) == -1)
-		return (errno);
-	return (0);
+	error = image_chunk_skipto(blk);
+	if (!error)
+		image_size = blk;
+	return (error);
 }
 
 int
@@ -538,7 +558,24 @@ image_write(lba_t blk, void *buf, ssize_
 static void
 image_cleanup(void)
 {
+	struct chunk *ch;
 
+	while ((ch = STAILQ_FIRST(&image_chunks)) != NULL) {
+		switch (ch->ch_type) {
+		case CH_TYPE_FILE:
+			/* We may be closing the same file multiple times. */
+			if (ch->ch_u.file.fd != -1)
+				close(ch->ch_u.file.fd);
+			break;
+		case CH_TYPE_MEMORY:
+			free(ch->ch_u.mem.ptr);
+			break;
+		default:
+			break;
+		}
+		STAILQ_REMOVE_HEAD(&image_chunks, ch_list);
+		free(ch);
+	}
 	if (image_swap_fd != -1)
 		close(image_swap_fd);
 	unlink(image_swap_file);


More information about the svn-src-user mailing list