1    	#include "clusterautoconfig.h"
2    	
3    	#include <stdio.h>
4    	#include <stdlib.h>
5    	#include <ctype.h>
6    	#include <string.h>
7    	#include <stdint.h>
8    	#include <inttypes.h>
9    	#include <sys/types.h>
10   	#include <sys/stat.h>
11   	#include <fcntl.h>
12   	#include <unistd.h>
13   	#include <errno.h>
14   	#include <curses.h>
15   	#include <term.h>
16   	#include <sys/ioctl.h>
17   	#include <limits.h>
18   	#include <sys/time.h>
19   	#include <zlib.h>
20   	#include <bzlib.h>
21   	#include <time.h>
22   	
23   	#include <logging.h>
24   	#include "osi_list.h"
25   	#include "gfs2hex.h"
26   	#include "hexedit.h"
27   	#include "libgfs2.h"
28   	
29   	#define DFT_SAVE_FILE "/tmp/gfsmeta.XXXXXX"
30   	#define MAX_JOURNALS_SAVED 256
31   	
32   	/* Header for the savemeta output file */
33   	struct savemeta_header {
34   	#define SAVEMETA_MAGIC (0x01171970)
35   		__be32 sh_magic;
36   	#define SAVEMETA_FORMAT (1)
37   		__be32 sh_format; /* In case we want to change the layout */
38   		__be64 sh_time; /* When savemeta was run */
39   		__be64 sh_fs_bytes; /* Size of the fs */
40   		uint8_t __reserved[104];
41   	};
42   	
43   	struct savemeta {
44   		time_t sm_time;
45   		unsigned sm_format;
46   		uint64_t sm_fs_bytes;
47   	};
48   	
49   	struct saved_metablock {
50   		__be64 blk;
51   		__be16 siglen; /* significant data length */
52   	/* This needs to be packed because old versions of gfs2_edit read and write the
53   	   individual fields separately, so the hole after siglen must be eradicated
54   	   before the struct reflects what's on disk. */
55   	} __attribute__((__packed__));
56   	
57   	struct metafd {
58   		int fd;
59   		gzFile gzfd;
60   		BZFILE *bzfd;
61   		const char *filename;
62   		int gziplevel;
63   		int eof;
64   		int (*read)(struct metafd *mfd, void *buf, unsigned len);
65   		void (*close)(struct metafd *mfd);
66   		const char* (*strerr)(struct metafd *mfd);
67   	};
68   	
69   	static char *restore_buf;
70   	static ssize_t restore_left;
71   	static off_t restore_off;
72   	#define RESTORE_BUF_SIZE (2 * 1024 * 1024)
73   	
74   	static char *restore_buf_next(struct metafd *mfd, size_t required_len)
75   	{
76   		if (restore_left < required_len) {
77   			char *tail = restore_buf + restore_off;
78   			int ret;
79   	
80   			memmove(restore_buf, tail, restore_left);
81   			ret = mfd->read(mfd, restore_buf + restore_left, RESTORE_BUF_SIZE - restore_left);
82   			if (ret < (int)required_len - restore_left)
83   				return NULL;
84   			restore_left += ret;
85   			restore_off = 0;
86   		}
87   		restore_left -= required_len;
88   		restore_off += required_len;
89   		return &restore_buf[restore_off - required_len];
90   	}
91   	
92   	/* gzip compression method */
93   	
94   	static const char *gz_strerr(struct metafd *mfd)
95   	{
96   		int err;
97   		const char *errstr = gzerror(mfd->gzfd, &err);
98   	
99   		if (err == Z_ERRNO)
100  			return strerror(errno);
101  		return errstr;
102  	}
103  	
104  	static int gz_read(struct metafd *mfd, void *buf, unsigned len)
105  	{
106  		int ret = gzread(mfd->gzfd, buf, len);
107  		if (ret < len && gzeof(mfd->gzfd))
108  			mfd->eof = 1;
109  		return ret;
110  	}
111  	
112  	static void gz_close(struct metafd *mfd)
113  	{
114  		gzclose(mfd->gzfd);
115  	}
116  	
117  	/* This should be tried last because gzip doesn't distinguish between
118  	   decompressing a gzip file and reading an uncompressed file */
119  	static int restore_try_gzip(struct metafd *mfd)
120  	{
121  		mfd->read = gz_read;
122  		mfd->close = gz_close;
123  		mfd->strerr = gz_strerr;
124  		lseek(mfd->fd, 0, SEEK_SET);
125  		mfd->gzfd = gzdopen(mfd->fd, "rb");
126  		if (!mfd->gzfd)
127  			return 1;
128  		gzbuffer(mfd->gzfd, (1<<20)); /* Increase zlib's buffers to 1MB */
129  		restore_left = mfd->read(mfd, restore_buf, RESTORE_BUF_SIZE);
130  		if (restore_left < 512)
131  			return -1;
132  		return 0;
133  	}
134  	
135  	/* bzip2 compression method */
136  	
137  	static const char *bz_strerr(struct metafd *mfd)
138  	{
139  		int err;
140  		const char *errstr = BZ2_bzerror(mfd->bzfd, &err);
141  	
142  		if (err == BZ_IO_ERROR)
143  			return strerror(errno);
144  		return errstr;
145  	}
146  	
147  	static int bz_read(struct metafd *mfd, void *buf, unsigned len)
148  	{
149  		int bzerr = BZ_OK;
150  		int ret;
151  	
152  		ret = BZ2_bzRead(&bzerr, mfd->bzfd, buf, len);
153  		if (bzerr == BZ_OK)
154  			return ret;
155  		if (bzerr == BZ_STREAM_END) {
156  			mfd->eof = 1;
157  			return ret;
158  		}
159  		return -1;
160  	}
161  	
162  	static void bz_close(struct metafd *mfd)
163  	{
164  		BZ2_bzclose(mfd->bzfd);
165  	}
166  	
167  	static int restore_try_bzip(struct metafd *mfd)
168  	{
169  		int bzerr;
170  		FILE *f;
171  	
172  		f = fdopen(mfd->fd, "r");
173  		if (f == NULL)
174  			return 1;
175  	
176  		mfd->read = bz_read;
177  		mfd->close = bz_close;
178  		mfd->strerr = bz_strerr;
179  		mfd->bzfd = BZ2_bzReadOpen(&bzerr, f, 0, 0, NULL, 0);
180  		if (!mfd->bzfd)
181  			return 1;
182  		restore_left = mfd->read(mfd, restore_buf, RESTORE_BUF_SIZE);
183  		if (restore_left < 512)
184  			return -1;
185  		return 0;
186  	}
187  	
188  	static uint64_t blks_saved;
189  	static uint64_t journal_blocks[MAX_JOURNALS_SAVED];
190  	static int journals_found = 0;
191  	int print_level = MSG_NOTICE;
192  	
193  	static int block_is_a_journal(uint64_t blk)
194  	{
195  		int j;
196  	
197  		for (j = 0; j < journals_found; j++)
198  			if (blk == journal_blocks[j])
199  				return TRUE;
200  		return FALSE;
201  	}
202  	
203  	static struct osi_root per_node_tree;
204  	struct per_node_node {
205  		struct osi_node node;
206  		uint64_t block;
207  	};
208  	
209  	static void destroy_per_node_lookup(void)
210  	{
211  		struct osi_node *n;
212  		struct per_node_node *pnp;
213  	
214  		while ((n = osi_first(&per_node_tree))) {
215  			pnp = (struct per_node_node *)n;
216  			osi_erase(n, &per_node_tree);
217  			free(pnp);
218  		}
219  	}
220  	
221  	static int block_is_in_per_node(uint64_t blk)
222  	{
223  		struct per_node_node *pnp = (struct per_node_node *)per_node_tree.osi_node;
224  	
225  		while (pnp) {
226  			if (blk < pnp->block)
227  				pnp = (struct per_node_node *)pnp->node.osi_left;
228  			else if (blk > pnp->block)
229  				pnp = (struct per_node_node *)pnp->node.osi_right;
230  			else
231  				return 1;
232  		}
233  	
234  		return 0;
235  	}
236  	
237  	static int insert_per_node_lookup(uint64_t blk)
238  	{
239  		struct osi_node **newn = &per_node_tree.osi_node, *parent = NULL;
240  		struct per_node_node *pnp;
241  	
242  		while (*newn) {
243  			struct per_node_node *cur = (struct per_node_node *)*newn;
244  	
245  			parent = *newn;
246  			if (blk < cur->block)
247  				newn = &((*newn)->osi_left);
248  			else if (blk > cur->block)
249  				newn = &((*newn)->osi_right);
250  			else
251  				return 0;
252  		}
253  	
254  		pnp = calloc(1, sizeof(struct per_node_node));
255  		if (pnp == NULL) {
256  			perror("Failed to insert per_node lookup entry");
257  			return 1;
258  		}
259  		pnp->block = blk;
260  		osi_link_node(&pnp->node, parent, newn);
261  		osi_insert_color(&pnp->node, &per_node_tree);
262  		return 0;
263  	}
264  	
265  	static int init_per_node_lookup(void)
266  	{
267  		int i;
268  		struct lgfs2_inode *per_node_di;
269  	
270  		per_node_di = lgfs2_inode_read(&sbd, masterblock("per_node"));
271  		if (per_node_di == NULL) {
272  			fprintf(stderr, "Failed to read per_node: %s\n", strerror(errno));
273  			return 1;
274  		}
275  	
276  		do_dinode_extended(per_node_di->i_bh->b_data);
277  		lgfs2_inode_put(&per_node_di);
278  	
279  		for (i = 0; i < indirect_blocks; i++) {
280  			int d;
281  			for (d = 0; d < indirect->ii[i].dirents; d++) {
282  				int ret = insert_per_node_lookup(indirect->ii[i].dirent[d].inum.in_addr);
283  				if (ret != 0)
284  					return ret;
285  			}
286  		}
287  		return 0;
288  	}
289  	
290  	static int block_is_systemfile(uint64_t blk)
291  	{
292  		return block_is_inum_file(blk) ||
293  		       block_is_statfs_file(blk) ||
294  		       block_is_quota_file(blk) ||
295  		       block_is_rindex(blk) ||
296  		       block_is_a_journal(blk) ||
297  		       block_is_per_node(blk) ||
298  		       block_is_in_per_node(blk);
299  	}
300  	
301  	static size_t di_save_len(const char *buf, uint64_t owner)
302  	{
303  		const struct gfs2_dinode *dn;
304  		uint16_t di_height;
305  		uint32_t di_mode;
306  	
307  		dn = (void *)buf;
308  		di_mode = be32_to_cpu(dn->di_mode);
309  		di_height = be16_to_cpu(dn->di_height);
310  	
311  		/* Do not save (user) data from the inode block unless they are
312  		   indirect pointers, dirents, symlinks or fs internal data */
313  		if (di_height > 0 || S_ISDIR(di_mode) || S_ISLNK(di_mode) ||
314  		    block_is_systemfile(owner))
315  			return sbd.sd_bsize;
316  		return sizeof(struct gfs2_dinode);
317  	}
318  	
319  	/*
320  	 * get_struct_info - get block type and structure length
321  	 *
322  	 * @buf - The block buffer to examine
323  	 * @owner - The block address of the parent structure
324  	 * @block_type - pointer to integer to hold the block type
325  	 * @gstruct_len - pointer to integer to hold the structure length
326  	 *
327  	 * returns: 0 if successful
328  	 *          -1 if this isn't gfs2 metadata.
329  	 */
330  	static int get_struct_info(const char *buf, uint64_t owner, unsigned *block_type,
331  	                               unsigned *gstruct_len)
332  	{
333  		struct gfs2_meta_header *mh = (struct gfs2_meta_header *)buf;
334  	
335  		if (block_type != NULL)
336  			*block_type = 0;
337  	
338  		if (gstruct_len != NULL)
339  			*gstruct_len = sbd.sd_bsize;
340  	
341  		if (be32_to_cpu(mh->mh_magic) != GFS2_MAGIC)
342  			return -1;
343  	
344  		if (block_type != NULL)
345  			*block_type = be32_to_cpu(mh->mh_type);
346  	
347  		if (gstruct_len == NULL)
348  			return 0;
349  	
350  		switch (be32_to_cpu(mh->mh_type)) {
351  		case GFS2_METATYPE_SB:   /* 1 (superblock) */
352  			*gstruct_len = sizeof(struct gfs2_sb);
353  			break;
354  		case GFS2_METATYPE_RG:   /* 2 (rsrc grp hdr) */
355  			*gstruct_len = sbd.sd_bsize; /*sizeof(struct gfs_rgrp);*/
356  			break;
357  		case GFS2_METATYPE_RB:   /* 3 (rsrc grp bitblk) */
358  			*gstruct_len = sbd.sd_bsize;
359  			break;
360  		case GFS2_METATYPE_DI:   /* 4 (disk inode) */
361  			*gstruct_len = di_save_len(buf, owner);
362  			break;
363  		case GFS2_METATYPE_IN:   /* 5 (indir inode blklst) */
364  			*gstruct_len = sbd.sd_bsize; /*sizeof(struct gfs_indirect);*/
365  			break;
366  		case GFS2_METATYPE_LF:   /* 6 (leaf dinode blklst) */
367  			*gstruct_len = sbd.sd_bsize; /*sizeof(struct gfs_leaf);*/
368  			break;
369  		case GFS2_METATYPE_JD:   /* 7 (journal data) */
370  			*gstruct_len = sbd.sd_bsize;
371  			break;
372  		case GFS2_METATYPE_LH:   /* 8 (log header) */
373  			*gstruct_len = sizeof(struct gfs2_log_header);
374  			break;
375  		case GFS2_METATYPE_LD:   /* 9 (log descriptor) */
376  			*gstruct_len = sbd.sd_bsize;
377  			break;
378  		case GFS2_METATYPE_EA:   /* 10 (extended attr hdr) */
379  			*gstruct_len = sbd.sd_bsize;
380  			break;
381  		case GFS2_METATYPE_ED:   /* 11 (extended attr data) */
382  			*gstruct_len = sbd.sd_bsize;
383  			break;
384  		default:
385  			*gstruct_len = sbd.sd_bsize;
386  			break;
387  		}
388  		return 0;
389  	}
390  	
391  	/**
392  	 * Print a progress message if one second has elapsed since the last time.
393  	 * pblock: The latest block number processed
394  	 * force:  If this is non-zero, print immediately and add a newline after the
395  	 *         progress message.
396  	 */
397  	static void report_progress(uint64_t pblock, int force)
398  	{
399  	        static struct timeval tv;
400  	        static uint32_t seconds = 0;
401  	
402  		gettimeofday(&tv, NULL);
403  		if (!seconds)
404  			seconds = tv.tv_sec;
405  		if (force || tv.tv_sec - seconds) {
406  			static uint64_t percent;
407  	
408  			seconds = tv.tv_sec;
409  			if (sbd.fssize) {
410  				printf("\r");
411  				percent = (pblock * 100) / sbd.fssize;
412  				printf("%"PRIu64" blocks saved (%"PRIu64"%% complete)",
413  				       blks_saved, percent);
414  				if (force)
415  					printf("\n");
416  				fflush(stdout);
417  			}
418  		}
419  	}
420  	
421  	/**
422  	 * Open a file and prepare it for writing by savemeta()
423  	 * out_fn: the path to the file, which will be truncated if it exists
424  	 * gziplevel: 0   - do not compress the file,
425  	 *            1-9 - use gzip compression level 1-9
426  	 * Returns a struct metafd containing the opened file descriptor
427  	 */
428  	static struct metafd savemetaopen(char *out_fn, int gziplevel)
429  	{
430  		struct metafd mfd = {0};
431  		char gzmode[3] = "w9";
432  		char dft_fn[] = DFT_SAVE_FILE;
433  		mode_t mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
434  		struct stat st;
435  	
436  		mfd.gziplevel = gziplevel;
437  	
438  		if (!out_fn) {
439  			out_fn = dft_fn;
440  			mfd.fd = mkstemp(out_fn);
441  		} else {
442  			mfd.fd = open(out_fn, O_RDWR | O_CREAT, 0644);
443  		}
444  		umask(mask);
445  		mfd.filename = out_fn;
446  	
447  		if (mfd.fd < 0) {
448  			fprintf(stderr, "Can't open %s: %s\n", out_fn, strerror(errno));
449  			exit(1);
450  		}
451  		if (fstat(mfd.fd, &st) == -1) {
452  			fprintf(stderr, "Failed to stat %s: %s\n", out_fn, strerror(errno));
453  			exit(1);
454  		}
455  		if (S_ISREG(st.st_mode) && ftruncate(mfd.fd, 0)) {
456  			fprintf(stderr, "Can't truncate %s: %s\n", out_fn, strerror(errno));
457  			exit(1);
458  		}
459  	
460  		if (gziplevel > 0) {
461  			gzmode[1] = '0' + gziplevel;
462  			mfd.gzfd = gzdopen(mfd.fd, gzmode);
463  			if (!mfd.gzfd) {
464  				fprintf(stderr, "gzdopen error: %s\n", strerror(errno));
465  				exit(1);
466  			}
467  			gzbuffer(mfd.gzfd, (1<<20)); /* Increase zlib's buffers to 1MB */
468  		}
469  	
470  		return mfd;
471  	}
472  	
473  	/**
474  	 * Write nbyte bytes from buf to a file opened with savemetaopen()
475  	 * mfd: the file descriptor opened using savemetaopen()
476  	 * buf: the buffer to write data from
477  	 * nbyte: the number of bytes to write
478  	 * Returns the number of bytes written from buf or -1 on error
479  	 */
480  	static ssize_t savemetawrite(struct metafd *mfd, const void *buf, size_t nbyte)
481  	{
482  		ssize_t ret;
483  		int gzerr;
484  		const char *gzerrmsg;
485  	
486  		if (mfd->gziplevel == 0) {
487  			return write(mfd->fd, buf, nbyte);
488  		}
489  	
490  		ret = gzwrite(mfd->gzfd, buf, nbyte);
491  		if (ret != nbyte) {
492  			gzerrmsg = gzerror(mfd->gzfd, &gzerr);
493  			if (gzerr != Z_ERRNO) {
494  				fprintf(stderr, "Error: zlib: %s\n", gzerrmsg);
495  			}
496  		}
497  		return ret;
498  	}
499  	
500  	/**
501  	 * Closes a file descriptor previously opened using savemetaopen()
502  	 * mfd: the file descriptor previously opened using savemetaopen()
503  	 * Returns 0 on success or -1 on error
504  	 */
505  	static int savemetaclose(struct metafd *mfd)
506  	{
507  		int gzret;
508  		if (mfd->gziplevel > 0) {
509  			gzret = gzclose(mfd->gzfd);
510  			if (gzret == Z_STREAM_ERROR) {
511  				fprintf(stderr, "gzclose: file is not valid\n");
512  				return -1;
513  			} else if (gzret == Z_ERRNO) {
514  				return -1;
515  			}
516  		}
517  		return close(mfd->fd);
518  	}
519  	
520  	static int save_buf(struct metafd *mfd, const char *buf, uint64_t addr, unsigned blklen)
521  	{
522  		struct saved_metablock *savedata;
523  		size_t outsz;
524  	
525  		/* No need to save trailing zeroes, but leave that for compression to
526  		   deal with when enabled as this adds a significant overhead */
527  		if (mfd->gziplevel == 0)
528  			for (; blklen > 0 && buf[blklen - 1] == '\0'; blklen--);
529  	
530  		if (blklen == 0) /* No significant data; skip. */
531  			return 0;
532  	
533  		outsz = sizeof(*savedata) + blklen;
534  		savedata = calloc(1, outsz);
535  		if (savedata == NULL) {
536  			perror("Failed to save block");
537  			exit(1);
538  		}
539  		savedata->blk = cpu_to_be64(addr);
540  		savedata->siglen = cpu_to_be16(blklen);
541  		memcpy(savedata + 1, buf, blklen);
542  	
543  		if (savemetawrite(mfd, savedata, outsz) != outsz) {
544  			fprintf(stderr, "write error: %s from %s:%d: block %"PRIu64"\n",
545  			        strerror(errno), __FUNCTION__, __LINE__, addr);
546  			free(savedata);
547  			exit(-1);
548  		}
549  		blks_saved++;
550  		free(savedata);
551  		return 0;
552  	}
553  	
554  	struct block_range {
555  		struct block_range *next;
556  		uint64_t start;
557  		unsigned len;
558  		unsigned *blktype;
559  		unsigned *blklen;
560  		char *buf;
561  	};
562  	
563  	static int block_range_prepare(struct block_range *br)
564  	{
565  		br->buf = calloc(br->len, sbd.sd_bsize + sizeof(*br->blktype) + sizeof(*br->blklen));
566  		if (br->buf == NULL) {
567  			perror("Failed to allocate block range buffer");
568  			return 1;
569  		}
570  		br->blktype = (unsigned *)(br->buf + (br->len * sbd.sd_bsize));
571  		br->blklen = br->blktype + br->len;
572  		return 0;
573  	}
574  	
575  	static int block_range_check(struct block_range *br)
576  	{
577  		if (br->start >= LGFS2_SB_ADDR(&sbd) && br->start + br->len <= sbd.fssize)
578  			return 0;
579  	
580  		fprintf(stderr, "Warning: bad range 0x%"PRIx64" (%u blocks) ignored.\n",
581  			br->start, br->len);
582  		free(br->buf);
583  		br->buf = NULL;
584  		return 1;
585  	}
586  	
587  	static void block_range_setinfo(struct block_range *br, uint64_t owner)
588  	{
589  		for (unsigned i = 0; i < br->len; i++) {
590  			char *buf = br->buf + (i * sbd.sd_bsize);
591  			uint64_t addr = br->start + i;
592  			uint64_t _owner = (owner == 0) ? addr : owner;
593  	
594  			if (get_struct_info(buf, _owner, br->blktype + i, br->blklen + i) &&
595  			    !block_is_systemfile(_owner)) {
596  				br->blklen[i] = 0;
597  			}
598  		}
599  	}
600  	
601  	static void block_range_free(struct block_range **brp)
602  	{
603  		free((*brp)->buf);
604  		free(*brp);
605  		*brp = NULL;
606  	}
607  	
608  	struct block_range_queue {
609  		struct block_range *tail;
610  		struct block_range **head;
611  	};
612  	
613  	static void block_range_queue_init(struct block_range_queue *q)
614  	{
615  		q->head = &q->tail;
616  	}
617  	
618  	static void block_range_queue_insert(struct block_range_queue *q, struct block_range *br)
619  	{
620  		*q->head = br;
621  		q->head = &br->next;
622  	}
623  	
624  	static struct block_range *block_range_queue_pop(struct block_range_queue *q)
625  	{
626  		struct block_range *br = q->tail;
627  	
628  		q->tail = br->next;
629  		br->next = NULL;
630  		return br;
631  	}
632  	
633  	static int save_range(struct metafd *mfd, struct block_range *br)
634  	{
635  		for (unsigned i = 0; i < br->len; i++) {
636  			int err;
637  	
638  			err = save_buf(mfd, br->buf + (i * sbd.sd_bsize), br->start + i, br->blklen[i]);
639  			if (err != 0)
640  				return err;
641  		}
642  		return 0;
643  	}
644  	
645  	static int check_read_range(int fd, struct block_range *br, uint64_t owner)
646  	{
647  		size_t size;
648  	
(1) Event cond_false: Condition "block_range_prepare(br) != 0", taking false branch.
649  		if (block_range_prepare(br) != 0)
(2) Event if_end: End of if statement.
650  			return 1;
651  	
(3) Event cond_false: Condition "block_range_check(br) != 0", taking false branch.
652  		if (block_range_check(br) != 0)
(4) Event if_end: End of if statement.
653  			return 1;
654  	
655  		size = br->len * sbd.sd_bsize;
(5) Event tainted_data_argument: Calling function "pread" taints parameter "*br->buf". [Note: The source code implementation of the function has been overridden by a builtin model.]
(6) Event cond_false: Condition "pread(sbd.device_fd, br->buf, size, sbd.sd_bsize * br->start) != size", taking false branch.
656  		if (pread(sbd.device_fd, br->buf, size, sbd.sd_bsize * br->start) != size) {
657  			fprintf(stderr, "Failed to read block range 0x%"PRIx64" (%u blocks): %s\n",
658  			        br->start, br->len, strerror(errno));
659  			free(br->buf);
660  			br->buf = NULL;
661  			return 1;
(7) Event if_end: End of if statement.
662  		}
663  		block_range_setinfo(br, owner);
664  		return 0;
665  	}
666  	
667  	static char *check_read_block(int fd, uint64_t blk, uint64_t owner, int *blktype, size_t *blklen)
668  	{
669  		struct block_range br = {
670  			.start = blk,
671  			.len = 1
672  		};
673  	
(1) Event tainted_data_argument: Calling function "check_read_range" taints parameter "*br.buf". [details]
(2) Event cond_false: Condition "check_read_range(fd, &br, owner) != 0", taking false branch.
Also see events: [return_tainted_data]
674  		if (check_read_range(fd, &br, owner) != 0)
(3) Event if_end: End of if statement.
675  			return NULL;
(4) Event cond_true: Condition "blklen != NULL", taking true branch.
676  		if (blklen != NULL)
677  			*blklen = *br.blklen;
(5) Event cond_true: Condition "blktype != NULL", taking true branch.
678  		if (blktype != NULL)
679  			*blktype = *br.blktype;
(6) Event return_tainted_data: Returning tainted data "br.buf".
Also see events: [tainted_data_argument]
680  		return br.buf;
681  	}
682  	
683  	/*
684  	 * save_ea_block - save off an extended attribute block
685  	 */
686  	static void save_ea_block(struct metafd *mfd, char *buf, uint64_t owner)
687  	{
688  		struct gfs2_ea_header *ea;
689  		uint32_t rec_len = 0;
690  		int e;
691  	
(1) Event cond_true: Condition "e < sbd.sd_bsize", taking true branch.
692  		for (e = sizeof(struct gfs2_meta_header); e < sbd.sd_bsize; e += rec_len) {
693  			uint64_t blk;
694  			int charoff, i;
695  			__be64 *b;
696  	
(2) Event var_assign_alias: Assigning: "ea" = "(void *)(buf + e)", which taints "ea".
Also see events: [lower_bounds][loop_bound_upper]
697  			ea = (void *)(buf + e);
698  			/* ea_num_ptrs and ea_name_len are u8 so no endianness worries */
(3) Event lower_bounds: Casting narrower unsigned "ea->ea_num_ptrs" to wider signed type "int" effectively tests its lower bound.
(4) Event loop_bound_upper: Using tainted expression "ea->ea_num_ptrs" as a loop boundary.
Also see events: [var_assign_alias]
699  			for (i = 0; i < ea->ea_num_ptrs; i++) {
700  				char *_buf;
701  	
702  				charoff = e + ea->ea_name_len +
703  					sizeof(struct gfs2_ea_header) +
704  					sizeof(uint64_t) - 1;
705  				charoff /= sizeof(uint64_t);
706  				b = (__be64 *)buf;
707  				b += charoff + i;
708  				blk = be64_to_cpu(*b);
709  				_buf = check_read_block(sbd.device_fd, blk, owner, NULL, NULL);
710  				if (_buf != NULL) {
711  					save_buf(mfd, _buf, blk, sbd.sd_bsize);
712  					free(_buf);
713  				}
714  			}
715  			rec_len = be32_to_cpu(ea->ea_rec_len);
716  			if (rec_len == 0)
717  				break;
718  		}
719  	}
720  	
721  	static void save_indirect_range(struct metafd *mfd, struct block_range **brp, uint64_t owner,
722  	                                struct block_range_queue *q)
723  	{
724  		struct block_range *br = *brp;
725  	
726  		if (check_read_range(sbd.device_fd, br, owner) != 0)
727  			return;
728  	
729  		save_range(mfd, br);
730  		for (unsigned i = 0; i < br->len; i++) {
731  			if (br->blktype[i] == GFS2_METATYPE_EA)
732  				save_ea_block(mfd, br->buf + (i * sbd.sd_bsize), owner);
733  		}
734  		if (q) {
735  			block_range_queue_insert(q, br);
736  			*brp = NULL; /* The list now has ownership of it */
737  		} else {
738  			free(br->buf);
739  			br->buf = NULL;
740  		}
741  	}
742  	
743  	static void save_indirect_blocks(struct metafd *mfd, char *buf, uint64_t owner,
744  	                                 struct block_range_queue *q, unsigned headsize)
745  	{
746  		uint64_t old_block = 0, indir_block;
747  		struct block_range *br = NULL;
748  		__be64 *ptr;
749  	
750  		for (ptr = (__be64 *)(buf + headsize);
751  		     (char *)ptr < (buf + sbd.sd_bsize); ptr++) {
752  			if (!*ptr)
753  				continue;
754  	
755  			indir_block = be64_to_cpu(*ptr);
756  			if (indir_block == old_block)
757  				continue;
758  			old_block = indir_block;
759  	
760  			if (br == NULL) {
761  	new_range:
762  				br = calloc(1, sizeof(*br));
763  				if (br == NULL) {
764  					perror("Failed to save indirect blocks");
765  					return;
766  				}
767  				br->start = indir_block;
768  				br->len = 1;
769  			} else if (indir_block == br->start + br->len) {
770  				br->len++;
771  			} else {
772  				save_indirect_range(mfd, &br, owner, q);
773  				if (br == NULL) /* This one was queued up for later */
774  					goto new_range;
775  				br->start = indir_block;
776  				br->len = 1;
777  			}
778  		}
779  		if (br != NULL && br->start != 0)
780  			save_indirect_range(mfd, &br, owner, q);
781  		free(br);
782  	}
783  	
784  	static int save_leaf_chain(struct metafd *mfd, struct lgfs2_sbd *sdp, char *buf)
785  	{
786  		struct gfs2_leaf *leaf = (struct gfs2_leaf *)buf;
787  	
788  		while (leaf->lf_next != 0) {
789  			uint64_t blk = be64_to_cpu(leaf->lf_next);
790  			ssize_t r;
791  	
792  			if (lgfs2_check_range(sdp, blk) != 0)
793  				return 0;
794  	
795  			r = pread(sdp->device_fd, buf, sdp->sd_bsize, sdp->sd_bsize * blk);
796  			if (r != sdp->sd_bsize) {
797  				fprintf(stderr, "Failed to read leaf block %"PRIx64": %s\n",
798  				        blk, strerror(errno));
799  				return 1;
800  			}
801  			report_progress(blk, 0);
802  			if (lgfs2_check_meta(buf, GFS2_METATYPE_LF) == 0) {
803  				int ret = save_buf(mfd, buf, blk, sdp->sd_bsize);
804  				if (ret != 0)
805  					return ret;
806  			}
807  			leaf = (struct gfs2_leaf *)buf;
808  		}
809  		return 0;
810  	}
811  	
812  	static void save_leaf_blocks(struct metafd *mfd, struct block_range_queue *q)
813  	{
814  		while (q->tail != NULL) {
815  			struct block_range *br = q->tail;
816  	
817  			for (unsigned i = 0; i < br->len; i++) {
818  				char *buf = br->buf + (i * sbd.sd_bsize);
819  	
820  				save_leaf_chain(mfd, &sbd, buf);
821  			}
822  			q->tail = br->next;
823  			block_range_free(&br);
824  		}
825  	}
826  	
827  	/*
828  	 * save_inode_data - save off important data associated with an inode
829  	 *
830  	 * mfd - destination file descriptor
831  	 * buf - buffer containing the inode block
832  	 * iblk - block number of the inode to save the data for
833  	 *
834  	 * For user files, we don't want anything except all the indirect block
835  	 * pointers that reside on blocks on all but the highest height.
836  	 *
837  	 * For system files like statfs and inum, we want everything because they
838  	 * may contain important clues and no user data.
839  	 *
840  	 * For file system journals, the "data" is a mixture of metadata and
841  	 * journaled data.  We want all the metadata and none of the user data.
842  	 */
843  	static void save_inode_data(struct metafd *mfd, char *ibuf, uint64_t iblk)
844  	{
845  		struct block_range_queue indq[GFS2_MAX_META_HEIGHT] = {{NULL}};
846  		struct gfs2_dinode *dip = (struct gfs2_dinode *)ibuf;
847  		uint16_t height;
848  		int is_exhash;
849  	
(1) Event cond_true: Condition "i < 10", taking true branch.
(3) Event loop_begin: Jumped back to beginning of loop.
(4) Event cond_true: Condition "i < 10", taking true branch.
(6) Event loop_begin: Jumped back to beginning of loop.
(7) Event cond_false: Condition "i < 10", taking false branch.
850  		for (unsigned i = 0; i < GFS2_MAX_META_HEIGHT; i++)
(2) Event loop: Jumping back to the beginning of the loop.
(5) Event loop: Jumping back to the beginning of the loop.
(8) Event loop_end: Reached end of loop.
851  			block_range_queue_init(&indq[i]);
852  	
853  		height = be16_to_cpu(dip->di_height);
854  	
855  		/* If this is a user inode, we don't follow to the file height.
856  		   We stop one level less.  That way we save off the indirect
857  		   pointer blocks but not the actual file contents. The exception
858  		   is directories, where the height represents the level at which
859  		   the hash table exists, and we have to save the directory data. */
860  	
(9) Event cond_true: Condition "(__bswap_32((uint32_t)(__be32)dip->di_mode) & 61440) == 16384", taking true branch.
(10) Event cond_true: Condition "__bswap_32((uint32_t)(__be32)dip->di_flags) & 2", taking true branch.
861  		is_exhash = S_ISDIR(be32_to_cpu(dip->di_mode)) &&
862  		            be32_to_cpu(dip->di_flags) & GFS2_DIF_EXHASH;
(11) Event cond_true: Condition "is_exhash", taking true branch.
863  		if (is_exhash)
(12) Event if_fallthrough: Falling through to end of if statement.
864  			height++;
865  		else if (height > 0 && !(be32_to_cpu(dip->di_flags) & GFS2_DIF_SYSTEM) &&
866  			 !block_is_systemfile(iblk) && !S_ISDIR(be32_to_cpu(dip->di_mode)))
(13) Event if_end: End of if statement.
867  			height--;
868  	
(14) Event cond_true: Condition "height == 1", taking true branch.
869  		if (height == 1)
(15) Event if_fallthrough: Falling through to end of if statement.
870  			save_indirect_blocks(mfd, ibuf, iblk, NULL, sizeof(*dip));
871  		else if (height > 1)
(16) Event if_end: End of if statement.
872  			save_indirect_blocks(mfd, ibuf, iblk, &indq[0], sizeof(*dip));
873  	
(17) Event cond_false: Condition "i < height", taking false branch.
874  		for (unsigned i = 1; i < height; i++) {
875  			struct block_range_queue *nextq = &indq[i];
876  	
877  			if (!is_exhash && i == height - 1)
878  				nextq = NULL;
879  	
880  			/* Coverity can't figure out that the tail becomes NULL eventually. */
881  			/* coverity[loop_top:SUPPRESS] */
882  			while (indq[i - 1].tail != NULL) {
883  				struct block_range *q = block_range_queue_pop(&indq[i - 1]);
884  	
885  				for (unsigned j = 0; j < q->len; j++) {
886  					char *_buf = q->buf + (j * sbd.sd_bsize);
887  	
888  					save_indirect_blocks(mfd, _buf, iblk, nextq, sizeof(dip->di_header));
889  				}
890  				report_progress(q->start + q->len, 0);
891  				block_range_free(&q);
892  			}
(18) Event loop_end: Reached end of loop.
893  		}
(19) Event cond_true: Condition "is_exhash", taking true branch.
894  		if (is_exhash)
895  			save_leaf_blocks(mfd, &indq[height - 1]);
(20) Event cond_true: Condition "dip->di_eattr", taking true branch.
896  		if (dip->di_eattr) { /* if this inode has extended attributes */
897  			size_t blklen;
898  			uint64_t blk;
899  			int mhtype;
900  			char *buf;
901  	
902  			blk = be64_to_cpu(dip->di_eattr);
(21) Event tainted_return_value: Function "check_read_block" returns tainted data. [details]
(22) Event var_assign: Assigning: "buf" = "check_read_block(sbd.device_fd, blk, iblk, &mhtype, &blklen)", which taints "buf".
Also see events: [tainted_data][remediation]
903  			buf = check_read_block(sbd.device_fd, blk, iblk, &mhtype, &blklen);
(23) Event cond_true: Condition "buf != NULL", taking true branch.
904  			if (buf != NULL) {
905  				save_buf(mfd, buf, blk, blklen);
(24) Event cond_true: Condition "mhtype == 10", taking true branch.
906  				if (mhtype == GFS2_METATYPE_EA)
(25) Event tainted_data: Passing tainted expression "*buf" to "save_ea_block", which uses it as a loop boundary. [details]
(26) Event remediation: Ensure that tainted values are properly sanitized, by checking that their values are within a permissible range.
Also see events: [tainted_return_value][var_assign]
907  					save_ea_block(mfd, buf, iblk);
908  				else if (mhtype == GFS2_METATYPE_IN)
909  					save_indirect_blocks(mfd, buf, iblk, NULL, sizeof(dip->di_header));
910  				free(buf);
911  			}
912  		}
913  	}
914  	
915  	static void get_journal_inode_blocks(void)
916  	{
917  		int journal;
918  	
919  		journals_found = 0;
920  		memset(journal_blocks, 0, sizeof(journal_blocks));
921  		/* Save off all the journals--but only the metadata.
922  		 * This is confusing so I'll explain.  The journals contain important 
923  		 * metadata.  However, in gfs2 the journals are regular files within
924  		 * the system directory.  Since they're regular files, the blocks
925  		 * within the journals are considered data, not metadata.  Therefore,
926  		 * they won't have been saved by the code above.  We want to dump
927  		 * these blocks, but we have to be careful.  We only care about the
928  		 * journal blocks that look like metadata, and we need to not save
929  		 * journaled user data that may exist there as well. */
930  		for (journal = 0; ; journal++) { /* while journals exist */
931  			uint64_t jblock;
932  	
933  			if (journal + 3 > indirect->ii[0].dirents)
934  				break;
935  			jblock = indirect->ii[0].dirent[journal + 2].inum.in_addr;
936  			journal_blocks[journals_found++] = jblock;
937  		}
938  	}
939  	
940  	static void save_allocated_range(struct metafd *mfd, struct block_range *br)
941  	{
942  		if (check_read_range(sbd.device_fd, br, 0) != 0)
943  			return;
944  	
945  		save_range(mfd, br);
946  		for (unsigned i = 0; i < br->len; i++) {
947  			char *buf = br->buf + (i * sbd.sd_bsize);
948  	
949  			if (br->blktype[i] == GFS2_METATYPE_DI)
950  				save_inode_data(mfd, buf, br->start + i);
951  		}
952  		free(br->buf);
953  	}
954  	
955  	static int uint64_cmp(const void *_a, const void *_b)
956  	{
957  		const uint64_t a = *(uint64_t *)_a, b = *(uint64_t *)_b;
958  	
959  		return (a < b) ? -1 : ((a > b) ? 1 : 0);
960  	}
961  	
962  	static void save_allocated(struct lgfs2_rgrp_tree *rgd, struct metafd *mfd)
963  	{
964  		uint64_t blk = 0;
965  		unsigned i, j, m, n;
966  		uint64_t *ibuf = malloc(sbd.sd_bsize * GFS2_NBBY * sizeof(uint64_t));
967  	
968  		for (i = 0; i < rgd->rt_length; i++) {
969  			struct block_range br = {0};
970  	
971  			/* Dump linked as well as unlinked inodes. */
972  			m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_DINODE);
973  			n = lgfs2_bm_scan(rgd, i, ibuf + m, GFS2_BLKST_UNLINKED);
974  			if (m && n)
975  				qsort(ibuf, m + n, sizeof(*ibuf), uint64_cmp);
976  	
977  			for (j = 0; j < m + n; j++) {
978  				blk = ibuf[j];
979  				if (br.start == 0) {
980  					br.start = blk;
981  					br.len = 1;
982  				} else if (blk == br.start + br.len) {
983  					br.len++;
984  				} else {
985  					save_allocated_range(mfd, &br);
986  					br.start = blk;
987  					br.len = 1;
988  				}
989  				report_progress(blk, 0);
990  			}
991  			if (br.start != 0)
992  				save_allocated_range(mfd, &br);
993  		}
994  		free(ibuf);
995  	}
996  	
997  	static char *rgrp_read(struct lgfs2_sbd *sdp, uint64_t addr, unsigned blocks)
998  	{
999  		size_t len = blocks * sdp->sd_bsize;
1000 		off_t off = addr * sdp->sd_bsize;
1001 		char *buf;
1002 	
1003 		if (blocks == 0 || lgfs2_check_range(sdp, addr))
1004 			return NULL;
1005 	
1006 		buf = calloc(1, len);
1007 		if (buf == NULL)
1008 			return NULL;
1009 	
1010 		if (pread(sdp->device_fd, buf, len, off) != len) {
1011 			free(buf);
1012 			return NULL;
1013 		}
1014 		return buf;
1015 	}
1016 	
1017 	static void save_rgrp(struct lgfs2_sbd *sdp, struct metafd *mfd, struct lgfs2_rgrp_tree *rgd, int withcontents)
1018 	{
1019 		uint64_t addr = rgd->rt_addr;
1020 		char *buf;
1021 	
1022 		buf = rgrp_read(sdp, rgd->rt_addr, rgd->rt_length);
1023 		if (buf == NULL)
1024 			return;
1025 	
1026 		for (unsigned i = 0; i < rgd->rt_length; i++)
1027 			rgd->rt_bits[i].bi_data = buf + (i * sdp->sd_bsize);
1028 	
1029 		log_debug("RG at %"PRIu64" is %"PRIu32" long\n", addr, rgd->rt_length);
1030 		/* Save the rg and bitmaps */
1031 		for (unsigned i = 0; i < rgd->rt_length; i++) {
1032 			report_progress(rgd->rt_addr + i, 0);
1033 			save_buf(mfd, buf + (i * sdp->sd_bsize), rgd->rt_addr + i, sdp->sd_bsize);
1034 		}
1035 		/* Save the other metadata: inodes, etc. if mode is not 'savergs' */
1036 		if (withcontents)
1037 			save_allocated(rgd, mfd);
1038 	
1039 		free(buf);
1040 		for (unsigned i = 0; i < rgd->rt_length; i++)
1041 			rgd->rt_bits[i].bi_data = NULL;
1042 	}
1043 	
1044 	static int save_header(struct metafd *mfd, uint64_t fsbytes)
1045 	{
1046 		struct savemeta_header smh = {
1047 			.sh_magic = cpu_to_be32(SAVEMETA_MAGIC),
1048 			.sh_format = cpu_to_be32(SAVEMETA_FORMAT),
1049 			.sh_time = cpu_to_be64(time(NULL)),
1050 			.sh_fs_bytes = cpu_to_be64(fsbytes)
1051 		};
1052 	
1053 		if (savemetawrite(mfd, (char *)(&smh), sizeof(smh)) != sizeof(smh))
1054 			return -1;
1055 		return 0;
1056 	}
1057 	
1058 	static int parse_header(char *buf, struct savemeta *sm)
1059 	{
1060 		struct savemeta_header *smh = (void *)buf;
1061 	
1062 		if (be32_to_cpu(smh->sh_magic) != SAVEMETA_MAGIC) {
1063 			printf("No valid file header found. Falling back to old format...\n");
1064 			return 1;
1065 		}
1066 		if (be32_to_cpu(smh->sh_format) > SAVEMETA_FORMAT) {
1067 			printf("This version of gfs2_edit is too old to restore this metadata format.\n");
1068 			return -1;
1069 		}
1070 		sm->sm_format = be32_to_cpu(smh->sh_format);
1071 		sm->sm_time = be64_to_cpu(smh->sh_time);
1072 		sm->sm_fs_bytes = be64_to_cpu(smh->sh_fs_bytes);
1073 		printf("Metadata saved at %s", ctime(&sm->sm_time)); /* ctime() adds \n */
1074 		printf("File system size %.2fGB\n", sm->sm_fs_bytes / ((float)(1 << 30)));
1075 		return 0;
1076 	}
1077 	
1078 	void savemeta(char *out_fn, int saveoption, int gziplevel)
1079 	{
1080 		struct metafd mfd;
1081 		struct osi_node *n;
1082 		uint64_t sb_addr;
1083 		int err = 0;
1084 		char *buf;
1085 	
1086 		sbd.md.journals = 1;
1087 	
1088 		mfd = savemetaopen(out_fn, gziplevel);
1089 	
1090 		blks_saved = 0;
1091 		printf("There are %"PRIu64" blocks of %u bytes in the filesystem.\n",
1092 		       sbd.fssize, sbd.sd_bsize);
1093 	
1094 		printf("Filesystem size: %.2fGB\n", (sbd.fssize * sbd.sd_bsize) / ((float)(1 << 30)));
1095 		get_journal_inode_blocks();
1096 	
1097 		err = init_per_node_lookup();
1098 		if (err)
1099 			exit(1);
1100 	
1101 		/* Write the savemeta file header */
1102 		err = save_header(&mfd, sbd.fssize * sbd.sd_bsize);
1103 		if (err) {
1104 			perror("Failed to write metadata file header");
1105 			exit(1);
1106 		}
1107 		/* Save off the superblock */
1108 		sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sbd.sd_bsize;
1109 		buf = check_read_block(sbd.device_fd, sb_addr, 0, NULL, NULL);
1110 		if (buf != NULL) {
1111 			save_buf(&mfd, buf, sb_addr, sizeof(struct gfs2_sb));
1112 			free(buf);
1113 		}
1114 		/* Walk through the resource groups saving everything within */
1115 		for (n = osi_first(&sbd.rgtree); n; n = osi_next(n)) {
1116 			struct lgfs2_rgrp_tree *rgd;
1117 	
1118 			rgd = (struct lgfs2_rgrp_tree *)n;
1119 			save_rgrp(&sbd, &mfd, rgd, (saveoption != 2));
1120 		}
1121 		/* Clean up */
1122 		/* There may be a gap between end of file system and end of device */
1123 		/* so we tell the user that we've processed everything. */
1124 		report_progress(sbd.fssize, 1);
1125 		printf("\nMetadata saved to file %s ", mfd.filename);
1126 		if (mfd.gziplevel) {
1127 			printf("(gzipped, level %d).\n", mfd.gziplevel);
1128 		} else {
1129 			printf("(uncompressed).\n");
1130 		}
1131 		savemetaclose(&mfd);
1132 		close(sbd.device_fd);
1133 		destroy_per_node_lookup();
1134 		free(indirect);
1135 		lgfs2_rgrp_free(&sbd, &sbd.rgtree);
1136 		exit(0);
1137 	}
1138 	
1139 	static char *restore_block(struct metafd *mfd, uint64_t *blk, uint16_t *siglen)
1140 	{
1141 		struct saved_metablock *svb;
1142 		const char *errstr;
1143 		char *buf = NULL;
1144 	
1145 		svb = (struct saved_metablock *)(restore_buf_next(mfd, sizeof(*svb)));
1146 		if (svb == NULL)
1147 			goto nobuffer;
1148 		*blk = be64_to_cpu(svb->blk);
1149 		*siglen = be16_to_cpu(svb->siglen);
1150 	
1151 		if (sbd.fssize && *blk >= sbd.fssize) {
1152 			fprintf(stderr, "Error: File system is too small to restore this metadata.\n");
1153 			fprintf(stderr, "File system is %"PRIu64" blocks. Restore block = %"PRIu64"\n",
1154 			        sbd.fssize, *blk);
1155 			return NULL;
1156 		}
1157 	
1158 		if (*siglen > sbd.sd_bsize) {
1159 			fprintf(stderr, "Bad record length: %u for block %"PRIu64" (0x%"PRIx64").\n",
1160 				*siglen, *blk, *blk);
1161 			return NULL;
1162 		}
1163 	
1164 		buf = restore_buf_next(mfd, *siglen);
1165 		if (buf != NULL) {
1166 			return buf;
1167 		}
1168 	nobuffer:
1169 		if (mfd->eof)
1170 			return NULL;
1171 	
1172 		errstr = mfd->strerr(mfd);
1173 		fprintf(stderr, "Failed to restore block: %s\n", errstr);
1174 		return NULL;
1175 	}
1176 	
1177 	static int restore_super(struct metafd *mfd, void *buf, int printonly)
1178 	{
1179 		int ret;
1180 	
1181 		lgfs2_sb_in(&sbd, buf);
1182 		ret = lgfs2_check_sb(buf);
1183 		if (ret < 0) {
1184 			fprintf(stderr, "Error: Invalid superblock in metadata file.\n");
1185 			return -1;
1186 		}
1187 		if ((!printonly) && lgfs2_sb_write(&sbd, sbd.device_fd)) {
1188 			fprintf(stderr, "Failed to write superblock\n");
1189 			return -1;
1190 		}
1191 		blks_saved++;
1192 		return 0;
1193 	}
1194 	
1195 	static int restore_data(int fd, struct metafd *mfd, int printonly)
1196 	{
1197 		uint64_t writes = 0;
1198 		char *buf;
1199 	
1200 		buf = calloc(1, sbd.sd_bsize);
1201 		if (buf == NULL) {
1202 			perror("Failed to restore data");
1203 			exit(1);
1204 		}
1205 	
1206 		while (TRUE) {
1207 			uint16_t siglen = 0;
1208 			uint64_t blk = 0;
1209 			char *bp;
1210 	
1211 			bp = restore_block(mfd, &blk, &siglen);
1212 			if (bp == NULL && mfd->eof)
1213 				break;
1214 			if (bp == NULL) {
1215 				free(buf);
1216 				return -1;
1217 			}
1218 			if (printonly) {
1219 				if (printonly > 1 && printonly == blk) {
1220 					display_block_type(bp, blk, TRUE);
1221 					display_gfs2(bp);
1222 					break;
1223 				} else if (printonly == 1) {
1224 					print_gfs2("%"PRId64" (l=0x%x): ", blks_saved, siglen);
1225 					display_block_type(bp, blk, TRUE);
1226 				}
1227 			} else {
1228 				report_progress(blk, 0);
1229 				memcpy(buf, bp, siglen);
1230 				memset(buf + siglen, 0, sbd.sd_bsize - siglen);
1231 				if (pwrite(fd, buf, sbd.sd_bsize, blk * sbd.sd_bsize) != sbd.sd_bsize) {
1232 					fprintf(stderr, "write error: %s from %s:%d: block %"PRIu64" (0x%"PRIx64")\n",
1233 						strerror(errno), __FUNCTION__, __LINE__, blk, blk);
1234 					free(buf);
1235 					return -1;
1236 				}
1237 				writes++;
1238 				if (writes % 1000 == 0)
1239 					fsync(fd);
1240 			}
1241 			blks_saved++;
1242 		}
1243 		if (!printonly)
1244 			report_progress(sbd.fssize, 1);
1245 		free(buf);
1246 		return 0;
1247 	}
1248 	
1249 	static void restoremeta_usage(void)
1250 	{
1251 		fprintf(stderr, "Usage:\n");
1252 		fprintf(stderr, "gfs2_edit restoremeta <metadata_file> <block_device>\n");
1253 	}
1254 	
1255 	static int restore_init(const char *path, struct metafd *mfd, struct savemeta *sm, int printonly)
1256 	{
1257 		struct gfs2_sb rsb;
1258 		uint16_t sb_siglen;
1259 		char *end;
1260 		char *bp;
1261 		int ret;
1262 	
1263 		blks_saved = 0;
1264 		restore_buf = malloc(RESTORE_BUF_SIZE);
1265 		if (restore_buf == NULL) {
1266 			perror("Restore failed");
1267 			return -1;
1268 		}
1269 		restore_off = 0;
1270 		restore_left = 0;
1271 	
1272 		mfd->filename = path;
1273 		mfd->fd = open(path, O_RDONLY|O_CLOEXEC);
1274 		if (mfd->fd < 0) {
1275 			perror("Could not open metadata file");
1276 			return 1;
1277 		}
1278 		if (restore_try_bzip(mfd) != 0 &&
1279 		    restore_try_gzip(mfd) != 0) {
1280 			fprintf(stderr, "Failed to read metadata file header and superblock\n");
1281 			return -1;
1282 		}
1283 		bp = restore_buf;
1284 		ret = parse_header(bp, sm);
1285 		if (ret == 0) {
1286 			bp = restore_buf + sizeof(struct savemeta_header);
1287 			restore_off = sizeof(struct savemeta_header);
1288 		} else if (ret == -1) {
1289 			return -1;
1290 		}
1291 		/* Scan for the position of the superblock. Required to support old formats(?). */
1292 		end = &restore_buf[256 + sizeof(struct saved_metablock) + sizeof(struct gfs2_meta_header)];
1293 		while (bp <= end) {
1294 			memcpy(&rsb, bp + sizeof(struct saved_metablock), sizeof(rsb));
1295 			sb_siglen = be16_to_cpu(((struct saved_metablock *)bp)->siglen);
1296 			if (be32_to_cpu(rsb.sb_header.mh_magic) == GFS2_MAGIC &&
1297 			    be32_to_cpu(rsb.sb_header.mh_type) == GFS2_METATYPE_SB)
1298 				break;
1299 			bp++;
1300 		}
1301 		if (bp > end) {
1302 			fprintf(stderr, "No superblock found in metadata file\n");
1303 			return -1;
1304 		}
1305 		bp += sizeof(struct saved_metablock);
1306 		ret = restore_super(mfd, &rsb, printonly);
1307 		if (ret != 0)
1308 			return ret;
1309 	
1310 		if (sm->sm_fs_bytes > 0) {
1311 			sbd.fssize = sm->sm_fs_bytes / sbd.sd_bsize;
1312 			printf("Saved file system size is %"PRIu64" blocks, %.2fGB\n",
1313 			       sbd.fssize, sm->sm_fs_bytes / ((float)(1 << 30)));
1314 		}
1315 		printf("Block size is %uB\n", sbd.sd_bsize);
1316 		printf("This is gfs2 metadata.\n");
1317 		if (printonly > 1 && printonly == LGFS2_SB_ADDR(&sbd)) {
1318 			display_block_type(bp, LGFS2_SB_ADDR(&sbd), TRUE);
1319 			display_gfs2(bp);
1320 		} else if (printonly == 1) {
1321 			print_gfs2("0 (l=0x%x): ", sb_siglen);
1322 			display_block_type(bp, LGFS2_SB_ADDR(&sbd), TRUE);
1323 		}
1324 		bp += sb_siglen;
1325 		restore_off = bp - restore_buf;
1326 		restore_left -= restore_off;
1327 		return 0;
1328 	}
1329 	
1330 	void restoremeta(const char *in_fn, const char *out_device, uint64_t printonly)
1331 	{
1332 		struct metafd mfd = {0};
1333 		struct savemeta sm = {0};
1334 		struct stat st;
1335 		int error;
1336 	
1337 		termlines = 0;
1338 		if (in_fn == NULL || in_fn[0] == '\0') {
1339 			fprintf(stderr, "No source file specified.");
1340 			restoremeta_usage();
1341 			exit(1);
1342 		}
1343 		if (!printonly && (out_device == NULL || out_device[0] == '\0')) {
1344 			fprintf(stderr, "No destination file system specified.");
1345 			restoremeta_usage();
1346 			exit(1);
1347 		}
1348 		if (!printonly) {
1349 			sbd.device_fd = open(out_device, O_RDWR);
1350 			if (sbd.device_fd < 0) {
1351 				fprintf(stderr, "Failed to open target '%s': %s\n",
1352 				    out_device, strerror(errno));
1353 				exit(1);
1354 			}
1355 		} else if (out_device) /* for printsavedmeta, the out_device is an
1356 					  optional block no */
1357 			printonly = check_keywords(out_device);
1358 	
1359 		error = restore_init(in_fn, &mfd, &sm, printonly);
1360 		if (error != 0)
1361 			exit(error);
1362 	
1363 		if (!printonly) {
1364 			uint64_t space = lseek(sbd.device_fd, 0, SEEK_END) / sbd.sd_bsize;
1365 			printf("There are %"PRIu64" free blocks on the destination device.\n", space);
1366 		}
1367 	
1368 		error = restore_data(sbd.device_fd, &mfd, printonly);
1369 	
1370 		/* When there is a metadata header available, truncate to filesystem 
1371 		   size if our device_fd is a regular file */   
1372 		if (!printonly) {
1373 			if (fstat(sbd.device_fd, &st) == -1) {
1374 				fprintf(stderr, "Failed to stat %s: %s\n", out_device, strerror(errno));
1375 				error = errno;
1376 			}
1377 		
1378 			if (sm.sm_fs_bytes > 0 && S_ISREG(st.st_mode)) {
1379 				if (ftruncate(sbd.device_fd, sm.sm_fs_bytes) != 0) {
1380 					fprintf(stderr, "Failed to truncate: %s, %s\n", out_device, strerror(errno));
1381 					error = errno;
1382 				}
1383 			}
1384 		}
1385 	
1386 		printf("File %s %s %s.\n", in_fn,
1387 		       (printonly ? "print" : "restore"),
1388 		       (error ? "error" : "successful"));
1389 	
1390 		mfd.close(&mfd);
1391 		if (!printonly)
1392 			close(sbd.device_fd);
1393 		free(indirect);
1394 		exit(error);
1395 	}
1396