cluster: STABLE3 - fsck.gfs2: link.c should log why it's making a change for debugging
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: f8a4338b1c2978b935cb4fe9289663cce642a6ec
Parent: f25fe6a87d568285aa6f7cf6298f6f284e964977
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Fri Jan 22 09:01:15 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:30 2010 -0600
fsck.gfs2: link.c should log why it's making a change for debugging
This patch helps in debugging directory link problems by logging
the dinode and the reason why the directory link count is being
incremented or decremented.
rhbz#455300
---
gfs2/fsck/link.c | 31 +++++++++++++++++++++++--------
gfs2/fsck/link.h | 6 ++++--
gfs2/fsck/lost_n_found.c | 22 ++++++++++++++++------
gfs2/fsck/pass2.c | 40 ++++++++++++++++++++++++++++------------
gfs2/fsck/pass3.c | 4 ++--
5 files changed, 73 insertions(+), 30 deletions(-)
diff --git a/gfs2/fsck/link.c b/gfs2/fsck/link.c
index 59e258b..0314074 100644
--- a/gfs2/fsck/link.c
+++ b/gfs2/fsck/link.c
@@ -27,21 +27,28 @@ int set_link_count(uint64_t inode_no, uint32_t count)
return 0;
}
-int increment_link(struct gfs2_sbd *sbp, uint64_t inode_no)
+int increment_link(uint64_t inode_no, uint64_t referenced_from,
+ const char *why)
{
struct inode_info *ii = NULL;
ii = inodetree_find(inode_no);
/* If the list has entries, look for one that matches
* inode_no */
- if(ii) {
+ if (ii) {
ii->counted_links++;
- log_debug( _("Incremented counted links to %u for %"PRIu64" (0x%"
- PRIx64 ")\n"), ii->counted_links, inode_no, inode_no);
+ log_debug( _("Directory %lld (0x%llx) incremented counted "
+ "links to %u for %"PRIu64" (0x%" PRIx64 ") "
+ "via %s\n"),
+ (unsigned long long)referenced_from,
+ (unsigned long long)referenced_from,
+ ii->counted_links, inode_no, inode_no, why);
return 0;
}
- log_debug( _("No match found when incrementing link for %" PRIu64
- " (0x%" PRIx64 ")!\n"), inode_no, inode_no);
+ log_debug( _("Ref: %lld (0x%llx) No match found when incrementing "
+ "link for %" PRIu64 " (0x%" PRIx64 ")!\n"),
+ (unsigned long long)referenced_from,
+ (unsigned long long)referenced_from, inode_no, inode_no);
/* If no match was found, add a new entry and set its
* counted links to 1 */
ii = inodetree_insert(inode_no);
@@ -52,16 +59,24 @@ int increment_link(struct gfs2_sbd *sbp, uint64_t inode_no)
return 0;
}
-int decrement_link(struct gfs2_sbd *sbp, uint64_t inode_no)
+int decrement_link(uint64_t inode_no, uint64_t referenced_from,
+ const char *why)
{
struct inode_info *ii = NULL;
ii = inodetree_find(inode_no);
/* If the list has entries, look for one that matches
* inode_no */
- log_err( _("Decrementing %"PRIu64" (0x%" PRIx64 ")\n"), inode_no, inode_no);
+ log_err( _("Decrementing %"PRIu64" (0x%" PRIx64 ") to %d\n"),
+ inode_no, inode_no, ii->counted_links);
if(ii) {
ii->counted_links--;
+ log_debug( _("Directory %lld (0x%llx) decremented counted "
+ "links to %u for %"PRIu64" (0x%" PRIx64 ") "
+ "via %s\n"),
+ (unsigned long long)referenced_from,
+ (unsigned long long)referenced_from,
+ ii->counted_links, inode_no, inode_no, why);
return 0;
}
log_debug( _("No match found when decrementing link for %" PRIu64
diff --git a/gfs2/fsck/link.h b/gfs2/fsck/link.h
index 7446b4a..f890575 100644
--- a/gfs2/fsck/link.h
+++ b/gfs2/fsck/link.h
@@ -2,7 +2,9 @@
#define _LINK_H
int set_link_count(uint64_t inode_no, uint32_t count);
-int increment_link(struct gfs2_sbd *sbp, uint64_t inode_no);
-int decrement_link(struct gfs2_sbd *sbp, uint64_t inode_no);
+int increment_link(uint64_t inode_no, uint64_t referenced_from,
+ const char *why);
+int decrement_link(uint64_t inode_no, uint64_t referenced_from,
+ const char *why);
#endif /* _LINK_H */
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 2c8bbea..2eee341 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -46,10 +46,16 @@ int add_inode_to_lf(struct gfs2_inode *ip){
* this */
gfs2_blockmap_set(bl, lf_dip->i_di.di_num.no_addr,
gfs2_inode_dir);
- increment_link(ip->i_sbd,
- ip->i_sbd->md.rooti->i_di.di_num.no_addr);
- increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr);
- increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr);
+ /* root inode links to lost+found */
+ increment_link(ip->i_sbd->md.rooti->i_di.di_num.no_addr,
+ lf_dip->i_di.di_num.no_addr, _("root"));
+ /* lost+found link for '.' from itself */
+ increment_link(lf_dip->i_di.di_num.no_addr,
+ lf_dip->i_di.di_num.no_addr, "\".\"");
+ /* lost+found link for '..' back to root */
+ increment_link(lf_dip->i_di.di_num.no_addr,
+ ip->i_sbd->md.rooti->i_di.di_num.no_addr,
+ "\"..\"");
}
}
if(ip->i_di.di_num.no_addr == lf_dip->i_di.di_num.no_addr) {
@@ -111,9 +117,13 @@ int add_inode_to_lf(struct gfs2_inode *ip){
dir_add(lf_dip, tmp_name, strlen(tmp_name), &(ip->i_di.di_num),
inode_type);
- increment_link(ip->i_sbd, ip->i_di.di_num.no_addr);
+ /* This inode is linked from lost+found */
+ increment_link(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
+ _("from lost+found"));
+ /* If it's a directory, lost+found is back-linked to it via .. */
if(S_ISDIR(ip->i_di.di_mode))
- increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr);
+ increment_link(lf_dip->i_di.di_num.no_addr,
+ ip->i_di.di_mode, _("to lost+found"));
log_notice( _("Added inode #%llu to lost+found dir\n"),
(unsigned long long)ip->i_di.di_num.no_addr);
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 3052190..e04f73f 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -377,7 +377,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* FIXME: Should we continue on here
* and check the rest of the '.'
* entry? */
- increment_link(sbp, entryblock);
+ increment_link(entryblock,
+ ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -412,7 +414,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
log_err( _("Invalid '.' reference remains\n"));
/* Not setting ds->dotdir here since
* this '.' entry is invalid */
- increment_link(sbp, entryblock);
+ increment_link(entryblock,
+ ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -420,7 +424,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
ds->dotdir = 1;
- increment_link(sbp, entryblock);
+ increment_link(entryblock, ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
@@ -447,7 +452,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* FIXME: Should we continue on here
* and check the rest of the '..'
* entry? */
- increment_link(sbp, entryblock);
+ increment_link(entryblock,
+ ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -470,7 +477,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
return 1;
} else {
log_err( _("Bad '..' directory entry remains\n"));
- increment_link(sbp, entryblock);
+ increment_link(entryblock,
+ ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -487,7 +496,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
}
ds->dotdotdir = 1;
- increment_link(sbp, entryblock);
+ increment_link(entryblock, ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -496,7 +506,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
/* After this point we're only concerned with directories */
if(q != gfs2_inode_dir) {
log_debug( _("Found non-dir inode dentry\n"));
- increment_link(sbp, entryblock);
+ increment_link(entryblock, ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
return 0;
@@ -524,7 +535,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
stack;
return -1;
}
- increment_link(sbp, entryblock);
+ increment_link(entryblock, ip->i_di.di_num.no_addr,
+ _("valid reference"));
(*count)++;
ds->entry_count++;
/* End of checks */
@@ -601,8 +613,10 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
log_warn( _("Adding '.' entry\n"));
dir_add(sysinode, filename, filename_len,
&(sysinode->i_di.di_num), DT_DIR);
- increment_link(sysinode->i_sbd,
- sysinode->i_di.di_num.no_addr);
+ /* This system inode is linked to itself via '.' */
+ increment_link(sysinode->i_di.di_num.no_addr,
+ sysinode->i_di.di_num.no_addr,
+ "sysinode \".\"");
ds.entry_count++;
free(filename);
} else
@@ -781,8 +795,10 @@ int pass2(struct gfs2_sbd *sbp)
dir_add(ip, filename, filename_len,
&(ip->i_di.di_num), DT_DIR);
- increment_link(ip->i_sbd,
- ip->i_di.di_num.no_addr);
+ /* directory links to itself via '.' */
+ increment_link(ip->i_di.di_num.no_addr,
+ ip->i_di.di_num.no_addr,
+ _("\". (itself)\""));
ds.entry_count++;
free(filename);
log_err( _("The directory was fixed.\n"));
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 5f529f2..bef6d00 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -49,9 +49,9 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
if(gfs2_dirent_del(ip, filename, filename_len))
log_warn( _("Unable to remove \"..\" directory entry.\n"));
else
- decrement_link(sbp, olddotdot);
+ decrement_link(olddotdot, block, _("old \"..\""));
dir_add(ip, filename, filename_len, &pip->i_di.di_num, DT_DIR);
- increment_link(sbp, newdotdot);
+ increment_link(newdotdot, block, _("new \"..\""));
bmodified(ip->i_bh);
fsck_inode_put(&ip);
fsck_inode_put(&pip);
14 years, 3 months
cluster: STABLE3 - libgfs2: Get rid of useless constants
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: f25fe6a87d568285aa6f7cf6298f6f284e964977
Parent: 1bb481b4baea438c86df58584c825ba735aef3d1
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Fri Jan 22 08:38:59 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:30 2010 -0600
libgfs2: Get rid of useless constants
This patch eliminates a bunch of constants relating to block type.
They were not used except by subsequent declares, so they only
served to confuse things. It was one more thing that had to be
kept in sync.
rhbz#455300
---
gfs2/fsck/util.c | 12 -------
gfs2/libgfs2/libgfs2.h | 81 ++++++++++++++++++++++++++++--------------------
2 files changed, 47 insertions(+), 46 deletions(-)
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 9f2aae0..4622eea 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -79,18 +79,6 @@ void warm_fuzzy_stuff(uint64_t block)
}
}
-const char *block_type_string(uint8_t q)
-{
- const char *blktyp[] = {"free", "used", "indirect data", "inode",
- "file", "symlink", "block dev", "char dev",
- "fifo", "socket", "dir leaf", "journ data",
- "other meta", "eattribute", "unused",
- "invalid"};
- if (q < 16)
- return (blktyp[q]);
- return blktyp[15];
-}
-
/* fsck_query: Same as gfs2_query except it adjusts errors_found and
errors_corrected. */
int fsck_query(const char *format, ...)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 4fbc4e1..3a6c61e 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -263,43 +263,56 @@ struct gfs2_bmap {
};
/* block_list.c */
-#define FREE (0x0) /* 0000 */
-#define BLOCK_IN_USE (0x1) /* 0001 */
-#define DIR_INDIR_BLK (0x2) /* 0010 */
-#define DIR_INODE (0x3) /* 0011 */
-#define FILE_INODE (0x4) /* 0100 */
-#define LNK_INODE (0x5)
-#define BLK_INODE (0x6)
-#define CHR_INODE (0x7)
-#define FIFO_INODE (0x8)
-#define SOCK_INODE (0x9)
-#define DIR_LEAF_INODE (0xA) /* 1010 */
-#define JOURNAL_BLK (0xB) /* 1011 */
-#define OTHER_META (0xC) /* 1100 */
-#define EATTR_META (0xD) /* 1101 */
-#define BAD_BLOCK (0xE) /* 1110 */
-#define INVALID_META (0xF) /* 1111 */
-
-/* Must be kept in sync with mark_to_bitmap array in block_list.c */
+
enum gfs2_mark_block {
- gfs2_block_free = FREE,
- gfs2_block_used = BLOCK_IN_USE,
- gfs2_indir_blk = DIR_INDIR_BLK,
- gfs2_inode_dir = DIR_INODE,
- gfs2_inode_file = FILE_INODE,
- gfs2_inode_lnk = LNK_INODE,
- gfs2_inode_blk = BLK_INODE,
- gfs2_inode_chr = CHR_INODE,
- gfs2_inode_fifo = FIFO_INODE,
- gfs2_inode_sock = SOCK_INODE,
- gfs2_leaf_blk = DIR_LEAF_INODE,
- gfs2_journal_blk = JOURNAL_BLK,
- gfs2_meta_other = OTHER_META,
- gfs2_meta_eattr = EATTR_META,
- gfs2_bad_block = BAD_BLOCK, /* Contains at least one bad block */
- gfs2_meta_inval = INVALID_META,
+ 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_journal_blk = (0xa),
+ gfs2_meta_inval = (0xb),
+ gfs2_leaf_blk = (0xc),
+ gfs2_meta_other = (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",
+
+ "journaled data",
+ "invalid meta",
+ "dir leaf",
+ "other metadata",
+ "eattribute",
+
+ "bad"};
+ if (q < 16)
+ return (blktyp[q]);
+ return blktyp[15];
+}
+
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);
14 years, 3 months
cluster: STABLE3 - fsck.gfs2: fix directories that have odd number of pointers.
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 1bb481b4baea438c86df58584c825ba735aef3d1
Parent: 1f8086a6382a337bc4febab691b83a7ce673e266
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 23:10:23 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:30 2010 -0600
fsck.gfs2: fix directories that have odd number of pointers.
Directory dinodes in gfs2 use the "depth" field to determine the
number of pointers in the hash table. The depth must be a
factor of 2. So 2, 4, 8, 16, etc. That's because the hash table
is doubled every time it gets full. The problem is, fsck.gfs2
previously had no checks for the depth being correct and/or
the hash table pointers being multiples of two. Needless to say,
the directory code gets very confused if this condition is not
met due to corruption. This patch introduces new code to
validate the depth is correct and fix the depth and/or pointers
if they're not.
rhbz#455300
---
gfs2/fsck/metawalk.c | 133 ++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 113 insertions(+), 20 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 7ba8e39..8b75311 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -332,6 +332,61 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
*leaf_no = old_leaf;
}
+/*
+ * fix_leaf_pointers - fix a directory dinode that has a number of pointers
+ * that is not a multiple of 2.
+ * dip - the directory inode having the problem
+ * lindex - the index of the leaf right after the problem (need to back up)
+ * cur_numleafs - current (incorrect) number of instances of the leaf block
+ * correct_numleafs - the correct number instances of the leaf block
+ */
+static int fix_leaf_pointers(struct gfs2_inode *dip, int *lindex,
+ int cur_numleafs, int correct_numleafs)
+{
+ int count;
+ char *ptrbuf;
+ int start_lindex = *lindex - cur_numleafs; /* start of bad ptrs */
+ int tot_num_ptrs = (1 << dip->i_di.di_depth) - start_lindex;
+ int bufsize = tot_num_ptrs * sizeof(uint64_t);
+ int off_by = cur_numleafs - correct_numleafs;
+
+ ptrbuf = malloc(bufsize);
+ if (!ptrbuf) {
+ log_err( _("Error: Cannot allocate memory to fix the leaf "
+ "pointers.\n"));
+ return -1;
+ }
+ /* Read all the pointers, starting with the first bad one */
+ count = gfs2_readi(dip, ptrbuf, start_lindex * sizeof(uint64_t),
+ bufsize);
+ if (count != bufsize) {
+ log_err( _("Error: bad read while fixing leaf pointers.\n"));
+ free(ptrbuf);
+ return -1;
+ }
+
+ bufsize -= off_by * sizeof(uint64_t); /* We need to write fewer */
+ /* Write the same pointers, but offset them so they fit within the
+ smaller factor of 2. So if we have 12 pointers, write out only
+ the last 8 of them. If we have 7, write the last 4, etc.
+ We need to write these starting at the current lindex and adjust
+ lindex accordingly. */
+ count = gfs2_writei(dip, ptrbuf + (off_by * sizeof(uint64_t)),
+ start_lindex * sizeof(uint64_t), bufsize);
+ if (count != bufsize) {
+ log_err( _("Error: bad read while fixing leaf pointers.\n"));
+ free(ptrbuf);
+ return -1;
+ }
+ /* Now zero out the hole left at the end */
+ memset(ptrbuf, 0, off_by * sizeof(uint64_t));
+ gfs2_writei(dip, ptrbuf, (start_lindex * sizeof(uint64_t)) +
+ bufsize, off_by * sizeof(uint64_t));
+ free(ptrbuf);
+ *lindex -= off_by; /* adjust leaf index to account for the change */
+ return 0;
+}
+
/* Checks exhash directory entries */
static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
{
@@ -382,33 +437,71 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
ref_count++;
continue;
}
- if (gfs2_check_range(ip->i_sbd, old_leaf) == 0 &&
- ref_count != exp_count) {
- log_err( _("Dir #%llu (0x%llx) has an incorrect "
- "number of pointers to leaf #%llu "
- " (0x%llx)\n\tFound: %u, Expected: "
- "%u\n"), (unsigned long long)
- ip->i_di.di_num.no_addr,
- (unsigned long long)
- ip->i_di.di_num.no_addr,
- (unsigned long long)old_leaf,
- (unsigned long long)old_leaf,
- ref_count, exp_count);
- if (query( _("Attempt to fix it? (y/n) "))) {
- int factor = 0, divisor = ref_count;
-
- lbh = bread(sbp, old_leaf);
- while (divisor > 1) {
- factor++;
- divisor /= 2;
+ if (gfs2_check_range(ip->i_sbd, old_leaf) == 0) {
+ int factor = 0, divisor = ref_count, multiple = 1;
+
+ /* Check to see if the number of pointers we found is
+ a power of 2. It needs to be and if it's not we
+ need to fix it.*/
+ while (divisor > 1) {
+ factor++;
+ divisor /= 2;
+ multiple = multiple << 1;
+ }
+ if (ref_count != multiple) {
+ log_err( _("Directory #%llu (0x%llx) has an "
+ "invalid number of pointers to "
+ "leaf #%llu (0x%llx)\n\tFound: %u, "
+ "which is not a factor of 2.\n"),
+ (unsigned long long)
+ ip->i_di.di_num.no_addr,
+ (unsigned long long)
+ ip->i_di.di_num.no_addr,
+ (unsigned long long)old_leaf,
+ (unsigned long long)old_leaf,
+ ref_count);
+ if (!query( _("Attempt to fix it? (y/n) "))) {
+ log_err( _("Directory inode was not "
+ "fixed.\n"));
+ return 1;
}
+ error = fix_leaf_pointers(ip, &lindex,
+ ref_count, multiple);
+ if (error)
+ return error;
+ ref_count = multiple;
+ log_err( _("Directory inode was fixed.\n"));
+ }
+ /* Check to see if the counted number of leaf pointers
+ is what we expect. */
+ if (ref_count != exp_count) {
+ log_err( _("Directory #%llu (0x%llx) has an "
+ "incorrect number of pointers to "
+ "leaf #%llu (0x%llx)\n\tFound: "
+ "%u, Expected: %u\n"),
+ (unsigned long long)
+ ip->i_di.di_num.no_addr,
+ (unsigned long long)
+ ip->i_di.di_num.no_addr,
+ (unsigned long long)old_leaf,
+ (unsigned long long)old_leaf,
+ ref_count, exp_count);
+ if (!query( _("Attempt to fix it? (y/n) "))) {
+ log_err( _("Directory leaf was not "
+ "fixed.\n"));
+ return 1;
+ }
+ lbh = bread(sbp, old_leaf);
gfs2_leaf_in(&oldleaf, lbh);
+ log_err( _("Leaf depth was %d, changed to "
+ "%d\n"), oldleaf.lf_depth,
+ ip->i_di.di_depth - factor);
oldleaf.lf_depth = ip->i_di.di_depth - factor;
gfs2_leaf_out(&oldleaf, lbh);
brelse(lbh);
+ exp_count = ref_count;
+ log_err( _("Directory leaf was fixed.\n"));
}
- else
- return 1;
}
ref_count = 1;
14 years, 3 months
cluster: STABLE3 - fsck.gfs2: Journal replay should report what it's doing
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 1f8086a6382a337bc4febab691b83a7ce673e266
Parent: 00652ee37168d9831d04012e767e8923309d0575
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 18:07:06 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:30 2010 -0600
fsck.gfs2: Journal replay should report what it's doing
When replaying the journals, fsck.gfs2 needs to report what it's
doing, if -v is specified.
rhbz#455300
---
gfs2/fsck/fs_recovery.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 893b622..ce3aaa5 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -118,6 +118,10 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
if (error)
return error;
+ log_info( _("Journal replay writing metadata block #"
+ "%lld (0x%llx) for journal+0x%x\n"),
+ (unsigned long long)blkno, (unsigned long long)blkno,
+ start);
bh_ip = bget(sdp, blkno);
memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize);
@@ -168,6 +172,11 @@ static int revoke_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
}
while (offset + sizeof(uint64_t) <= sdp->sd_sb.sb_bsize) {
blkno = be64_to_cpu(*(__be64 *)(bh->b_data + offset));
+ log_info( _("Journal replay processing revoke for "
+ "block #%lld (0x%llx) for journal+0x%x\n"),
+ (unsigned long long)blkno,
+ (unsigned long long)blkno,
+ start);
error = gfs2_revoke_add(sdp, blkno, start);
if (error < 0)
return error;
@@ -217,6 +226,10 @@ static int databuf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
if (error)
return error;
+ log_info( _("Journal replay writing data block #%lld (0x%llx)"
+ " for journal+0x%x\n"),
+ (unsigned long long)blkno, (unsigned long long)blkno,
+ start);
bh_ip = bget(sdp, blkno);
memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize);
14 years, 3 months
cluster: STABLE3 - fsck.gfs2: should use the libgfs2 is_system_directory
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 00652ee37168d9831d04012e767e8923309d0575
Parent: 6f711c7174cdf863bc5a5c9f497270114dab7413
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 17:55:59 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:30 2010 -0600
fsck.gfs2: should use the libgfs2 is_system_directory
The fsck.gfs2 program had its own implementation of the standard
function to determine if a dinode in memory was one of the system
dinodes. The difference was that the fsck.gfs2 version ignored
the journal inodes and instead checked the lost+found dinode.
This has been standardized.
rhbz#455300
---
gfs2/fsck/metawalk.c | 38 +++++++++++---------------------------
1 files changed, 11 insertions(+), 27 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index fa332de..7ba8e39 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -16,30 +16,6 @@
#define COMFORTABLE_BLKS 5242880 /* 20GB in 4K blocks */
-static struct gfs2_inode *get_system_inode(struct gfs2_sbd *sbp,
- uint64_t block)
-{
- if (block == sbp->md.inum->i_di.di_num.no_addr)
- return sbp->md.inum;
- if (block == sbp->md.statfs->i_di.di_num.no_addr)
- return sbp->md.statfs;
- if (block == sbp->md.jiinode->i_di.di_num.no_addr)
- return sbp->md.jiinode;
- if (block == sbp->md.riinode->i_di.di_num.no_addr)
- return sbp->md.riinode;
- if (block == sbp->md.qinode->i_di.di_num.no_addr)
- return sbp->md.qinode;
- if (block == sbp->md.pinode->i_di.di_num.no_addr)
- return sbp->md.pinode;
- if (block == sbp->md.rooti->i_di.di_num.no_addr)
- return sbp->md.rooti;
- if (block == sbp->master_dir->i_di.di_num.no_addr)
- return sbp->master_dir;
- if (lf_dip && block == lf_dip->i_di.di_num.no_addr)
- return lf_dip;
- return is_system_inode(sbp, block);
-}
-
struct duptree *dupfind(uint64_t block)
{
struct osi_node *node = dup_blocks.osi_node;
@@ -57,13 +33,21 @@ struct duptree *dupfind(uint64_t block)
return NULL;
}
+static struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
+ uint64_t block)
+{
+ if (lf_dip && lf_dip->i_di.di_num.no_addr == block)
+ return lf_dip;
+ return is_system_inode(sdp, block);
+}
+
/* fsck_load_inode - same as gfs2_load_inode() in libgfs2 but system inodes
get special treatment. */
struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block)
{
struct gfs2_inode *ip = NULL;
- ip = get_system_inode(sbp, block);
+ ip = fsck_system_inode(sbp, block);
if (ip)
return ip;
return inode_read(sbp, block);
@@ -76,7 +60,7 @@ struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
{
struct gfs2_inode *sysip;
- sysip = get_system_inode(sdp, bh->b_blocknr);
+ sysip = fsck_system_inode(sdp, bh->b_blocknr);
if (sysip)
return sysip;
@@ -90,7 +74,7 @@ void fsck_inode_put(struct gfs2_inode **ip_in)
struct gfs2_inode *ip = *ip_in;
struct gfs2_inode *sysip;
- sysip = get_system_inode(ip->i_sbd, ip->i_di.di_num.no_addr);
+ sysip = fsck_system_inode(ip->i_sbd, ip->i_di.di_num.no_addr);
if (!sysip)
inode_put(ip_in);
}
14 years, 3 months
cluster: STABLE3 - libgfs2: Set block range based on rgrps, not device size
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 6f711c7174cdf863bc5a5c9f497270114dab7413
Parent: 3e89cfb766711d210e23284206b791eee71273f7
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 17:35:33 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:29 2010 -0600
libgfs2: Set block range based on rgrps, not device size
The functions that read in the rindex need to set the block
range properly, rather than basing it on the device size.
If not, bad block pointers might reference blocks beyond the
end of the file system (as can happen if a device is extended
before gfs2_grow is run), or if a different metadata set is
restored with gfs2_edit restoremeta.
rhbz#455300
---
gfs2/libgfs2/gfs1.c | 1 +
gfs2/libgfs2/super.c | 4 ++++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 5cced66..5018334 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -315,6 +315,7 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
rmax = ri->ri_data0 + ri->ri_data - 1;
}
+ sdp->fssize = rmax;
*rgcount = count1;
if (count1 != count2)
goto fail;
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index ca7bf09..1fa18ce 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -229,6 +229,7 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
osi_list_t *tmp;
int count1 = 0, count2 = 0;
uint64_t errblock = 0;
+ uint64_t rmax = 0;
if (rindex_read(sdp, fd, &count1))
goto fail;
@@ -238,9 +239,12 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
if (errblock)
return errblock;
ri = &rgd->ri;
+ if (ri->ri_data0 + ri->ri_data - 1 > rmax)
+ rmax = ri->ri_data0 + ri->ri_data - 1;
count2++;
}
+ sdp->fssize = rmax;
*rgcount = count1;
if (count1 != count2)
goto fail;
14 years, 3 months
cluster: STABLE3 - libgfs2: dir_split_leaf needs to check for allocation failure
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 3e89cfb766711d210e23284206b791eee71273f7
Parent: 53028729cd3b8987ee498d486c6cae37c60b808b
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 17:22:55 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:29 2010 -0600
libgfs2: dir_split_leaf needs to check for allocation failure
When splitting directory leaf blocks, if an allocation fails
for some reason (e.g. corruption) it should throw an error
rather than plowing forward.
rhbz#455300
---
gfs2/libgfs2/fs_ops.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 3fc80ce..35721fa 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -899,7 +899,8 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
be32_to_cpu(dent->de_hash) < divider) {
name_len = be16_to_cpu(dent->de_name_len);
- dirent_alloc(dip, nbh, name_len, &new);
+ if (dirent_alloc(dip, nbh, name_len, &new))
+ die("dir_split_leaf (3)\n");
new->de_inum = dent->de_inum;
new->de_hash = dent->de_hash;
@@ -925,7 +926,8 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
} while (dent);
if (!moved) {
- dirent_alloc(dip, nbh, 0, &new);
+ if (dirent_alloc(dip, nbh, 0, &new))
+ die("dir_split_leaf (4)\n");
new->de_inum.no_formal_ino = 0;
}
@@ -1105,7 +1107,8 @@ restart:
nleaf->lf_depth = leaf->lf_depth;
nleaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
- dirent_alloc(dip, nbh, len, &dent);
+ if (dirent_alloc(dip, nbh, len, &dent))
+ die("dir_split_leaf (3)\n");
dip->i_di.di_blocks++;
bmodified(dip->i_bh);
bmodified(bh);
14 years, 3 months
cluster: STABLE3 - libgfs2: dir_split_leaf needs to zero out the new leaf
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 53028729cd3b8987ee498d486c6cae37c60b808b
Parent: 7fd936c0f96689f53c58341bf5ea20a37a119911
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 17:15:24 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:29 2010 -0600
libgfs2: dir_split_leaf needs to zero out the new leaf
The dir_split_leaf function was not clearing out the new leaf
block it had allocated, so there was likely to be trash left
on the block. Granted, this is pretty rare, but I actually
saw it in a situation where lots of orphaned dinodes were
tossed into lost+found.
rhbz#455300
---
gfs2/libgfs2/fs_ops.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index bc8319e..3fc80ce 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -856,6 +856,8 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
mh.mh_type = GFS2_METATYPE_LF;
mh.mh_format = GFS2_FORMAT_LF;
gfs2_meta_header_out(&mh, nbh);
+ buffer_clear_tail(dip->i_sbd, nbh,
+ sizeof(struct gfs2_meta_header));
}
nleaf = (struct gfs2_leaf *)nbh->b_data;
14 years, 3 months
cluster: STABLE3 - libgfs2: Remove unneeded sdp parameter in gfs2_block_set
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 7fd936c0f96689f53c58341bf5ea20a37a119911
Parent: 25541883d8844c4cfcac59346a211c897a84bbb6
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 17:07:41 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:29 2010 -0600
libgfs2: Remove unneeded sdp parameter in gfs2_block_set
Function gfs2_blockmap_set does not use the sdp parameter, so
it only was wasting time passing it. Therefore I removed it.
Again, this may not seem like much, but it's called for every
allocated block, which numbers in the millions.
rhbz#455300
---
gfs2/edit/savemeta.c | 2 +-
gfs2/fsck/eattr.c | 2 +-
gfs2/fsck/lost_n_found.c | 4 +-
gfs2/fsck/main.c | 10 +++----
gfs2/fsck/metawalk.c | 8 +++---
gfs2/fsck/pass1.c | 59 ++++++++++++++++++++++-----------------------
gfs2/fsck/pass1b.c | 22 +++++++----------
gfs2/fsck/pass2.c | 12 ++++----
gfs2/fsck/pass3.c | 8 +++---
gfs2/fsck/pass4.c | 12 ++++----
gfs2/libgfs2/block_list.c | 4 +-
gfs2/libgfs2/libgfs2.h | 4 +-
12 files changed, 70 insertions(+), 77 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index a69816f..3e7ec7e 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -642,7 +642,7 @@ void savemeta(char *out_fn, int saveoption)
(unsigned long long)rgd->ri.ri_addr,
rgd->ri.ri_length);
for (i = 0; i < rgd->ri.ri_length; i++) {
- if(gfs2_blockmap_set(&sbd, blocklist,
+ if(gfs2_blockmap_set(blocklist,
rgd->ri.ri_addr + i,
gfs2_meta_other))
break;
diff --git a/gfs2/fsck/eattr.c b/gfs2/fsck/eattr.c
index 6be4fa3..199bc46 100644
--- a/gfs2/fsck/eattr.c
+++ b/gfs2/fsck/eattr.c
@@ -15,7 +15,7 @@ static int clear_blk_nodup(struct gfs2_sbd *sbp, uint64_t block)
return 1;
}
- gfs2_blockmap_set(sbp, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(bl, block, gfs2_block_free);
return 0;
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 25dec6c..2c8bbea 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -44,8 +44,8 @@ int add_inode_to_lf(struct gfs2_inode *ip){
* directory or just found an old one, and we
* used that instead of the block_type to run
* this */
- gfs2_blockmap_set(ip->i_sbd, bl,
- lf_dip->i_di.di_num.no_addr, gfs2_inode_dir);
+ gfs2_blockmap_set(bl, lf_dip->i_di.di_num.no_addr,
+ gfs2_inode_dir);
increment_link(ip->i_sbd,
ip->i_sbd->md.rooti->i_di.di_num.no_addr);
increment_link(ip->i_sbd, lf_dip->i_di.di_num.no_addr);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index ffac5e7..25c36ad 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -169,9 +169,8 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
/* Just reuse the inode and fix the bitmap. */
if (ds.q == gfs2_block_free) {
log_info( _("The inode exists but the block is not marked 'in use'; fixing it.\n"));
- gfs2_blockmap_set(sysinode->i_sbd, bl,
- sysinode->i_di.di_num.no_addr,
- mark);
+ gfs2_blockmap_set(bl,sysinode->i_di.di_num.no_addr,
+ mark);
ds.q = mark;
if (mark == gfs2_inode_dir)
dirtree_insert(sysinode->i_di.di_num.no_addr);
@@ -187,9 +186,8 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
log_err( _("Invalid or missing %s system inode.\n"), filename);
if (query(_("Create new %s system inode? (y/n) "), filename)) {
builder(sysinode->i_sbd);
- gfs2_blockmap_set(sysinode->i_sbd, bl,
- sysinode->i_di.di_num.no_addr,
- mark);
+ gfs2_blockmap_set(bl, sysinode->i_di.di_num.no_addr,
+ mark);
ds.q = mark;
if (mark == gfs2_inode_dir)
dirtree_insert(sysinode->i_di.di_num.no_addr);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index d5a29b7..fa332de 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -615,7 +615,7 @@ static int check_eattr_entries(struct gfs2_inode *ip,
/* Endianness doesn't matter
in this case because it's
a single byte. */
- gfs2_blockmap_set(sdp, bl,
+ gfs2_blockmap_set(bl,
ip->i_di.di_eattr,
gfs2_meta_eattr);
log_err( _("The EA was "
@@ -769,8 +769,8 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
if (indirect_buf->b_modified)
gfs2_set_bitmap(sdp, indirect,
GFS2_BLKST_FREE);
- gfs2_blockmap_set(sdp, bl, indirect,
- gfs2_block_free);
+ gfs2_blockmap_set(bl, indirect,
+ gfs2_block_free);
error = 1;
}
}
@@ -1128,7 +1128,7 @@ int delete_blocks(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)block,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(bl, block, gfs2_block_free);
gfs2_free_block(ip->i_sbd, block);
}
}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index ba5206d..7563d60 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -79,7 +79,7 @@ static int leaf(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)block, (unsigned long long)block);
- gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_leaf_blk);
+ gfs2_blockmap_set(bl, block, gfs2_leaf_blk);
bc->indir_count++;
return 0;
}
@@ -95,7 +95,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
*bh = NULL;
if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
- gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
gfs2_bad_block);
log_debug( _("Bad indirect block pointer (out of range).\n"));
@@ -114,7 +114,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
log_debug( _("Bad indirect block pointer (points to "
"something that is not an indirect block).\n"));
if(!found_dup) {
- gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_meta_inval);
+ gfs2_blockmap_set(bl, block, gfs2_meta_inval);
brelse(nbh);
return 1;
}
@@ -125,7 +125,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
if (!found_dup) {
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to indirect "
"block.\n"), block, block);
- gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_indir_blk);
+ gfs2_blockmap_set(bl, block, gfs2_indir_blk);
}
bc->indir_count++;
@@ -147,7 +147,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
/* Mark the owner of this block with the bad_block
* designator so we know to check it for out of range
* blocks later */
- gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
gfs2_bad_block);
return 1;
}
@@ -178,7 +178,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
}
log_debug( _("Marking block %llu (0x%llx) as data block\n"),
(unsigned long long)block, (unsigned long long)block);
- gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_used);
+ gfs2_blockmap_set(bl, block, gfs2_block_used);
/* This is also confusing, so I'll clarify. There are two bitmaps:
(1) The gfs2_bmap that fsck uses to keep track of what block
@@ -221,8 +221,7 @@ static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc,
if (!duplicate) {
gfs2_set_bitmap(ip->i_sbd, ip->i_di.di_eattr,
GFS2_BLKST_FREE);
- gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_eattr,
- gfs2_block_free);
+ gfs2_blockmap_set(bl, ip->i_di.di_eattr, gfs2_block_free);
}
ip->i_di.di_eattr = 0;
bc->ea_count = 0;
@@ -276,7 +275,7 @@ static int clear_eas(struct gfs2_inode *ip, struct block_count *bc,
log_err( _("The bad extended attribute was "
"removed.\n"));
} else if (!duplicate) {
- gfs2_blockmap_set(sdp, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(bl, block, gfs2_block_free);
gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
log_err( _("The bad Extended Attribute was "
"removed.\n"));
@@ -303,7 +302,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
if(gfs2_check_range(sdp, indirect)) {
/*log_warn("EA indirect block #%"PRIu64" is out of range.\n",
indirect);
- gfs2_blockmap_set(sdp, bl, parent, bad_block);*/
+ gfs2_blockmap_set(bl, parent, bad_block);*/
/* Doesn't help to mark this here - this gets checked
* in pass1c */
return 1;
@@ -345,7 +344,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
log_debug( _("Setting #%" PRIu64 " (0x%" PRIx64
") to indirect Extended Attribute block\n"),
indirect, indirect);
- gfs2_blockmap_set(sdp, bl, indirect, gfs2_indir_blk);
+ gfs2_blockmap_set(bl, indirect, gfs2_indir_blk);
bc->ea_count++;
}
return ret;
@@ -432,7 +431,7 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
/* Point of confusion: We've got to set the ea block itself to
gfs2_meta_eattr here. Elsewhere we mark the inode with
gfs2_eattr_block meaning it contains an eattr for pass1c. */
- gfs2_blockmap_set(sdp, bl, block, gfs2_meta_eattr);
+ gfs2_blockmap_set(bl, block, gfs2_meta_eattr);
bc->ea_count++;
*bh = leaf_bh;
return 0;
@@ -470,7 +469,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
(unsigned long long)ip->i_di.di_eattr,
(unsigned long long)el_blk,
(unsigned long long)el_blk);
- gfs2_blockmap_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block);
+ gfs2_blockmap_set(bl, ip->i_di.di_eattr, gfs2_bad_block);
return 1;
}
error = check_leaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh, private);
@@ -501,7 +500,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)block, (unsigned long long)block);
- gfs2_blockmap_set(sdp, bl, ip->i_di.di_eattr, gfs2_bad_block);
+ gfs2_blockmap_set(bl, ip->i_di.di_eattr, gfs2_bad_block);
return 1;
}
return check_leaf_block(ip, block, GFS2_METATYPE_EA, bh, private);
@@ -554,7 +553,7 @@ static int clear_metalist(struct gfs2_inode *ip, uint64_t block,
*bh = NULL;
if(!is_duplicate(block)) {
- gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(bl, block, gfs2_block_free);
return 0;
}
return 0;
@@ -563,7 +562,7 @@ static int clear_metalist(struct gfs2_inode *ip, uint64_t block,
static int clear_data(struct gfs2_inode *ip, uint64_t block, void *private)
{
if(!is_duplicate(block)) {
- gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free);
+ gfs2_blockmap_set(bl, block, gfs2_block_free);
return 0;
}
return 0;
@@ -579,7 +578,7 @@ static int clear_leaf(struct gfs2_inode *ip, uint64_t block,
if(!is_duplicate(block)) {
log_crit( _("Setting leaf #%" PRIu64 " (0x%" PRIx64 ") invalid\n"),
block, block);
- if(gfs2_blockmap_set(ip->i_sbd, bl, block, gfs2_block_free)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_block_free)) {
stack;
return -1;
}
@@ -633,7 +632,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFDIR:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to directory inode.\n"),
block, block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_dir)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_inode_dir)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -647,7 +646,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFREG:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to file inode.\n"),
block, block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_file)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_inode_file)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -656,7 +655,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFLNK:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to symlink inode.\n"),
block, block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_lnk)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_inode_lnk)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -665,7 +664,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFBLK:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to block dev inode.\n"),
block, block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_blk)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_inode_blk)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -674,7 +673,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFCHR:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to char dev inode.\n"),
block, block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_chr)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_inode_chr)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -683,7 +682,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFIFO:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to fifo inode.\n"),
block, block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_fifo)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_inode_fifo)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -692,7 +691,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
case S_IFSOCK:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to socket inode.\n"),
block, block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_inode_sock)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_inode_sock)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -701,7 +700,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
default:
log_debug( _("Setting %" PRIu64 " (0x%" PRIx64 ") to invalid.\n"),
block, block);
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_meta_inval)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_meta_inval)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -727,7 +726,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
(1 >> (ip->i_di.di_size/sizeof(uint64_t))));
/* once implemented, remove continue statement */
log_warn( _("Marking inode invalid\n"));
- if(gfs2_blockmap_set(sdp, bl, block, gfs2_meta_inval)) {
+ if(gfs2_blockmap_set(bl, block, gfs2_meta_inval)) {
stack;
fsck_inode_put(&ip);
return -1;
@@ -751,8 +750,8 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh,
(unsigned long long)ip->i_di.di_num.no_addr);
/* FIXME: Must set all leaves invalid as well */
check_metatree(ip, &invalidate_metatree);
- gfs2_blockmap_set(sdp, bl, ip->i_di.di_num.no_addr,
- gfs2_meta_inval);
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
+ gfs2_meta_inval);
gfs2_set_bitmap(sdp, ip->i_di.di_num.no_addr, GFS2_BLKST_FREE);
fsck_inode_put(&ip);
return 0;
@@ -843,8 +842,8 @@ int pass1(struct gfs2_sbd *sbp)
rg_count);
rgd = osi_list_entry(tmp, struct rgrp_list, list);
for (i = 0; i < rgd->ri.ri_length; i++) {
- if(gfs2_blockmap_set(sbp, bl, rgd->ri.ri_addr + i,
- gfs2_meta_other)){
+ if(gfs2_blockmap_set(bl, rgd->ri.ri_addr + i,
+ gfs2_meta_other)){
stack;
return FSCK_ERROR;
}
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 1ee0ebd..728ec8b 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -165,8 +165,8 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block,
dh->id->parent);
/* Setting the block to invalid means the inode is
* cleared in pass2 */
- gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
- gfs2_meta_inval);
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
+ gfs2_meta_inval);
}
return 0;
}
@@ -197,8 +197,7 @@ static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block,
log_err( _("Inode %s is in directory %" PRIu64 " (0x%" PRIx64 ")\n"),
dh->id->name ? dh->id->name : "",
dh->id->parent, dh->id->parent);
- gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_eattr,
- gfs2_meta_inval);
+ gfs2_blockmap_set(bl, ip->i_di.di_eattr, gfs2_meta_inval);
}
return 0;
@@ -224,8 +223,7 @@ static int clear_dup_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
dh->id->name ? dh->id->name : "",
dh->id->parent, dh->id->parent);
/* mark the main eattr block invalid */
- gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_eattr,
- gfs2_meta_inval);
+ gfs2_blockmap_set(bl, ip->i_di.di_eattr, gfs2_meta_inval);
}
return 0;
@@ -295,8 +293,7 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
dh->id->name ? dh->id->name : "",
dh->id->parent, dh->id->parent);
/* mark the main eattr block invalid */
- gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_eattr,
- gfs2_meta_inval);
+ gfs2_blockmap_set(bl, ip->i_di.di_eattr, gfs2_meta_inval);
}
return 0;
@@ -418,9 +415,8 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
inodetree_delete(ii);
/* Setting the block to invalid means the inode
is cleared in pass2 */
- gfs2_blockmap_set(ip->i_sbd, bl,
- ip->i_di.di_num.no_addr,
- gfs2_meta_inval);
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
+ gfs2_meta_inval);
bmodified(ip->i_bh);
fsck_inode_put(&ip);
} else {
@@ -465,8 +461,8 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
if(!id->ea_only)
check_metatree(ip, &clear_dup_fxns);
- gfs2_blockmap_set(ip->i_sbd, bl, ip->i_di.di_num.no_addr,
- gfs2_meta_inval);
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
+ gfs2_meta_inval);
fsck_inode_put(&ip); /* out, brelse, free */
dh.ref_inode_count--;
if(dh.ref_inode_count == 1)
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index a368124..3052190 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -186,8 +186,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
"\tName length = %u\n"),
de->de_rec_len,
de->de_name_len);
- gfs2_blockmap_set(sbp, bl, ip->i_di.di_num.no_addr,
- gfs2_meta_inval);
+ gfs2_blockmap_set(bl, ip->i_di.di_num.no_addr,
+ gfs2_meta_inval);
return 1;
/* FIXME: should probably delete the entry here at the
* very least - maybe look at attempting to fix it */
@@ -255,7 +255,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
bmodified(entry_ip->i_bh);
fsck_inode_put(&entry_ip);
dirent2_del(ip, bh, prev_de, dent);
- gfs2_blockmap_set(sbp, bl, entryblock, gfs2_block_free);
+ gfs2_blockmap_set(bl, entryblock, gfs2_block_free);
bmodified(bh);
log_warn( _("The inode containing bad blocks was "
"deleted.\n"));
@@ -306,7 +306,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
check_metatree(entry_ip, &pass2_fxns_delete);
bmodified(entry_ip->i_bh);
fsck_inode_put(&entry_ip);
- gfs2_blockmap_set(sbp, bl, entryblock, gfs2_block_free);
+ gfs2_blockmap_set(bl, entryblock, gfs2_block_free);
return 1;
} else {
@@ -575,7 +575,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
return -1;
}
if (error > 0)
- gfs2_blockmap_set(sysinode->i_sbd, bl, iblock, gfs2_meta_inval);
+ gfs2_blockmap_set(bl, iblock, gfs2_meta_inval);
if(check_inode_eattr(sysinode, &pass2_fxns)) {
stack;
@@ -753,7 +753,7 @@ int pass2(struct gfs2_sbd *sbp)
} else
log_err( _("Directory entry to invalid inode remains.\n"));
}
- gfs2_blockmap_set(sbp, bl, dirblk, gfs2_meta_inval);
+ gfs2_blockmap_set(bl, dirblk, gfs2_meta_inval);
}
ip = fsck_load_inode(sbp, dirblk);
if(!ds.dotdir) {
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index fd34de2..5f529f2 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -201,7 +201,7 @@ int pass3(struct gfs2_sbd *sbp)
log_err( _("Found unlinked directory containing bad block\n"));
if(query(
_("Clear unlinked directory with bad blocks? (y/n) "))) {
- gfs2_blockmap_set(sbp, bl,
+ gfs2_blockmap_set(bl,
di->dinode,
gfs2_block_free);
break;
@@ -216,8 +216,8 @@ int pass3(struct gfs2_sbd *sbp)
q != gfs2_inode_fifo &&
q != gfs2_inode_sock) {
log_err( _("Unlinked block marked as inode not an inode\n"));
- gfs2_blockmap_set(sbp, bl, di->dinode,
- gfs2_block_free);
+ gfs2_blockmap_set(bl, di->dinode,
+ gfs2_block_free);
log_err( _("Cleared\n"));
break;
}
@@ -230,7 +230,7 @@ int pass3(struct gfs2_sbd *sbp)
if(!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err( _("Unlinked directory has zero size.\n"));
if(query( _("Remove zero-size unlinked directory? (y/n) "))) {
- gfs2_blockmap_set(sbp, bl,
+ gfs2_blockmap_set(bl,
di->dinode,
gfs2_block_free);
fsck_inode_put(&ip);
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index efcf70d..d275ecf 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -72,8 +72,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp) {
check_metatree(ip, &pass4_fxns_delete);
bmodified(ip->i_bh);
fsck_inode_put(&ip);
- gfs2_blockmap_set(sbp, bl, ii->inode,
- gfs2_block_free);
+ gfs2_blockmap_set(bl, ii->inode,
+ gfs2_block_free);
continue;
} else
log_err( _("Unlinked inode with bad blocks not cleared\n"));
@@ -96,8 +96,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp) {
&pass4_fxns_delete);
check_metatree(ip, &pass4_fxns_delete);
bmodified(ip->i_bh);
- gfs2_blockmap_set(sbp, bl, ii->inode,
- gfs2_block_free);
+ gfs2_blockmap_set(bl, ii->inode,
+ gfs2_block_free);
log_err( _("The inode was deleted\n"));
} else {
log_err( _("The inode was not "
@@ -114,8 +114,8 @@ static int scan_inode_list(struct gfs2_sbd *sbp) {
if(!ip->i_di.di_size && !ip->i_di.di_eattr){
log_err( _("Unlinked inode has zero size\n"));
if(query( _("Clear zero-size unlinked inode? (y/n) "))) {
- gfs2_blockmap_set(sbp, bl, ii->inode,
- gfs2_block_free);
+ gfs2_blockmap_set(bl, ii->inode,
+ gfs2_block_free);
fsck_inode_put(&ip);
continue;
}
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index b671a4b..2c1bfc9 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -125,8 +125,8 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *bmap,
return 0;
}
-int gfs2_blockmap_set(struct gfs2_sbd *sdp, struct gfs2_bmap *bmap,
- uint64_t bblock, enum gfs2_mark_block mark)
+int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock,
+ enum gfs2_mark_block mark)
{
static unsigned char *byte;
static uint64_t b;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 0452e47..4fbc4e1 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -306,8 +306,8 @@ extern struct special_blocks *blockfind(struct special_blocks *blist, uint64_t n
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_sbd *sdp, struct gfs2_bmap *il,
- uint64_t block, enum gfs2_mark_block mark);
+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);
/* gfs2_block_unmark clears ONE mark for the given block */
14 years, 3 months
cluster: STABLE3 - fsck.gfs2: pass1 should use gfs2_special_add not _set
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 25541883d8844c4cfcac59346a211c897a84bbb6
Parent: 7471efad8ae060d70803bbf66d21e9a36abdd3a5
Author: Bob Peterson <bob(a)ganesha.peterson>
AuthorDate: Thu Jan 21 14:26:17 2010 -0600
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Tue Jan 26 14:39:29 2010 -0600
fsck.gfs2: pass1 should use gfs2_special_add not _set
Since pass1 traverses the file system sequentially by block,
it can safely assume blocks it adds to the special_blocks list
are not already on it. Therefore, it can safely add those
blocks to the list and avoid checking for it already being
there. This saves a tiny bit of time, which may seem
trivial but when there are a million inodes on the list, the
time saved is worth it.
rhbz#455300
---
gfs2/fsck/pass1.c | 4 ++--
gfs2/libgfs2/block_list.c | 11 ++++++++---
gfs2/libgfs2/libgfs2.h | 3 ++-
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 0070886..ba5206d 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -364,7 +364,7 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
(unsigned long long)ip->i_di.di_num.no_addr);
/* Mark the inode as having an eattr in the block map
so pass1c can check it. */
- gfs2_special_set(&ip->i_sbd->eattr_blocks, ip->i_di.di_num.no_addr);
+ gfs2_special_add(&ip->i_sbd->eattr_blocks, ip->i_di.di_num.no_addr);
if (!leaf_pointer_errors)
return 0;
log_err( _("Inode %lld (0x%llx) has recoverable indirect "
@@ -494,7 +494,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
"block(s) attached.\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
- gfs2_special_set(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
+ gfs2_special_add(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
if(gfs2_check_range(sdp, block)) {
log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf "
"block #%llu (0x%llx) is out of range.\n"),
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index bc8babc..b671a4b 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -79,12 +79,10 @@ struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num)
return NULL;
}
-void gfs2_special_set(struct special_blocks *blocklist, uint64_t block)
+void gfs2_special_add(struct special_blocks *blocklist, uint64_t block)
{
struct special_blocks *b;
- if (blockfind(blocklist, block))
- return;
b = malloc(sizeof(struct special_blocks));
if (b) {
memset(b, 0, sizeof(*b));
@@ -93,6 +91,13 @@ void gfs2_special_set(struct special_blocks *blocklist, uint64_t block)
}
}
+void gfs2_special_set(struct special_blocks *blocklist, uint64_t block)
+{
+ if (blockfind(blocklist, block))
+ return;
+ gfs2_special_add(blocklist, block);
+}
+
void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
{
struct special_blocks *b;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 86db414..0452e47 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -303,10 +303,11 @@ enum gfs2_mark_block {
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_sbd *sdp, struct gfs2_bmap *il,
- uint64_t block, enum gfs2_mark_block mark);
+ uint64_t block, enum gfs2_mark_block mark);
extern void gfs2_special_clear(struct special_blocks *blocklist,
uint64_t block);
/* gfs2_block_unmark clears ONE mark for the given block */
14 years, 3 months