This is an automated email from the git hooks/post-receive script.
andyp pushed a commit to branch master
in repository gfs2-utils.
commit 4a262bd74b46e2172ee287f91cedf92781fd51ec
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu May 7 00:32:34 2020 +0100
savemeta: Save rgrps without using gfs2_buffer_heads
Separate the block saving code from save_bh out into save_buf so that
the resource groups can be dumped without using a temporary
gfs2_buffer_head. The rgrp saving code has also been tidied up.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/edit/savemeta.c | 123 +++++++++++++++++++++++++--------------------------
1 file changed, 61 insertions(+), 62 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 11c8355..f8f3312 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -527,23 +527,13 @@ static int savemetaclose(struct metafd *mfd)
return close(mfd->fd);
}
-static int save_bh(struct metafd *mfd, struct gfs2_buffer_head *savebh, uint64_t owner,
int *blktype)
+static int save_buf(struct metafd *mfd, char *buf, uint64_t addr, unsigned blklen)
{
struct saved_metablock *savedata;
- size_t blklen;
size_t outsz;
- /* If this isn't metadata and isn't a system file, we don't want it.
- Note that we're checking "owner" here rather than blk. That's
- because we want to know if the source inode is a system inode
- not the block within the inode "blk". They may or may not
- be the same thing. */
- if (get_gfs_struct_info(savebh, owner, blktype, &blklen) &&
- !block_is_systemfile(owner) && owner != 0)
- return 0; /* Not metadata, and not system file, so skip it */
-
/* No need to save trailing zeroes */
- for (; blklen > 0 && savebh->b_data[blklen - 1] == '\0';
blklen--);
+ for (; blklen > 0 && buf[blklen - 1] == '\0'; blklen--);
if (blklen == 0) /* No significant data; skip. */
return 0;
@@ -554,34 +544,45 @@ static int save_bh(struct metafd *mfd, struct gfs2_buffer_head
*savebh, uint64_t
perror("Failed to save block");
exit(1);
}
- savedata->blk = cpu_to_be64(savebh->b_blocknr);
+ savedata->blk = cpu_to_be64(addr);
savedata->siglen = cpu_to_be16(blklen);
- memcpy(savedata + 1, savebh->b_data, blklen);
+ memcpy(savedata + 1, buf, blklen);
if (savemetawrite(mfd, savedata, outsz) != outsz) {
- fprintf(stderr, "write error: %s from %s:%d: block %lld (0x%llx)\n",
- strerror(errno), __FUNCTION__, __LINE__,
- (unsigned long long)savedata->blk,
- (unsigned long long)savedata->blk);
+ fprintf(stderr, "write error: %s from %s:%d: block %"PRIu64"\n",
+ strerror(errno), __FUNCTION__, __LINE__, addr);
free(savedata);
exit(-1);
}
-
blks_saved++;
free(savedata);
return 0;
}
+static int save_bh(struct metafd *mfd, struct gfs2_buffer_head *savebh, uint64_t owner,
int *blktype)
+{
+ size_t blklen;
+
+ /* If this isn't metadata and isn't a system file, we don't want it.
+ Note that we're checking "owner" here rather than blk. That's
+ because we want to know if the source inode is a system inode
+ not the block within the inode "blk". They may or may not
+ be the same thing. */
+ if (get_gfs_struct_info(savebh, owner, blktype, &blklen) &&
+ !block_is_systemfile(owner) && owner != 0)
+ return 0; /* Not metadata, and not system file, so skip it */
+
+ return save_buf(mfd, savebh->b_data, savebh->b_blocknr, blklen);
+}
+
static int save_block(int fd, struct metafd *mfd, uint64_t blk, uint64_t owner, int
*blktype)
{
struct gfs2_buffer_head *savebh;
int err;
if (gfs2_check_range(&sbd, blk) && blk != LGFS2_SB_ADDR(&sbd)) {
- fprintf(stderr, "\nWarning: bad block pointer '0x%llx' "
- "ignored in block (block %llu (0x%llx))",
- (unsigned long long)blk,
- (unsigned long long)owner, (unsigned long long)owner);
+ fprintf(stderr, "Warning: bad pointer 0x%"PRIx64" ignored in block
0x%"PRIx64"\n",
+ blk, owner);
return 0;
}
savebh = bread(&sbd, blk);
@@ -595,7 +596,7 @@ static int save_block(int fd, struct metafd *mfd, uint64_t blk,
uint64_t owner,
/*
* save_ea_block - save off an extended attribute block
*/
-static void save_ea_block(struct metafd *mfd, struct gfs2_buffer_head *metabh, uint64_t
owner)
+static void save_ea_block(struct metafd *mfd, char *buf, uint64_t owner)
{
int e;
struct gfs2_ea_header ea;
@@ -604,13 +605,13 @@ static void save_ea_block(struct metafd *mfd, struct
gfs2_buffer_head *metabh, u
uint64_t blk, *b;
int charoff, i;
- gfs2_ea_header_in(&ea, metabh->b_data + e);
+ gfs2_ea_header_in(&ea, buf + e);
for (i = 0; i < ea.ea_num_ptrs; i++) {
charoff = e + ea.ea_name_len +
sizeof(struct gfs2_ea_header) +
sizeof(uint64_t) - 1;
charoff /= sizeof(uint64_t);
- b = (uint64_t *)(metabh->b_data);
+ b = (uint64_t *)buf;
b += charoff + i;
blk = be64_to_cpu(*b);
save_block(sbd.device_fd, mfd, blk, owner, NULL);
@@ -646,7 +647,7 @@ static void save_indirect_blocks(struct metafd *mfd, osi_list_t
*cur_list,
save_block(sbd.device_fd, mfd, indir_block, owner, &blktype);
if (blktype == GFS2_METATYPE_EA) {
nbh = bread(&sbd, indir_block);
- save_ea_block(mfd, nbh, owner);
+ save_ea_block(mfd, nbh->b_data, owner);
brelse(nbh);
}
if (height != hgt && /* If not at max height and */
@@ -790,7 +791,7 @@ static void save_inode_data(struct metafd *mfd, uint64_t iblk)
gfs2_meta_header_in(&mh, lbh->b_data);
if (mh.mh_magic == GFS2_MAGIC &&
mh.mh_type == GFS2_METATYPE_EA)
- save_ea_block(mfd, lbh, iblk);
+ save_ea_block(mfd, lbh->b_data, iblk);
else if (mh.mh_magic == GFS2_MAGIC &&
mh.mh_type == GFS2_METATYPE_IN)
save_indirect_blocks(mfd, cur_list, lbh, iblk, 2, 2);
@@ -853,7 +854,7 @@ static void get_journal_inode_blocks(void)
jblock = ji.ji_addr;
gfs1_journal_size = (uint64_t)ji.ji_nsegment * 16;
} else {
- if (journal > indirect->ii[0].dirents - 3)
+ if (journal + 3 > indirect->ii[0].dirents)
break;
jblock = indirect->ii[0].dirent[journal + 2].block;
}
@@ -878,7 +879,6 @@ static void save_allocated(struct rgrp_tree *rgd, struct metafd *mfd)
if (blktype == GFS2_METATYPE_DI)
save_inode_data(mfd, blk);
}
-
if (!sbd.gfs1)
continue;
@@ -892,57 +892,56 @@ static void save_allocated(struct rgrp_tree *rgd, struct metafd
*mfd)
free(ibuf);
}
-/* We don't use gfs2_rgrp_read() here as it checks for metadata sanity and we
- want to save rgrp headers even if they're corrupt. */
-static int rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
+static char *rgrp_read(struct gfs2_sbd *sdp, uint64_t addr, unsigned blocks)
{
- unsigned length = rgd->ri.ri_length * sdp->bsize;
- off_t off = rgd->ri.ri_addr * sdp->bsize;
+ size_t len = blocks * sdp->bsize;
+ off_t off = addr * sdp->bsize;
char *buf;
- if (length == 0 || gfs2_check_range(sdp, rgd->ri.ri_addr))
- return -1;
+ if (blocks == 0 || gfs2_check_range(sdp, addr))
+ return NULL;
- buf = calloc(1, length);
+ buf = calloc(1, len);
if (buf == NULL)
- return -1;
+ return NULL;
- if (pread(sdp->device_fd, buf, length, off) != length) {
+ if (pread(sdp->device_fd, buf, len, off) != len) {
free(buf);
- return -1;
+ return NULL;
}
- for (unsigned i = 0; i < rgd->ri.ri_length; i++)
- rgd->bits[i].bi_data = buf + (i * sdp->bsize);
-
- if (sdp->gfs1)
- gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_data);
- else
- gfs2_rgrp_in(&rgd->rg, rgd->bits[0].bi_data);
- return 0;
+ return buf;
}
-static void save_rgrp(struct metafd *mfd, struct rgrp_tree *rgd, int withcontents)
+static void save_rgrp(struct gfs2_sbd *sdp, struct metafd *mfd, struct rgrp_tree *rgd,
int withcontents)
{
uint64_t addr = rgd->ri.ri_addr;
- uint32_t i;
+ char *buf;
- if (rgrp_read(&sbd, rgd))
+ buf = rgrp_read(sdp, rgd->ri.ri_addr, rgd->ri.ri_length);
+ if (buf == NULL)
return;
- log_debug("RG at %"PRIu64" (0x%"PRIx64") is %u long\n",
- addr, addr, rgd->ri.ri_length);
+
+ if (sdp->gfs1)
+ gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, buf);
+ else
+ gfs2_rgrp_in(&rgd->rg, buf);
+
+ for (unsigned i = 0; i < rgd->ri.ri_length; i++)
+ rgd->bits[i].bi_data = buf + (i * sdp->bsize);
+
+ log_debug("RG at %"PRIu64" is %"PRIu32" long\n", addr,
(uint32_t)rgd->ri.ri_length);
/* Save the rg and bitmaps */
- for (i = 0; i < rgd->ri.ri_length; i++) {
- struct gfs2_buffer_head tmpbh = {
- .b_data = rgd->bits[i].bi_data,
- .b_blocknr = rgd->ri.ri_addr + i
- };
+ for (unsigned i = 0; i < rgd->ri.ri_length; i++) {
warm_fuzzy_stuff(rgd->ri.ri_addr + i, FALSE);
- save_bh(mfd, &tmpbh, 0, NULL);
+ save_buf(mfd, buf + (i * sdp->bsize), rgd->ri.ri_addr + i, sdp->bsize);
}
/* Save the other metadata: inodes, etc. if mode is not 'savergs' */
if (withcontents)
save_allocated(rgd, mfd);
- gfs2_rgrp_relse(&sbd, rgd);
+
+ free(buf);
+ for (unsigned i = 0; i < rgd->ri.ri_length; i++)
+ rgd->bits[i].bi_data = NULL;
}
static int save_header(struct metafd *mfd, uint64_t fsbytes)
@@ -1042,7 +1041,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
struct rgrp_tree *rgd;
rgd = (struct rgrp_tree *)n;
- save_rgrp(&mfd, rgd, (saveoption != 2));
+ save_rgrp(&sbd, &mfd, rgd, (saveoption != 2));
}
/* Clean up */
/* There may be a gap between end of file system and end of device */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.