cluster: RHEL6 - fsck.gfs2: four-step duplicate elimination process
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 7a55740823bc98268dc7765eb99f365e42f4803b
Parent: 02714254368e71d63e1804e05a4534d564d5f5cb
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Aug 11 12:25:38 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: four-step duplicate elimination process
This patch reforms the duplicate block reference processing by
introducing a new four-step duplicate elimination process.
Step 1. Delete inodes that reference the block and were previously
marked invalid.
Step 2. Delete inodes that reference the block as the wrong block
type. (Data block referenced as metadata, or vise versa)
Step 3. Delete inodes until we're down to a single reference.
Step 4. Fix the block type to be according to the remaining reference.
rhbz#675723
---
gfs2/fsck/pass1b.c | 280 ++++++++++++++++++++++++++++++++++++----------------
1 files changed, 196 insertions(+), 84 deletions(-)
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 67b8d14..a66bd8b 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -13,6 +13,10 @@
#include "metawalk.h"
#include "inode_hash.h"
+const char *reftype_str[ref_types + 1] = {"data", "metadata",
+ "extended attribute",
+ "unimportant"};
+
struct fxn_info {
uint64_t block;
int found;
@@ -365,25 +369,38 @@ static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
return error;
}
+/* get_ref_type - figure out if all duplicate references from this inode
+ are the same type, and if so, return the type. */
+static enum dup_ref_type get_ref_type(struct inode_with_dups *id)
+{
+ if (id->reftypecount[ref_as_ea] &&
+ !id->reftypecount[ref_as_data] &&
+ !id->reftypecount[ref_as_meta])
+ return ref_as_ea;
+ if (!id->reftypecount[ref_as_ea] &&
+ id->reftypecount[ref_as_data] &&
+ !id->reftypecount[ref_as_meta])
+ return ref_as_data;
+ if (!id->reftypecount[ref_as_ea] &&
+ !id->reftypecount[ref_as_data] &&
+ id->reftypecount[ref_as_meta])
+ return ref_as_meta;
+ return ref_types; /* multiple references */
+}
+
static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
{
char reftypestring[32];
struct inode_with_dups *id;
id = osi_list_entry(tmp, struct inode_with_dups, list);
- if (id->dup_count == 1) {
- if (id->reftypecount[ref_as_data])
- strcpy(reftypestring, "as data");
- else if (id->reftypecount[ref_as_meta])
- strcpy(reftypestring, "as metadata");
- else
- strcpy(reftypestring, "as extended attribute");
- } else {
+ if (id->dup_count == 1)
+ sprintf(reftypestring, "as %s", reftype_str[get_ref_type(id)]);
+ else
sprintf(reftypestring, "%d/%d/%d",
id->reftypecount[ref_as_data],
id->reftypecount[ref_as_meta],
id->reftypecount[ref_as_ea]);
- }
if (inval)
log_warn( _("Invalid "));
log_warn( _("Inode %s (%lld/0x%llx) has %d reference(s) to "
@@ -393,10 +410,22 @@ static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
(unsigned long long)b->block,
(unsigned long long)b->block, reftypestring);
}
-
-static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
- osi_list_t *ref_list, struct dup_handler *dh,
- int inval)
+/*
+ * resolve_dup_references - resolve all but the last dinode that has a
+ * duplicate reference to a given block.
+ *
+ * @sdp - pointer to the superblock structure
+ * @b - pointer to the duplicate reference rbtree to use
+ * @ref_list - list of duplicate references to be resolved (invalid or valid)
+ * @dh - duplicate handler
+ * inval - The references on this ref_list are invalid. We prefer to delete
+ * these first before resorting to deleting valid dinodes.
+ * acceptable_ref - Delete dinodes that reference the given block as anything
+ * _but_ this type. Try to save references as this type.
+ */
+static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
+ osi_list_t *ref_list, struct dup_handler *dh,
+ int inval, int acceptable_ref)
{
struct gfs2_inode *ip;
struct inode_with_dups *id;
@@ -412,26 +441,74 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
.check_eattr_entry = clear_eattr_entry,
.check_eattr_extentry = clear_eattr_extentry,
};
+ enum dup_ref_type this_ref;
+ struct inode_info *ii;
+ int found_good_ref = 0;
osi_list_foreach_safe(tmp, ref_list, x) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
dh->b = b;
dh->id = id;
+
if (dh->ref_inode_count == 1) /* down to the last reference */
return 1;
- if (!(query( _("Okay to clear %s inode %lld (0x%llx)? (y/n) "),
+
+ this_ref = get_ref_type(id);
+ if (inval)
+ log_warn( _("Invalid "));
+ /* FIXME: If we already found an acceptable reference to this
+ * block, we should really duplicate the block and fix all
+ * references to it in this inode. Unfortunately, we would
+ * have to traverse the entire metadata tree to do that. */
+ if (acceptable_ref != ref_types && /* If we're nuking all but
+ an acceptable reference
+ type and */
+ this_ref == acceptable_ref && /* this ref is acceptable */
+ !found_good_ref) { /* We haven't found a good reference */
+ uint8_t q;
+
+ /* If this is an invalid inode, but not on the invalid
+ list, it's better to delete it. */
+ q = block_type(id->block_no);
+ if (q != gfs2_inode_invalid) {
+ found_good_ref = 1;
+ continue; /* don't delete the dinode */
+ }
+ }
+
+ log_warn( _("Inode %s (%lld/0x%llx) references block "
+ "%llu (0x%llx) as '%s', but the block is "
+ "really %s.\n"),
+ id->name, (unsigned long long)id->block_no,
+ (unsigned long long)id->block_no,
+ (unsigned long long)b->block,
+ (unsigned long long)b->block,
+ reftype_str[this_ref],
+ reftype_str[acceptable_ref]);
+ if (!(query( _("Okay to delete %s inode %lld (0x%llx)? "
+ "(y/n) "),
(inval ? _("invalidated") : ""),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no))) {
- log_warn( _("The bad inode was not cleared...\n"));
+ log_warn( _("The bad inode was not cleared."));
+ /* delete the list entry so we don't leak memory but
+ leave the reference count. If the decrement the
+ ref count, we could get down to 1 and the dinode
+ would be changed without a 'Yes' answer. */
+ /* (dh->ref_inode_count)--;*/
+ dup_listent_delete(id);
continue;
}
log_warn( _("Clearing inode %lld (0x%llx)...\n"),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no);
+
+ ip = fsck_load_inode(sdp, id->block_no);
+ ii = inodetree_find(ip->i_di.di_num.no_addr);
+ if (ii)
+ inodetree_delete(ii);
clear_dup_fxns.private = (void *) dh;
/* Clear the EAs for the inode first */
- ip = fsck_load_inode(sdp, id->block_no);
check_inode_eattr(ip, &clear_dup_fxns);
/* If the dup wasn't only in the EA, clear the inode */
if (id->reftypecount[ref_as_data] ||
@@ -439,13 +516,14 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
check_metatree(ip, &clear_dup_fxns);
fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
- _("bad"), gfs2_inode_invalid);
+ _("duplicate referencing bad"),
+ gfs2_inode_invalid);
fsck_inode_put(&ip); /* out, brelse, free */
(dh->ref_inode_count)--;
- /* Inode is marked invalid and is removed in pass2 */
/* FIXME: other option should be to duplicate the
* block for each duplicate and point the metadata at
* the cloned blocks */
+ dup_listent_delete(id);
}
if (dh->ref_inode_count == 1) /* down to the last reference */
return 1;
@@ -458,19 +536,56 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
osi_list_t *tmp;
struct inode_with_dups *id;
struct dup_handler dh = {0};
- int last_reference, ref_in_invalid_inode = 0;
+ int last_reference = 0;
+ struct gfs2_buffer_head *bh;
+ uint32_t cmagic, ctype;
+ enum dup_ref_type acceptable_ref;
+ /* Count the duplicate references, both valid and invalid */
osi_list_foreach(tmp, &b->ref_invinode_list) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
dh.ref_inode_count++;
dh.ref_count += id->dup_count;
- ref_in_invalid_inode = 1;
}
osi_list_foreach(tmp, &b->ref_inode_list) {
id = osi_list_entry(tmp, struct inode_with_dups, list);
dh.ref_inode_count++;
dh.ref_count += id->dup_count;
}
+
+ /* Log the duplicate references */
+ log_notice( _("Block %llu (0x%llx) has %d inodes referencing it"
+ " for a total of %d duplicate references:\n"),
+ (unsigned long long)b->block, (unsigned long long)b->block,
+ dh.ref_inode_count, dh.ref_count);
+
+ osi_list_foreach(tmp, &b->ref_invinode_list)
+ log_inode_reference(b, tmp, 1);
+ osi_list_foreach(tmp, &b->ref_inode_list)
+ log_inode_reference(b, tmp, 0);
+
+ /* Figure out the block type to see if we can eliminate references
+ to a different type. In other words, if the duplicate block looks
+ like metadata, we can delete dinodes that reference it as data.
+ If the block doesn't look like metadata, we can eliminate any
+ references to it as metadata. Dinodes with such references are
+ clearly corrupt and need to be deleted.
+ And if we're left with a single reference, problem solved. */
+ bh = bread(sdp, b->block);
+ cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
+ ctype = ((struct gfs2_meta_header *)(bh->b_data))->mh_type;
+ brelse(bh);
+
+ if (be32_to_cpu(cmagic) == GFS2_MAGIC &&
+ (be32_to_cpu(ctype) == GFS2_METATYPE_EA ||
+ be32_to_cpu(ctype) == GFS2_METATYPE_ED))
+ acceptable_ref = ref_as_ea;
+ else if (be32_to_cpu(cmagic) == GFS2_MAGIC &&
+ be32_to_cpu(ctype) <= GFS2_METATYPE_QC)
+ acceptable_ref = ref_as_meta;
+ else
+ acceptable_ref = ref_as_data;
+
/* A single reference to the block implies a possible situation where
a data pointer points to a metadata block. In other words, the
duplicate reference in the file system is (1) Metadata block X and
@@ -484,75 +599,71 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
invalidated for other reasons, such as bad pointers. So we need to
make sure at this point that any inode deletes reverse out any
duplicate reference before we get to this point. */
- if (dh.ref_count == 1) {
- struct gfs2_buffer_head *bh;
- uint32_t cmagic;
-
- bh = bread(sdp, b->block);
- cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
- brelse(bh);
- if (be32_to_cpu(cmagic) == GFS2_MAGIC) {
- if (ref_in_invalid_inode)
- tmp = b->ref_invinode_list.next;
- else
- tmp = b->ref_inode_list.next;
- id = osi_list_entry(tmp, struct inode_with_dups, list);
- log_warn( _("Inode %s (%lld/0x%llx) has a reference to"
- " data block %llu (0x%llx), "
- "but the block is really metadata.\n"),
- id->name, (unsigned long long)id->block_no,
- (unsigned long long)id->block_no,
- (unsigned long long)b->block,
- (unsigned long long)b->block);
- if (query( _("Clear the inode? (y/n) "))) {
- struct inode_info *ii;
-
- log_warn( _("Clearing inode %lld (0x%llx)...\n"),
- (unsigned long long)id->block_no,
- (unsigned long long)id->block_no);
- ip = fsck_load_inode(sdp, id->block_no);
- ii = inodetree_find(ip->i_di.di_num.no_addr);
- if (ii)
- inodetree_delete(ii);
- /* Setting the block to invalid means the inode
- is cleared in pass2 */
- fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
- _("inode with bad duplicate"),
- gfs2_inode_invalid);
- fsck_inode_put(&ip);
- } else {
- log_warn( _("The bad inode was not cleared."));
- }
- return 0;
- }
- /* The other references may have been discredited due to
- invalid metadata or something. Use the last remaining. */
- log_notice( _("Block %llu (0x%llx) has only one remaining "
- "reference.\n"),
+ if (dh.ref_count == 1)
+ last_reference = 1;
+
+ /* Step 1 - eliminate references from inodes that are not valid.
+ * This may be because they were deleted due to corruption.
+ * All block types are unacceptable, so we use ref_types.
+ */
+ if (!last_reference) {
+ log_debug( _("----------------------------------------------\n"
+ "Step 1: Eliminate references to block %llu "
+ "(0x%llx) that were previously marked "
+ "invalid.\n"),
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
+ last_reference = resolve_dup_references(sdp, b,
+ &b->ref_invinode_list,
+ &dh, 1, ref_types);
+ }
+ /* Step 2 - eliminate reference from inodes that reference it as the
+ * wrong type. For example, a data file referencing it as
+ * a data block, but it's really a metadata block. Or a
+ * directory inode referencing a data block as a leaf block.
+ */
+ if (!last_reference) {
+ last_reference = resolve_dup_references(sdp, b,
+ &b->ref_inode_list,
+ &dh, 0,
+ acceptable_ref);
+ log_debug( _("----------------------------------------------\n"
+ "Step 2: Eliminate references to block %llu "
+ "(0x%llx) that need the wrong block type.\n"),
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
+ }
+ /* Step 3 - We have multiple dinodes referencing it as the correct
+ * type. Just blast one of them.
+ * All block types are fair game, so we use ref_types.
+ */
+ if (!last_reference) {
+ log_debug( _("----------------------------------------------\n"
+ "Step 3: Choose one reference to block %llu "
+ "(0x%llx) to keep.\n"),
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
+ last_reference = resolve_dup_references(sdp, b,
+ &b->ref_inode_list,
+ &dh, 0, ref_types);
+ }
+ /* Now fix the block type of the block in question. */
+ if (osi_list_empty(&b->ref_inode_list)) {
+ log_notice( _("Block %llu (0x%llx) has no more references; "
+ "Marking as 'free'.\n"),
(unsigned long long)b->block,
(unsigned long long)b->block);
+ gfs2_blockmap_set(bl, b->block, gfs2_block_free);
+ check_n_fix_bitmap(sdp, b->block, gfs2_block_free);
return 0;
}
-
- log_notice( _("Block %llu (0x%llx) has %d inodes referencing it"
- " for a total of %d duplicate references\n"),
- (unsigned long long)b->block, (unsigned long long)b->block,
- dh.ref_inode_count, dh.ref_count);
-
- osi_list_foreach(tmp, &b->ref_invinode_list)
- log_inode_reference(b, tmp, 1);
- osi_list_foreach(tmp, &b->ref_inode_list)
- log_inode_reference(b, tmp, 0);
-
- last_reference = clear_a_reference(sdp, b, &b->ref_invinode_list,
- &dh, 1);
- if (!last_reference)
- last_reference = clear_a_reference(sdp, b, &b->ref_inode_list,
- &dh, 0);
-
- if (last_reference && !osi_list_empty(&b->ref_inode_list)) {
+ if (last_reference) {
uint8_t q;
+ log_notice( _("Block %llu (0x%llx) has only one remaining "
+ "reference.\n"),
+ (unsigned long long)b->block,
+ (unsigned long long)b->block);
/* If we're down to a single reference (and not all references
deleted, which may be the case of an inode that has only
itself and a reference), we need to reset the block type
@@ -560,7 +671,8 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
in the list, not the structure's place holder. */
tmp = (&b->ref_inode_list)->next;
id = osi_list_entry(tmp, struct inode_with_dups, list);
- log_debug( _("Resetting the type based on the remaining "
+ log_debug( _("----------------------------------------------\n"
+ "Step 4. Set block type based on the remaining "
"reference in inode %lld (0x%llx).\n"),
(unsigned long long)id->block_no,
(unsigned long long)id->block_no);
12 years, 3 months
cluster: RHEL6 - libgfs2: expand capabilities to operate on gfs1
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: e04c6a5aaa36e551c7d34e428edeb21d726c7ab4
Parent: 4459c39de938feec3e245805a96af83d6286c0e5
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 16:28:02 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: expand capabilities to operate on gfs1
This patch expands many of the libgfs2 functions so that they may
operate on gfs1 file systems, depending on the sdp->gfs1 variable.
rhbz#675723
---
gfs2/libgfs2/fs_ops.c | 113 +++++++++++++++++++++++++++++++++++--------
gfs2/libgfs2/gfs1.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/libgfs2.h | 17 ++++++-
gfs2/libgfs2/ondisk.c | 10 +++-
gfs2/libgfs2/rgrp.c | 9 ++-
5 files changed, 248 insertions(+), 27 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 6ffee9d..e99cc2a 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -177,7 +177,10 @@ found:
rg->rg_free--;
bmodified(bh);
- gfs2_rgrp_out(rg, rl->bh[0]);
+ if (sdp->gfs1)
+ gfs_rgrp_out((struct gfs_rgrp *)rg, rl->bh[0]);
+ else
+ gfs2_rgrp_out(rg, rl->bh[0]);
sdp->blks_alloced++;
return ri->ri_data0 + bn;
@@ -231,7 +234,7 @@ void unstuff_dinode(struct gfs2_inode *ip)
struct gfs2_sbd *sdp = ip->i_sbd;
struct gfs2_buffer_head *bh;
uint64_t block = 0;
- int isdir = !!(S_ISDIR(ip->i_di.di_mode));
+ int isdir = S_ISDIR(ip->i_di.di_mode) || is_gfs_dir(&ip->i_di);
if (ip->i_di.di_size) {
if (isdir) {
@@ -828,6 +831,8 @@ void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex,
uint64_t leaf_no;
int count;
+ if (dip->i_sbd->gfs1)
+ return gfs_get_leaf_nr(dip, lindex, leaf_out);
count = gfs2_readi(dip, (char *)&leaf_no, lindex * sizeof(uint64_t),
sizeof(uint64_t));
if (count != sizeof(uint64_t))
@@ -841,6 +846,10 @@ void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
uint64_t leaf_no;
int count;
+ if (dip->i_sbd->gfs1) {
+ gfs_put_leaf_nr(dip, inx, leaf_out);
+ return;
+ }
leaf_no = cpu_to_be64(leaf_out);
count = gfs2_writei(dip, (char *)&leaf_no, inx * sizeof(uint64_t),
sizeof(uint64_t));
@@ -891,8 +900,12 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
for (x = 0; x < half_len; x++)
lp[x] = cpu_to_be64(bn);
- count = gfs2_writei(dip, (char *)lp, start * sizeof(uint64_t),
- half_len * sizeof(uint64_t));
+ if (dip->i_sbd->gfs1)
+ count = gfs1_writei(dip, (char *)lp, start * sizeof(uint64_t),
+ half_len * sizeof(uint64_t));
+ else
+ count = gfs2_writei(dip, (char *)lp, start * sizeof(uint64_t),
+ half_len * sizeof(uint64_t));
if (count != half_len * sizeof(uint64_t))
die("dir_split_leaf (2)\n");
@@ -985,8 +998,14 @@ static void dir_double_exhash(struct gfs2_inode *dip)
*to++ = *from;
}
- count = gfs2_writei(dip, (char *)buf + sdp->sd_hash_bsize,
- block * sdp->bsize, sdp->bsize);
+ if (sdp->gfs1)
+ count = gfs1_writei(dip, (char *)buf +
+ sdp->sd_hash_bsize,
+ block * sdp->bsize, sdp->bsize);
+ else
+ count = gfs2_writei(dip, (char *)buf +
+ sdp->sd_hash_bsize,
+ block * sdp->bsize, sdp->bsize);
if (count != sdp->bsize)
die("dir_double_exhash (2)\n");
@@ -1235,13 +1254,21 @@ void dir_add(struct gfs2_inode *dip, const char *filename, int len,
dir_l_add(dip, filename, len, inum, type);
}
-struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
- struct gfs2_inum *inum, unsigned int mode,
- uint32_t flags, struct gfs2_inum *parent)
+static struct gfs2_buffer_head *__init_dinode(struct gfs2_sbd *sdp,
+ struct gfs2_inum *inum,
+ unsigned int mode,
+ uint32_t flags,
+ struct gfs2_inum *parent,
+ int gfs1)
{
struct gfs2_buffer_head *bh;
struct gfs2_dinode di;
+ int is_dir;
+ if (gfs1)
+ is_dir = (IF2DT(mode) == GFS_FILE_DIR);
+ else
+ is_dir = S_ISDIR(mode);
bh = bget(sdp, inum->no_addr);
memset(&di, 0, sizeof(struct gfs2_dinode));
@@ -1256,7 +1283,7 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
di.di_goal_meta = di.di_goal_data = bh->b_blocknr;
di.di_flags = flags;
- if (S_ISDIR(mode)) {
+ if (is_dir) {
struct gfs2_dirent de1, de2;
memset(&de1, 0, sizeof(struct gfs2_dirent));
@@ -1264,14 +1291,14 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
de1.de_hash = gfs2_disk_hash(".", 1);
de1.de_rec_len = GFS2_DIRENT_SIZE(1);
de1.de_name_len = 1;
- de1.de_type = IF2DT(S_IFDIR);
+ de1.de_type = (gfs1 ? GFS_FILE_DIR : IF2DT(S_IFDIR));
memset(&de2, 0, sizeof(struct gfs2_dirent));
de2.de_inum = *parent;
de2.de_hash = gfs2_disk_hash("..", 2);
de2.de_rec_len = sdp->bsize - sizeof(struct gfs2_dinode) - de1.de_rec_len;
de2.de_name_len = 2;
- de2.de_type = IF2DT(S_IFDIR);
+ de2.de_type = (gfs1 ? GFS_FILE_DIR : IF2DT(S_IFDIR));
gfs2_dirent_out(&de1, bh->b_data + sizeof(struct gfs2_dinode));
memcpy(bh->b_data +
@@ -1297,30 +1324,56 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
return bh;
}
-struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
- unsigned int mode, uint32_t flags)
+struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
+ struct gfs2_inum *inum,
+ unsigned int mode, uint32_t flags,
+ struct gfs2_inum *parent)
+{
+ return __init_dinode(sdp, inum, mode, flags, parent, 0);
+}
+
+struct gfs2_buffer_head *init_gfs_dinode(struct gfs2_sbd *sdp,
+ struct gfs2_inum *inum,
+ unsigned int mode, uint32_t flags,
+ struct gfs2_inum *parent)
+{
+ return __init_dinode(sdp, inum, mode, flags, parent, 1);
+}
+
+static struct gfs2_inode *__createi(struct gfs2_inode *dip,
+ const char *filename, unsigned int mode,
+ uint32_t flags, int if_gfs1)
{
struct gfs2_sbd *sdp = dip->i_sbd;
uint64_t bn;
struct gfs2_inum inum;
struct gfs2_buffer_head *bh;
struct gfs2_inode *ip;
+ int is_dir;
gfs2_lookupi(dip, filename, strlen(filename), &ip);
if (!ip) {
bn = dinode_alloc(sdp);
- inum.no_formal_ino = sdp->md.next_inum++;
+ if (if_gfs1)
+ inum.no_formal_ino = bn;
+ else
+ inum.no_formal_ino = sdp->md.next_inum++;
inum.no_addr = bn;
dir_add(dip, filename, strlen(filename), &inum, IF2DT(mode));
- if(S_ISDIR(mode)) {
+ if (if_gfs1)
+ is_dir = (IF2DT(mode) == GFS_FILE_DIR);
+ else
+ is_dir = S_ISDIR(mode);
+ if (is_dir) {
bmodified(dip->i_bh);
dip->i_di.di_nlink++;
}
- bh = init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num);
+ bh = __init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num,
+ if_gfs1);
ip = inode_get(sdp, bh);
bmodified(bh);
}
@@ -1328,6 +1381,18 @@ struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
return ip;
}
+struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
+ unsigned int mode, uint32_t flags)
+{
+ return __createi(dip, filename, mode, flags, 0);
+}
+
+struct gfs2_inode *gfs_createi(struct gfs2_inode *dip, const char *filename,
+ unsigned int mode, uint32_t flags)
+{
+ return __createi(dip, filename, mode, flags, 1);
+}
+
/**
* gfs2_filecmp - Compare two filenames
* @file1: The first filename
@@ -1541,7 +1606,7 @@ int dir_search(struct gfs2_inode *dip, const char *filename, int len,
{
int error;
- if(!S_ISDIR(dip->i_di.di_mode))
+ if(!S_ISDIR(dip->i_di.di_mode) && !is_gfs_dir(&dip->i_di))
return -1;
if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
@@ -1627,7 +1692,7 @@ int gfs2_dirent_del(struct gfs2_inode *dip, const char *filename, int len)
{
int error;
- if(!S_ISDIR(dip->i_di.di_mode))
+ if(!S_ISDIR(dip->i_di.di_mode) && !is_gfs_dir(&dip->i_di))
return -1;
if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
@@ -1684,7 +1749,10 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
if (rgd) {
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
rgd->rg.rg_free++; /* adjust the free count */
- gfs2_rgrp_out(&rgd->rg, rgd->bh[0]); /* back to the buffer */
+ if (sdp->gfs1)
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ else
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
sdp->blks_alloced--;
}
}
@@ -1748,7 +1816,10 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
rgd = gfs2_blk2rgrpd(sdp, diblock);
rgd->rg.rg_free++;
rgd->rg.rg_dinodes--; /* one less inode in use */
- gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
+ if (sdp->gfs1)
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ else
+ gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
sdp->dinodes_alloced--;
return 0;
}
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 5b8d4ed..d1e8ab8 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
+#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -31,6 +32,13 @@ gfs1_metapointer(struct gfs2_buffer_head *bh, unsigned int height,
return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height];
}
+int is_gfs_dir(struct gfs2_dinode *dinode)
+{
+ if (dinode->__pad1 == GFS_FILE_DIR)
+ return 1;
+ return 0;
+}
+
void gfs1_lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
unsigned int height, struct metapath *mp,
int create, int *new, uint64_t *block)
@@ -159,6 +167,98 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
free(mp);
}
+int gfs1_writei(struct gfs2_inode *ip, char *buf, uint64_t offset,
+ unsigned int size)
+{
+ struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_buffer_head *bh;
+ uint64_t lblock, dblock;
+ uint32_t extlen = 0;
+ unsigned int amount;
+ int new;
+ int journaled = fs_is_jdata(ip);
+ const uint64_t start = offset;
+ int copied = 0;
+ int error = 0;
+
+ if (!size)
+ goto fail; /* Not really an error */
+
+
+ if (!ip->i_di.di_height && /* stuffed */
+ ((start + size) > (sdp->bsize - sizeof(struct gfs_dinode))))
+ unstuff_dinode(ip);
+
+ if (journaled) {
+ lblock = offset / sdp->sd_jbsize;
+ offset %= sdp->sd_jbsize;
+ } else {
+ lblock = offset >> sdp->sd_sb.sb_bsize_shift;
+ offset &= sdp->bsize - 1;
+ }
+
+ if (!ip->i_di.di_height) /* stuffed */
+ offset += sizeof(struct gfs_dinode);
+ else if (journaled)
+ offset += sizeof(struct gfs2_meta_header);
+
+ while (copied < size) {
+ amount = size - copied;
+ if (amount > sdp->bsize - offset)
+ amount = sdp->bsize - offset;
+
+ if (!extlen){
+ new = TRUE;
+ gfs1_block_map(ip, lblock, &new, &dblock, &extlen, 0);
+ if (!dblock)
+ return -1;
+ }
+
+ if (dblock == ip->i_di.di_num.no_addr)
+ bh = ip->i_bh;
+ else
+ bh = bread(sdp, dblock);
+
+ if (journaled && dblock != ip->i_di.di_num.no_addr ) {
+ struct gfs2_meta_header mh;
+
+ mh.mh_magic = GFS2_MAGIC;
+ mh.mh_type = GFS2_METATYPE_JD;
+ mh.mh_format = GFS2_FORMAT_JD;
+ gfs2_meta_header_out(&mh, bh);
+ }
+
+ memcpy(bh->b_data + offset, buf + copied, amount);
+ bmodified(bh);
+ if (bh != ip->i_bh)
+ brelse(bh);
+
+ copied += amount;
+ lblock++;
+ dblock++;
+ extlen--;
+
+ offset = (journaled) ? sizeof(struct gfs2_meta_header) : 0;
+ }
+
+ out:
+ if (ip->i_di.di_size < start + copied) {
+ bmodified(ip->i_bh);
+ ip->i_di.di_size = start + copied;
+ }
+ ip->i_di.di_mtime = ip->i_di.di_ctime = time(NULL);
+
+ gfs2_dinode_out(&ip->i_di, ip->i_bh);
+
+ return copied;
+
+ fail:
+ if (copied)
+ goto out;
+
+ return error;
+}
+
/* ------------------------------------------------------------------------ */
/* gfs_dinode_in */
/* ------------------------------------------------------------------------ */
@@ -301,3 +401,29 @@ void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
memcpy(str->rg_reserved, rgrp->rg_reserved, 64);
bmodified(rbh);
}
+
+void gfs_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex,
+ uint64_t *leaf_out)
+{
+ uint64_t leaf_no;
+ int count;
+
+ count = gfs2_readi(dip, (char *)&leaf_no, lindex * sizeof(uint64_t),
+ sizeof(uint64_t));
+ if (count != sizeof(uint64_t))
+ die("gfs_get_leaf_nr: Bad internal read.\n");
+
+ *leaf_out = be64_to_cpu(leaf_no);
+}
+
+void gfs_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
+{
+ uint64_t leaf_no;
+ int count;
+
+ leaf_no = cpu_to_be64(leaf_out);
+ count = gfs1_writei(dip, (char *)&leaf_no, inx * sizeof(uint64_t),
+ sizeof(uint64_t));
+ if (count != sizeof(uint64_t))
+ die("gfs_put_leaf_nr: Bad internal write.\n");
+}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 22c6552..58442e8 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -366,8 +366,16 @@ extern struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
struct gfs2_inum *inum,
unsigned int mode, uint32_t flags,
struct gfs2_inum *parent);
+extern struct gfs2_buffer_head *init_gfs_dinode(struct gfs2_sbd *sdp,
+ struct gfs2_inum *inum,
+ unsigned int mode,
+ uint32_t flags,
+ struct gfs2_inum *parent);
extern struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
unsigned int mode, uint32_t flags);
+extern struct gfs2_inode *gfs_createi(struct gfs2_inode *dip,
+ const char *filename, unsigned int mode,
+ uint32_t flags);
extern void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
struct gfs2_dirent *prev, struct gfs2_dirent *cur);
extern int dir_search(struct gfs2_inode *dip, const char *filename, int len,
@@ -577,13 +585,15 @@ struct gfs_log_descriptor {
char ld_reserved[64];
};
+extern int is_gfs_dir(struct gfs2_dinode *dinode);
extern void gfs1_lookup_block(struct gfs2_inode *ip,
struct gfs2_buffer_head *bh,
unsigned int height, struct metapath *mp,
int create, int *new, uint64_t *block);
extern void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
uint64_t *dblock, uint32_t *extlen, int prealloc);
-extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
+extern int gfs1_writei(struct gfs2_inode *ip, char *buf, uint64_t offset,
+ unsigned int size);
extern int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet);
extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
@@ -592,6 +602,10 @@ extern struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp,
extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
extern void gfs_rgrp_in(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
extern void gfs_rgrp_out(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
+extern void gfs_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex,
+ uint64_t *leaf_out);
+extern void gfs_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx,
+ uint64_t leaf_out);
/* gfs2_log.c */
struct gfs2_options {
@@ -685,6 +699,7 @@ extern int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
/* rgrp.c */
extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
+extern uint64_t __gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
extern void gfs2_rgrp_relse(struct rgrp_list *rgd);
extern void gfs2_rgrp_free(osi_list_t *rglist);
diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
index 351198a..507cebb 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -98,15 +98,20 @@ void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh)
CPIN_32(sb, str, sb_fs_format);
CPIN_32(sb, str, sb_multihost_format);
+ CPIN_32(sb, str, __pad0); /* gfs sb_flags */
CPIN_32(sb, str, sb_bsize);
CPIN_32(sb, str, sb_bsize_shift);
+ CPIN_32(sb, str, __pad1); /* gfs sb_seg_size */
gfs2_inum_in(&sb->sb_master_dir, (char *)&str->sb_master_dir);
gfs2_inum_in(&sb->sb_root_dir, (char *)&str->sb_root_dir);
CPIN_08(sb, str, sb_lockproto, GFS2_LOCKNAME_LEN);
CPIN_08(sb, str, sb_locktable, GFS2_LOCKNAME_LEN);
+ gfs2_inum_in(&sb->__pad2, (char *)&str->__pad2); /* gfs rindex */
+ gfs2_inum_in(&sb->__pad3, (char *)&str->__pad3); /* gfs quota */
+ gfs2_inum_in(&sb->__pad4, (char *)&str->__pad4); /* gfs license */
#ifdef GFS2_HAS_UUID
CPIN_08(sb, str, sb_uuid, sizeof(sb->sb_uuid));
#endif
@@ -233,7 +238,7 @@ void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
CPIN_32(rg, str, rg_free);
CPIN_32(rg, str, rg_dinodes);
- CPIN_08(rg, str, rg_reserved, 36);
+ CPIN_08(rg, str, rg_reserved, 80);
}
void gfs2_rgrp_out(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
@@ -245,7 +250,7 @@ void gfs2_rgrp_out(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
CPOUT_32(rg, str, rg_free);
CPOUT_32(rg, str, rg_dinodes);
- CPOUT_08(rg, str, rg_reserved, 36);
+ CPOUT_08(rg, str, rg_reserved, 80);
bmodified(bh);
}
@@ -343,6 +348,7 @@ void gfs2_dinode_out(struct gfs2_dinode *di, struct gfs2_buffer_head *bh)
CPOUT_32(di, str, di_flags);
CPOUT_32(di, str, di_payload_format);
+ CPOUT_16(di, str, __pad1);
CPOUT_16(di, str, di_height);
CPOUT_16(di, str, di_depth);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 0f34e33..cd3667f 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -156,9 +156,12 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
return error;
}
}
-
- if (rgd->bh && rgd->bh[0])
- gfs2_rgrp_in(&rgd->rg, rgd->bh[0]);
+ if (rgd->bh && rgd->bh[0]) {
+ if (sdp->gfs1)
+ gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ else
+ gfs2_rgrp_in(&rgd->rg, rgd->bh[0]);
+ }
return 0;
}
12 years, 3 months
cluster: RHEL6 - fsck.gfs2: Combine block and char device inode types
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 02714254368e71d63e1804e05a4534d564d5f5cb
Parent: e04c6a5aaa36e551c7d34e428edeb21d726c7ab4
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Aug 11 09:16:33 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
fsck.gfs2: Combine block and char device inode types
This patch combines the block and character device block designations.
Devices are now treated equally as one block type, which is fine.
This buys back a block type in the block map which may be used later
for gfs1 support. It also eliminates the rgrp block designation,
which is not needed: We only need to know whether rgrp blocks are
"in use" or not. In fact, the rgrp blocks have special processing
anyway and special code (function valid_block) to check for overlaps.
rhbz#675723
---
gfs2/fsck/pass1.c | 6 +++---
gfs2/fsck/pass2.c | 8 ++------
gfs2/fsck/pass3.c | 5 ++---
gfs2/fsck/pass4.c | 3 +--
gfs2/fsck/pass5.c | 4 +---
gfs2/fsck/util.h | 50 +++++++++++++++++++++++++-------------------------
6 files changed, 34 insertions(+), 42 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 64220f0..c0b7420 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1153,12 +1153,12 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
break;
case S_IFBLK:
if (fsck_blockmap_set(ip, block, _("block device"),
- gfs2_inode_blk))
+ gfs2_inode_device))
goto bad_dinode;
break;
case S_IFCHR:
if (fsck_blockmap_set(ip, block, _("character device"),
- gfs2_inode_chr))
+ gfs2_inode_device))
goto bad_dinode;
break;
case S_IFIFO:
@@ -1551,7 +1551,7 @@ int pass1(struct gfs2_sbd *sdp)
"is now marked as 'rgrp data'\n"),
rgd->ri.ri_addr + i, rgd->ri.ri_addr + i);
if (gfs2_blockmap_set(bl, rgd->ri.ri_addr + i,
- gfs2_meta_rgrp)) {
+ gfs2_indir_blk)) {
stack;
return FSCK_ERROR;
}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 7f32903..a4e8dca 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -134,12 +134,8 @@ static int check_file_type(uint8_t de_type, uint8_t blk_type)
if (de_type != DT_LNK)
return 1;
break;
- case gfs2_inode_blk:
- if (de_type != DT_BLK)
- return 1;
- break;
- case gfs2_inode_chr:
- if (de_type != DT_CHR)
+ case gfs2_inode_device:
+ if (de_type != DT_BLK && de_type != DT_CHR)
return 1;
break;
case gfs2_inode_fifo:
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index b904814..51104b5 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -240,9 +240,8 @@ int pass3(struct gfs2_sbd *sdp)
log_err( _("Unlinked directory with bad block remains\n"));
}
if (q != gfs2_inode_dir && q != gfs2_inode_file &&
- q != gfs2_inode_lnk && q != gfs2_inode_blk &&
- q != gfs2_inode_chr && q != gfs2_inode_fifo &&
- q != gfs2_inode_sock) {
+ q != gfs2_inode_lnk && q != gfs2_inode_device &&
+ q != gfs2_inode_fifo && q != gfs2_inode_sock) {
log_err( _("Unlinked block marked as an inode "
"is not an inode\n"));
if (!query(_("Clear the unlinked block?"
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 04fb075..32dbb72 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -83,8 +83,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
if (q != gfs2_inode_dir &&
q != gfs2_inode_file &&
q != gfs2_inode_lnk &&
- q != gfs2_inode_blk &&
- q != gfs2_inode_chr &&
+ q != gfs2_inode_device &&
q != gfs2_inode_fifo &&
q != gfs2_inode_sock) {
log_err( _("Unlinked block %lld (0x%llx) "
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 814f202..29b5965 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -27,8 +27,7 @@ static int convert_mark(uint8_t q, uint32_t *count)
case gfs2_inode_dir:
case gfs2_inode_file:
case gfs2_inode_lnk:
- case gfs2_inode_blk:
- case gfs2_inode_chr:
+ case gfs2_inode_device:
case gfs2_inode_fifo:
case gfs2_inode_sock:
count[1]++;
@@ -36,7 +35,6 @@ static int convert_mark(uint8_t q, uint32_t *count)
case gfs2_indir_blk:
case gfs2_leaf_blk:
- case gfs2_meta_rgrp:
case gfs2_meta_eattr:
count[2]++;
return GFS2_BLKST_USED;
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index b26c123..106cca8 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -42,15 +42,15 @@ enum gfs2_mark_block {
gfs2_inode_file = (0x4),
gfs2_inode_lnk = (0x5),
- gfs2_inode_blk = (0x6),
- gfs2_inode_chr = (0x7),
+ gfs2_inode_device = (0x6),
+
gfs2_inode_fifo = (0x8),
gfs2_inode_sock = (0x9),
gfs2_inode_invalid = (0xa),
gfs2_meta_inval = (0xb),
gfs2_leaf_blk = (0xc),
- gfs2_meta_rgrp = (0xd),
+
gfs2_meta_eattr = (0xe),
gfs2_bad_block = (0xf), /* Contains at least one bad block */
@@ -66,15 +66,15 @@ static const inline char *block_type_string(uint8_t q)
"file",
"symlink",
- "block device",
- "char device",
+ "device",
+ "",
"fifo",
"socket",
"invalid inode",
"invalid meta",
"dir leaf",
- "rgrp meta",
+ "",
"eattribute",
"bad"};
@@ -88,25 +88,25 @@ static const inline char *block_type_string(uint8_t q)
static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
{
static int bitmap_states[16] = {
- GFS2_BLKST_FREE,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
-
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
-
- GFS2_BLKST_FREE,
- GFS2_BLKST_FREE,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
-
- GFS2_BLKST_USED
+ GFS2_BLKST_FREE, /* free */
+ GFS2_BLKST_USED, /* data */
+ GFS2_BLKST_USED, /* indirect data or rgrp meta*/
+ GFS2_BLKST_DINODE, /* directory */
+ GFS2_BLKST_DINODE, /* file */
+
+ GFS2_BLKST_DINODE, /* symlink */
+ GFS2_BLKST_DINODE, /* block or char device */
+ GFS2_BLKST_USED, /* reserved */
+ GFS2_BLKST_DINODE, /* fifo */
+ GFS2_BLKST_DINODE, /* socket */
+
+ GFS2_BLKST_FREE, /* invalid inode */
+ GFS2_BLKST_FREE, /* invalid meta */
+ GFS2_BLKST_USED, /* dir leaf */
+ GFS2_BLKST_UNLINKED, /* unused */
+ GFS2_BLKST_USED, /* eattribute */
+
+ GFS2_BLKST_USED, /* bad */
};
return bitmap_states[m];
}
12 years, 3 months
cluster: RHEL6 - gfs2_edit savemeta: save_inode_data backward for gfs1
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 4459c39de938feec3e245805a96af83d6286c0e5
Parent: 89e76e78c87d586dab18168e4b692c0d534abc35
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 15:30:25 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
gfs2_edit savemeta: save_inode_data backward for gfs1
The logic in "gfs2_edit savemeta" was wrong for saving inode blocks.
This patch fixes the logic.
rhbz#675723
---
gfs2/edit/savemeta.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 665af07..8ccbf8a 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -121,9 +121,9 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
break;
case GFS2_METATYPE_DI: /* 4 (disk inode) */
if (sbd.gfs1)
- inode = inode_get(&sbd, lbh);
- else
inode = gfs_inode_get(&sbd, lbh);
+ else
+ inode = inode_get(&sbd, lbh);
if (S_ISDIR(inode->i_di.di_mode) ||
(sbd.gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR))
*gstruct_len = sbd.bsize;
@@ -455,9 +455,9 @@ static void save_inode_data(struct metafd *mfd)
osi_list_init(&metalist[i]);
metabh = bread(&sbd, block);
if (sbd.gfs1)
- inode = inode_get(&sbd, metabh);
- else
inode = gfs_inode_get(&sbd, metabh);
+ else
+ inode = inode_get(&sbd, metabh);
height = inode->i_di.di_height;
/* If this is a user inode, we don't follow to the file height.
We stop one level less. That way we save off the indirect
12 years, 3 months
cluster: RHEL6 - libgfs2: move gfs1 functions from edit to libgfs2
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 89e76e78c87d586dab18168e4b692c0d534abc35
Parent: 0d5832a1b88c81e5937f2bff26d7a7a9b6cd6892
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 15:27:10 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: move gfs1 functions from edit to libgfs2
This patch moves some gfs1-specific functions from gfs2_edit to
libgfs2 so that other utils can eventually operate on gfs1 file
systems.
rhbz#675723
---
gfs2/edit/hexedit.c | 47 -------------------------------------------
gfs2/edit/hexedit.h | 1 -
gfs2/libgfs2/gfs1.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/libgfs2.h | 3 ++
4 files changed, 55 insertions(+), 48 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index abb8ef0..a2ccc60 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1498,40 +1498,6 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
}
/* ------------------------------------------------------------------------ */
-/* gfs_rgrp_in - Read in a resource group header */
-/* ------------------------------------------------------------------------ */
-void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
-{
- struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
-
- gfs2_meta_header_in(&rgrp->rg_header, rbh);
- rgrp->rg_flags = be32_to_cpu(str->rg_flags);
- rgrp->rg_free = be32_to_cpu(str->rg_free);
- rgrp->rg_useddi = be32_to_cpu(str->rg_useddi);
- rgrp->rg_freedi = be32_to_cpu(str->rg_freedi);
- gfs2_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
- rgrp->rg_usedmeta = be32_to_cpu(str->rg_usedmeta);
- rgrp->rg_freemeta = be32_to_cpu(str->rg_freemeta);
-}
-
-/* ------------------------------------------------------------------------ */
-/* gfs_rgrp_out */
-/* ------------------------------------------------------------------------ */
-static void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
-{
- struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
-
- gfs2_meta_header_out(&rgrp->rg_header, rbh);
- str->rg_flags = cpu_to_be32(rgrp->rg_flags);
- str->rg_free = cpu_to_be32(rgrp->rg_free);
- str->rg_useddi = cpu_to_be32(rgrp->rg_useddi);
- str->rg_freedi = cpu_to_be32(rgrp->rg_freedi);
- gfs2_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
- str->rg_usedmeta = cpu_to_be32(rgrp->rg_usedmeta);
- str->rg_freemeta = cpu_to_be32(rgrp->rg_freemeta);
-}
-
-/* ------------------------------------------------------------------------ */
/* gfs_rgrp_print - print a gfs1 resource group */
/* ------------------------------------------------------------------------ */
void gfs_rgrp_print(struct gfs_rgrp *rg)
@@ -1622,19 +1588,6 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
}
/* ------------------------------------------------------------------------ */
-/* gfs_jindex_in - read in a gfs1 jindex structure. */
-/* ------------------------------------------------------------------------ */
-void gfs_jindex_in(struct gfs_jindex *jindex, char *jbuf)
-{
- struct gfs_jindex *str = (struct gfs_jindex *) jbuf;
-
- jindex->ji_addr = be64_to_cpu(str->ji_addr);
- jindex->ji_nsegment = be32_to_cpu(str->ji_nsegment);
- jindex->ji_pad = be32_to_cpu(str->ji_pad);
- memcpy(jindex->ji_reserved, str->ji_reserved, 64);
-}
-
-/* ------------------------------------------------------------------------ */
/* has_indirect_blocks */
/* ------------------------------------------------------------------------ */
int has_indirect_blocks(void)
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index f7b539e..07125bd 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -221,7 +221,6 @@ extern int display(int identify_only);
extern uint64_t check_keywords(const char *kword);
extern uint64_t masterblock(const char *fn);
extern void gfs_rgrp_print(struct gfs_rgrp *rg);
-extern void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh);
extern int has_indirect_blocks(void);
#endif /* __HEXVIEW_DOT_H__ */
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index fb4acab..5b8d4ed 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -249,3 +249,55 @@ struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
{
return __gfs_inode_get(sdp, NULL, di_addr);
}
+
+/* ------------------------------------------------------------------------ */
+/* gfs_jindex_in - read in a gfs1 jindex structure. */
+/* ------------------------------------------------------------------------ */
+void gfs_jindex_in(struct gfs_jindex *jindex, char *jbuf)
+{
+ struct gfs_jindex *str = (struct gfs_jindex *) jbuf;
+
+ jindex->ji_addr = be64_to_cpu(str->ji_addr);
+ jindex->ji_nsegment = be32_to_cpu(str->ji_nsegment);
+ jindex->ji_pad = be32_to_cpu(str->ji_pad);
+ memcpy(jindex->ji_reserved, str->ji_reserved, 64);
+}
+
+/* ------------------------------------------------------------------------ */
+/* gfs_rgrp_in - Read in a resource group header */
+/* ------------------------------------------------------------------------ */
+void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
+{
+ struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
+
+ gfs2_meta_header_in(&rgrp->rg_header, rbh);
+ rgrp->rg_flags = be32_to_cpu(str->rg_flags);
+ rgrp->rg_free = be32_to_cpu(str->rg_free);
+ rgrp->rg_useddi = be32_to_cpu(str->rg_useddi);
+ rgrp->rg_freedi = be32_to_cpu(str->rg_freedi);
+ gfs2_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
+ rgrp->rg_usedmeta = be32_to_cpu(str->rg_usedmeta);
+ rgrp->rg_freemeta = be32_to_cpu(str->rg_freemeta);
+
+ memcpy(rgrp->rg_reserved, str->rg_reserved, 64);
+}
+
+/* ------------------------------------------------------------------------ */
+/* gfs_rgrp_out */
+/* ------------------------------------------------------------------------ */
+void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
+{
+ struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
+
+ gfs2_meta_header_out(&rgrp->rg_header, rbh);
+ str->rg_flags = cpu_to_be32(rgrp->rg_flags);
+ str->rg_free = cpu_to_be32(rgrp->rg_free);
+ str->rg_useddi = cpu_to_be32(rgrp->rg_useddi);
+ str->rg_freedi = cpu_to_be32(rgrp->rg_freedi);
+ gfs2_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
+ str->rg_usedmeta = cpu_to_be32(rgrp->rg_usedmeta);
+ str->rg_freemeta = cpu_to_be32(rgrp->rg_freemeta);
+
+ memcpy(str->rg_reserved, rgrp->rg_reserved, 64);
+ bmodified(rbh);
+}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index a2e1523..22c6552 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -589,6 +589,9 @@ extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
struct gfs2_buffer_head *bh);
extern struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp,
uint64_t di_addr);
+extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
+extern void gfs_rgrp_in(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
+extern void gfs_rgrp_out(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
/* gfs2_log.c */
struct gfs2_options {
12 years, 3 months
cluster: RHEL6 - libgfs2: combine gfs_inode_read and gfs_inode_get
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 0d5832a1b88c81e5937f2bff26d7a7a9b6cd6892
Parent: 8bd29a4cca3a6c3b210d42c2d1c87bca59d4bcb0
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 14:49:35 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: combine gfs_inode_read and gfs_inode_get
Functions gfs_inode_read and gfs_inode_get were nearly identical.
They did the same exact thing, but one operated on a buffer passed in
while the other read the buffer from the media. This patch combines
the two into a common function and two replacement stubs.
rhbz#675723
---
gfs2/libgfs2/gfs1.c | 57 +++++++++++++-------------------------------------
1 files changed, 15 insertions(+), 42 deletions(-)
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 3e314ce..fb4acab 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -191,8 +191,9 @@ static void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh)
di->di_eattr = be64_to_cpu(str->di_eattr);
}
-struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
- struct gfs2_buffer_head *bh)
+static struct gfs2_inode *__gfs_inode_get(struct gfs2_sbd *sdp,
+ struct gfs2_buffer_head *bh,
+ uint64_t di_addr)
{
struct gfs_dinode gfs1_dinode;
struct gfs2_inode *ip;
@@ -203,6 +204,11 @@ struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
exit(-1);
}
+ ip->bh_owned = 0;
+ if (!bh) {
+ bh = bread(sdp, di_addr);
+ ip->bh_owned = 1;
+ }
gfs_dinode_in(&gfs1_dinode, bh);
memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header,
sizeof(struct gfs2_meta_header));
@@ -230,49 +236,16 @@ struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
ip->i_di.di_eattr = gfs1_dinode.di_eattr;
ip->i_bh = bh;
ip->i_sbd = sdp;
- ip->bh_owned = 0;
return ip;
}
-struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
+struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
+ struct gfs2_buffer_head *bh)
{
- struct gfs_dinode gfs1_dinode;
- struct gfs2_inode *ip;
-
- ip = calloc(1, sizeof(struct gfs2_inode));
- if (ip == NULL) {
- fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
- exit(-1);
- }
-
- ip->i_bh = bread(sdp, di_addr);
- gfs_dinode_in(&gfs1_dinode, ip->i_bh);
- memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header,
- sizeof(struct gfs2_meta_header));
- memcpy(&ip->i_di.di_num, &gfs1_dinode.di_num,
- sizeof(struct gfs2_inum));
- ip->i_di.di_mode = gfs1_dinode.di_mode;
- ip->i_di.di_uid = gfs1_dinode.di_uid;
- ip->i_di.di_gid = gfs1_dinode.di_gid;
- ip->i_di.di_nlink = gfs1_dinode.di_nlink;
- ip->i_di.di_size = gfs1_dinode.di_size;
- ip->i_di.di_blocks = gfs1_dinode.di_blocks;
- ip->i_di.di_atime = gfs1_dinode.di_atime;
- ip->i_di.di_mtime = gfs1_dinode.di_mtime;
- ip->i_di.di_ctime = gfs1_dinode.di_ctime;
- ip->i_di.di_major = gfs1_dinode.di_major;
- ip->i_di.di_minor = gfs1_dinode.di_minor;
- ip->i_di.di_goal_data = gfs1_dinode.di_goal_dblk;
- ip->i_di.di_goal_meta = gfs1_dinode.di_goal_mblk;
- ip->i_di.di_flags = gfs1_dinode.di_flags;
- ip->i_di.di_payload_format = gfs1_dinode.di_payload_format;
- ip->i_di.__pad1 = gfs1_dinode.di_type;
- ip->i_di.di_height = gfs1_dinode.di_height;
- ip->i_di.di_depth = gfs1_dinode.di_depth;
- ip->i_di.di_entries = gfs1_dinode.di_entries;
- ip->i_di.di_eattr = gfs1_dinode.di_eattr;
- ip->i_sbd = sdp;
- ip->bh_owned = 1;
- return ip;
+ return __gfs_inode_get(sdp, bh, 0);
}
+struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
+{
+ return __gfs_inode_get(sdp, NULL, di_addr);
+}
12 years, 3 months
cluster: RHEL6 - libgfs2: combine ri_update and gfs1_ri_update
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 8bd29a4cca3a6c3b210d42c2d1c87bca59d4bcb0
Parent: d01bf561a8a3470335cf0a3832715fda7b7cf0f4
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 14:20:11 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: combine ri_update and gfs1_ri_update
Since gfs1_ri_update is nearly identical to ri_update, I decided to
combine the main logic into a common function. That simplifies the
code and if one gets fixed, they both get fixed automatically.
rhbz#675723
---
gfs2/libgfs2/gfs1.c | 49 -------------------------------------------------
gfs2/libgfs2/super.c | 33 ++++++++++++++++++++++++++++++---
2 files changed, 30 insertions(+), 52 deletions(-)
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 076f4d0..3e314ce 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -159,55 +159,6 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
free(mp);
}
-/**
- * gfs1_ri_update - attach rgrps to the super block
- * Stolen from libgfs2/super.c, but modified to handle gfs1.
- * @sdp:
- *
- * Given the rgrp index inode, link in all rgrps into the super block
- * and be sure that they can be read.
- *
- * Returns: 0 on success, -1 on failure.
- */
-int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
-{
- struct rgrp_list *rgd;
- struct gfs2_rindex *ri;
- osi_list_t *tmp;
- int count1 = 0, count2 = 0;
- uint64_t errblock = 0;
- uint64_t rmax = 0;
- int sane;
-
- if (rindex_read(sdp, fd, &count1, &sane))
- goto fail;
- for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
- rgd = osi_list_entry(tmp, struct rgrp_list, list);
- errblock = gfs2_rgrp_read(sdp, rgd);
- if (errblock)
- return errblock;
- count2++;
- if (!quiet && count2 % 100 == 0) {
- printf(".");
- fflush(stdout);
- }
- ri = &rgd->ri;
- if (ri->ri_data0 + ri->ri_data - 1 > rmax)
- rmax = ri->ri_data0 + ri->ri_data - 1;
- }
-
- sdp->fssize = rmax;
- *rgcount = count1;
- if (count1 != count2)
- goto fail;
-
- return 0;
-
- fail:
- gfs2_rgrp_free(&sdp->rglist);
- return -1;
-}
-
/* ------------------------------------------------------------------------ */
/* gfs_dinode_in */
/* ------------------------------------------------------------------------ */
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 0fac740..27f6c2c 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -223,7 +223,8 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
*
* Returns: 0 on success, -1 on failure.
*/
-int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
+static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane,
+ int quiet)
{
struct rgrp_list *rgd;
struct gfs2_rindex *ri;
@@ -233,16 +234,20 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
uint64_t rmax = 0;
if (rindex_read(sdp, fd, &count1, sane))
- goto fail;
+ goto fail;
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
errblock = gfs2_rgrp_read(sdp, rgd);
if (errblock)
return errblock;
+ count2++;
+ if (!quiet && count2 % 100 == 0) {
+ printf(".");
+ fflush(stdout);
+ }
ri = &rgd->ri;
if (ri->ri_data0 + ri->ri_data - 1 > rmax)
rmax = ri->ri_data0 + ri->ri_data - 1;
- count2++;
}
sdp->fssize = rmax;
@@ -257,6 +262,28 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
return -1;
}
+int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
+{
+ return __ri_update(sdp, fd, rgcount, sane, 1);
+}
+
+/**
+ * gfs1_ri_update - attach rgrps to the super block
+ * Stolen from libgfs2/super.c, but modified to handle gfs1.
+ * @sdp:
+ *
+ * Given the rgrp index inode, link in all rgrps into the super block
+ * and be sure that they can be read.
+ *
+ * Returns: 0 on success, -1 on failure.
+ */
+int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
+{
+ int sane;
+
+ return __ri_update(sdp, fd, rgcount, &sane, quiet);
+}
+
int write_sb(struct gfs2_sbd *sbp)
{
struct gfs2_buffer_head *bh;
12 years, 3 months
cluster: RHEL6 - libgfs2: eliminate gfs1_rindex_read
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: d01bf561a8a3470335cf0a3832715fda7b7cf0f4
Parent: 4591e128cb00343274b3edc2744d03372816243e
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 14:07:45 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: eliminate gfs1_rindex_read
Now that function rindex_read is able to handle gfs1 file reading,
this patch eliminates the gfs1-specific function gfs1_rindex_read.
rhbz#675723
---
gfs2/edit/hexedit.c | 13 +++-------
gfs2/libgfs2/gfs1.c | 62 +-------------------------------------------------
2 files changed, 6 insertions(+), 69 deletions(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 903f169..abb8ef0 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1756,7 +1756,7 @@ static int block_has_extended_info(void)
/* ------------------------------------------------------------------------ */
static void read_superblock(int fd)
{
- int count;
+ int count, sane;
sbd1 = (struct gfs_sb *)&sbd.sd_sb;
ioctl(fd, BLKFLSBUF, 0);
@@ -1809,11 +1809,7 @@ static void read_superblock(int fd)
sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs_dinode)) /
sizeof(uint64_t);
sbd.md.riinode = inode_read(&sbd, sbd1->sb_rindex_di.no_addr);
- sbd.fssize = sbd.device.length;
- gfs1_rindex_read(&sbd, 0, &count);
} else {
- int sane;
-
sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
sizeof(uint64_t);
sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs2_dinode)) /
@@ -1821,11 +1817,10 @@ static void read_superblock(int fd)
sbd.master_dir = inode_read(&sbd,
sbd.sd_sb.sb_master_dir.no_addr);
gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
- sbd.fssize = sbd.device.length;
- if (sbd.md.riinode) /* If we found the rindex */
- rindex_read(&sbd, 0, &count, &sane);
}
-
+ sbd.fssize = sbd.device.length;
+ if (sbd.md.riinode) /* If we found the rindex */
+ rindex_read(&sbd, 0, &count, &sane);
}
/* ------------------------------------------------------------------------ */
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 2ace124..076f4d0 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -160,65 +160,6 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
}
/**
- * gfs1_rindex_read - read in the rg index file
- * Stolen from libgfs2/super.c, but modified to handle gfs1.
- * @sdp: the incore superblock pointer
- * fd: optional file handle for rindex file (if meta_fs file system is mounted)
- * (if fd is <= zero, it will read from raw device)
- * @count1: return count of the rgs.
- *
- * Returns: 0 on success, -1 on failure
- */
-int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
-{
- unsigned int rg;
- int error;
- struct gfs2_rindex buf;
- struct rgrp_list *rgd, *prev_rgd;
- uint64_t prev_length = 0;
-
- *count1 = 0;
- prev_rgd = NULL;
- for (rg = 0; ; rg++) {
- if (fd > 0)
- error = read(fd, &buf, sizeof(struct gfs2_rindex));
- else
- error = gfs2_readi(sdp->md.riinode, (char *)&buf,
- (rg * sizeof(struct gfs2_rindex)),
- sizeof(struct gfs2_rindex));
- if (!error)
- break;
- if (error != sizeof(struct gfs2_rindex))
- return -1;
-
- rgd = (struct rgrp_list *)malloc(sizeof(struct rgrp_list));
- if (!rgd) {
- log_crit("Cannot allocate memory for rindex.\n");
- exit(-1);
- }
- memset(rgd, 0, sizeof(struct rgrp_list));
- osi_list_add_prev(&rgd->list, &sdp->rglist);
-
- gfs2_rindex_in(&rgd->ri, (char *)&buf);
-
- rgd->start = rgd->ri.ri_addr;
- if (prev_rgd) {
- prev_length = rgd->start - prev_rgd->start;
- prev_rgd->length = prev_length;
- }
-
- if(gfs2_compute_bitstructs(sdp, rgd))
- return -1;
-
- (*count1)++;
- prev_rgd = rgd;
- }
- if (prev_rgd)
- prev_rgd->length = prev_length;
- return 0;
-}
-
-/**
* gfs1_ri_update - attach rgrps to the super block
* Stolen from libgfs2/super.c, but modified to handle gfs1.
* @sdp:
@@ -236,8 +177,9 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
int count1 = 0, count2 = 0;
uint64_t errblock = 0;
uint64_t rmax = 0;
+ int sane;
- if (gfs1_rindex_read(sdp, fd, &count1))
+ if (rindex_read(sdp, fd, &count1, &sane))
goto fail;
for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
rgd = osi_list_entry(tmp, struct rgrp_list, list);
12 years, 3 months
cluster: RHEL6 - libgfs2: move block_map functions to fsck.gfs2
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 4591e128cb00343274b3edc2744d03372816243e
Parent: e411d72a57ee6b8e720db6e49c8de58a2b4d3501
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 13:12:54 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: move block_map functions to fsck.gfs2
Since the "blockmap" functions were only used in fsck.gfs2 they don't
have a place in libgfs2. This patch moves them to fsck.gfs2.
rhbz#675723
---
gfs2/fsck/metawalk.h | 2 +
gfs2/fsck/util.c | 72 ++++++++++++++++++++++++++++++++++++++
gfs2/fsck/util.h | 84 +++++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/block_list.c | 72 --------------------------------------
gfs2/libgfs2/libgfs2.h | 82 -------------------------------------------
5 files changed, 158 insertions(+), 154 deletions(-)
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 719bbd9..e114427 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -4,6 +4,8 @@
#define DIR_LINEAR 1
#define DIR_EXHASH 2
+#include "util.h"
+
struct metawalk_fxns;
extern int check_inode_eattr(struct gfs2_inode *ip,
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 569f25a..4075aec 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -380,3 +380,75 @@ void dirtree_delete(struct dir_info *b)
osi_erase(&b->node, &dirtree);
free(b);
}
+
+static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
+{
+ bmap->size = size;
+
+ /* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
+ * must be 1-based */
+ bmap->mapsize = BLOCKMAP_SIZE4(size);
+
+ if (!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
+ return -ENOMEM;
+ if (!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
+ free(bmap->map);
+ bmap->map = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
+{
+ if (bmap->map)
+ free(bmap->map);
+ bmap->size = 0;
+ bmap->mapsize = 0;
+}
+
+struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed)
+{
+ struct gfs2_bmap *il;
+
+ *addl_mem_needed = 0L;
+ il = malloc(sizeof(*il));
+ if (!il || !memset(il, 0, sizeof(*il)))
+ return NULL;
+
+ if (gfs2_blockmap_create(il, size)) {
+ *addl_mem_needed = il->mapsize;
+ free(il);
+ il = NULL;
+ }
+ osi_list_init(&sdp->eattr_blocks.list);
+ return il;
+}
+
+int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock,
+ enum gfs2_mark_block mark)
+{
+ static unsigned char *byte;
+ static uint64_t b;
+
+ if (bblock > bmap->size)
+ return -1;
+
+ byte = bmap->map + BLOCKMAP_SIZE4(bblock);
+ b = BLOCKMAP_BYTE_OFFSET4(bblock);
+ *byte &= ~(BLOCKMAP_MASK4 << b);
+ *byte |= (mark & BLOCKMAP_MASK4) << b;
+ return 0;
+}
+
+void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
+{
+ if (il) {
+ gfs2_blockmap_destroy(il);
+ free(il);
+ il = NULL;
+ }
+ gfs2_special_free(&sdp->eattr_blocks);
+ return il;
+}
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 56b83fe..b26c123 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -33,4 +33,88 @@ static inline uint8_t block_type(uint64_t bblock)
return btype;
}
+/* blockmap declarations and functions */
+enum gfs2_mark_block {
+ gfs2_block_free = (0x0),
+ gfs2_block_used = (0x1),
+ gfs2_indir_blk = (0x2),
+ gfs2_inode_dir = (0x3),
+ gfs2_inode_file = (0x4),
+
+ gfs2_inode_lnk = (0x5),
+ gfs2_inode_blk = (0x6),
+ gfs2_inode_chr = (0x7),
+ gfs2_inode_fifo = (0x8),
+ gfs2_inode_sock = (0x9),
+
+ gfs2_inode_invalid = (0xa),
+ gfs2_meta_inval = (0xb),
+ gfs2_leaf_blk = (0xc),
+ gfs2_meta_rgrp = (0xd),
+ gfs2_meta_eattr = (0xe),
+
+ gfs2_bad_block = (0xf), /* Contains at least one bad block */
+};
+
+static const inline char *block_type_string(uint8_t q)
+{
+ const char *blktyp[] = {
+ "free",
+ "data",
+ "indirect data",
+ "directory",
+ "file",
+
+ "symlink",
+ "block device",
+ "char device",
+ "fifo",
+ "socket",
+
+ "invalid inode",
+ "invalid meta",
+ "dir leaf",
+ "rgrp meta",
+ "eattribute",
+
+ "bad"};
+ if (q < 16)
+ return (blktyp[q]);
+ return blktyp[15];
+}
+
+/* Must be kept in sync with gfs2_mark_block enum above. Blocks marked as
+ invalid or bad are considered metadata until actually freed. */
+static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
+{
+ static int bitmap_states[16] = {
+ GFS2_BLKST_FREE,
+ GFS2_BLKST_USED,
+ GFS2_BLKST_USED,
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+ GFS2_BLKST_DINODE,
+
+ GFS2_BLKST_FREE,
+ GFS2_BLKST_FREE,
+ GFS2_BLKST_USED,
+ GFS2_BLKST_USED,
+ GFS2_BLKST_USED,
+
+ GFS2_BLKST_USED
+ };
+ return bitmap_states[m];
+}
+
+extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed);
+extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
+extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
+ enum gfs2_mark_block mark);
+
#endif /* __UTIL_H__ */
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index faedc54..65003b0 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -8,51 +8,6 @@
#include "libgfs2.h"
-static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
-{
- bmap->size = size;
-
- /* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
- * must be 1-based */
- bmap->mapsize = BLOCKMAP_SIZE4(size);
-
- if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
- return -ENOMEM;
- if(!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
- free(bmap->map);
- bmap->map = NULL;
- return -ENOMEM;
- }
- return 0;
-}
-
-static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
-{
- if(bmap->map)
- free(bmap->map);
- bmap->size = 0;
- bmap->mapsize = 0;
-}
-
-struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
- uint64_t *addl_mem_needed)
-{
- struct gfs2_bmap *il;
-
- *addl_mem_needed = 0L;
- il = malloc(sizeof(*il));
- if (!il || !memset(il, 0, sizeof(*il)))
- return NULL;
-
- if(gfs2_blockmap_create(il, size)) {
- *addl_mem_needed = il->mapsize;
- free(il);
- il = NULL;
- }
- osi_list_init(&sdp->eattr_blocks.list);
- return il;
-}
-
void gfs2_special_free(struct special_blocks *blist)
{
struct special_blocks *f;
@@ -108,30 +63,3 @@ void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
free(b);
}
}
-
-int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock,
- enum gfs2_mark_block mark)
-{
- static unsigned char *byte;
- static uint64_t b;
-
- if(bblock > bmap->size)
- return -1;
-
- byte = bmap->map + BLOCKMAP_SIZE4(bblock);
- b = BLOCKMAP_BYTE_OFFSET4(bblock);
- *byte &= ~(BLOCKMAP_MASK4 << b);
- *byte |= (mark & BLOCKMAP_MASK4) << b;
- return 0;
-}
-
-void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
-{
- if(il) {
- gfs2_blockmap_destroy(il);
- free(il);
- il = NULL;
- }
- gfs2_special_free(&sdp->eattr_blocks);
- return il;
-}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index cc71bd3..a2e1523 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -273,94 +273,12 @@ struct gfs2_bmap {
/* block_list.c */
-enum gfs2_mark_block {
- gfs2_block_free = (0x0),
- gfs2_block_used = (0x1),
- gfs2_indir_blk = (0x2),
- gfs2_inode_dir = (0x3),
- gfs2_inode_file = (0x4),
-
- gfs2_inode_lnk = (0x5),
- gfs2_inode_blk = (0x6),
- gfs2_inode_chr = (0x7),
- gfs2_inode_fifo = (0x8),
- gfs2_inode_sock = (0x9),
-
- gfs2_inode_invalid = (0xa),
- gfs2_meta_inval = (0xb),
- gfs2_leaf_blk = (0xc),
- gfs2_meta_rgrp = (0xd),
- gfs2_meta_eattr = (0xe),
-
- gfs2_bad_block = (0xf), /* Contains at least one bad block */
-};
-
-static const inline char *block_type_string(uint8_t q)
-{
- const char *blktyp[] = {
- "free",
- "data",
- "indirect data",
- "directory",
- "file",
-
- "symlink",
- "block device",
- "char device",
- "fifo",
- "socket",
-
- "invalid inode",
- "invalid meta",
- "dir leaf",
- "rgrp meta",
- "eattribute",
-
- "bad"};
- if (q < 16)
- return (blktyp[q]);
- return blktyp[15];
-}
-
-/* Must be kept in sync with gfs2_mark_block enum above. Blocks marked as
- invalid or bad are considered metadata until actually freed. */
-static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
-{
- static int bitmap_states[16] = {
- GFS2_BLKST_FREE,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
-
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
- GFS2_BLKST_DINODE,
-
- GFS2_BLKST_FREE,
- GFS2_BLKST_FREE,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
- GFS2_BLKST_USED,
-
- GFS2_BLKST_USED
- };
- return bitmap_states[m];
-}
-
-extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
- uint64_t *addl_mem_needed);
extern struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num);
extern void gfs2_special_add(struct special_blocks *blocklist, uint64_t block);
extern void gfs2_special_set(struct special_blocks *blocklist, uint64_t block);
extern void gfs2_special_free(struct special_blocks *blist);
-extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
- enum gfs2_mark_block mark);
extern void gfs2_special_clear(struct special_blocks *blocklist,
uint64_t block);
-extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
/* buf.c */
extern struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp,
12 years, 3 months
cluster: RHEL6 - libgfs2: Use dinode buffer to map gfs1 dinode blocks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: e411d72a57ee6b8e720db6e49c8de58a2b4d3501
Parent: acee2940261ea454b8f82fcc55827a3e97ad0049
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 10 10:33:49 2011 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri Jan 20 08:26:27 2012 -0600
libgfs2: Use dinode buffer to map gfs1 dinode blocks
When function gfs1_block_map found a block for a stuffed file it
wasn't returning the dinode buffer, it was returning the block as a
new buffer. The problem is, if changes are made to the block, they
will be overwritten by the dinode buffer when that is released.
The result is a fixed block that doesn't get fixed. This patch
changes the code to return the block properly like gfs2_block_map.
rhbz#675723
---
gfs2/libgfs2/gfs1.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 59eaa8d..2ace124 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -118,7 +118,10 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
mh.mh_format = GFS2_FORMAT_IN;
gfs2_meta_header_out(&mh, bh);
} else {
- bh = bread(sdp, *dblock);
+ if (*dblock == ip->i_di.di_num.no_addr)
+ bh = ip->i_bh;
+ else
+ bh = bread(sdp, *dblock);
}
}
12 years, 3 months