This patch eliminates pass1c and moves its checks to pass1. In
pass1c, it used to delete bad extended attribute blocks, but in
pass1, we have to go about things a little differently. Since
pass1 is prior to resolving duplicate references (pass1b) it
must "undo" the references rather than delete them.

rhbz#1257625
---
 gfs2/fsck/Makefile.am  |   1 -
 gfs2/fsck/main.c       |   1 -
 gfs2/fsck/pass1.c      |  98 ++++++++++-------
 gfs2/fsck/pass1c.c     | 285 -------------------------------------------------
 gfs2/fsck/util.c       |   2 -
 gfs2/libgfs2/libgfs2.h |   2 -
 6 files changed, 62 insertions(+), 327 deletions(-)
 delete mode 100644 gfs2/fsck/pass1c.c

diff --git a/gfs2/fsck/Makefile.am b/gfs2/fsck/Makefile.am
index fb93110..73d957e 100644
--- a/gfs2/fsck/Makefile.am
+++ b/gfs2/fsck/Makefile.am
@@ -21,7 +21,6 @@ fsck_gfs2_SOURCES = \
        metawalk.c \
        pass1b.c \
        pass1.c \
-       pass1c.c \
        pass2.c \
        pass3.c \
        pass4.c \
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 658cd17..08343ca 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -237,7 +237,6 @@ struct fsck_pass {
 static const struct fsck_pass passes[] = {
        { .name = "pass1",  .f = pass1 },
        { .name = "pass1b", .f = pass1b },
-       { .name = "pass1c", .f = pass1c },
        { .name = "pass2",  .f = pass2 },
        { .name = "pass3",  .f = pass3 },
        { .name = "pass4",  .f = pass4 },
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index f95e7eb..a892b4b 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -684,8 +684,6 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int 
leaf_pointers,
                              int leaf_pointer_errors, void *private)
 {
        struct block_count *bc = (struct block_count *) private;
-       osi_list_t *head;
-       struct special_blocks *b = NULL;
 
        if (leaf_pointer_errors == leaf_pointers) /* All eas were bad */
                return ask_remove_inode_eattr(ip, bc);
@@ -693,18 +691,6 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int 
leaf_pointers,
                     "attribute block\n"),
                   (unsigned long long)ip->i_di.di_num.no_addr,
                   (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. We may have previously added this inode
-          to the eattr_blocks list and if we did, it would be the first
-          one on the list.  So check that one only (to save time) and
-          if that one matches, no need to add it again. */
-       if (!osi_list_empty(&ip->i_sbd->eattr_blocks.list)) {
-               head = &ip->i_sbd->eattr_blocks.list;
-               b = osi_list_entry(head->next, struct special_blocks, list);
-       }
-       if (!b || b->block != 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 "
@@ -774,7 +760,7 @@ static int check_ealeaf_block(struct gfs2_inode *ip, 
uint64_t block, int btype,
        }
        /* Point of confusion: We've got to set the ea block itself to
           GFS2_BLKST_USED here.  Elsewhere we mark the inode with
-          gfs2_eattr_block meaning it contains an eattr for pass1c. */
+          gfs2_eattr_block meaning it contains an eattr. */
        fsck_blockmap_set(ip, block, _("Extended Attribute"),
                          sdp->gfs1 ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
        bc->ea_count++;
@@ -830,24 +816,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, 
uint64_t block,
                            void *private)
 {
        struct gfs2_sbd *sdp = ip->i_sbd;
-       osi_list_t *head;
-       struct special_blocks *b = NULL;
 
-       /* This inode contains an eattr - it may be invalid, but the
-        * eattr attributes points to a non-zero block.
-        * Clarification: If we're here we're checking a leaf block, and the
-        * source dinode needs to be marked as having extended attributes.
-        * That instructs pass1c to check the contents of the ea blocks. */
-       log_debug( _("Setting inode %lld (0x%llx) as having eattr "
-                    "block(s) attached.\n"),
-                  (unsigned long long)ip->i_di.di_num.no_addr,
-                  (unsigned long long)ip->i_di.di_num.no_addr);
-       if (!osi_list_empty(&ip->i_sbd->eattr_blocks.list)) {
-               head = &ip->i_sbd->eattr_blocks.list;
-               b = osi_list_entry(head->next, struct special_blocks, list);
-       }
-       if (!b || b->block != ip->i_di.di_num.no_addr)
-               gfs2_special_add(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
        if (!valid_block(sdp, block)) {
                log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf "
                            "block #%llu (0x%llx) is invalid or out of "
@@ -863,6 +832,41 @@ static int check_eattr_leaf(struct gfs2_inode *ip, 
uint64_t block,
        return check_ealeaf_block(ip, block, GFS2_METATYPE_EA, bh, private);
 }
 
+static int ask_remove_eattr_entry(struct gfs2_sbd *sdp,
+                                 struct gfs2_buffer_head *leaf_bh,
+                                 struct gfs2_ea_header *curr,
+                                 struct gfs2_ea_header *prev,
+                                 int fix_curr, int fix_curr_len)
+{
+       if (!query( _("Remove the bad Extended Attribute entry? (y/n) "))) {
+               log_err( _("Bad Extended Attribute not removed.\n"));
+               return 0;
+       }
+       if (fix_curr)
+               curr->ea_flags |= GFS2_EAFLAG_LAST;
+       if (fix_curr_len) {
+               uint32_t max_size = sdp->sd_sb.sb_bsize;
+               uint32_t offset = (uint32_t)(((unsigned long)curr) -
+                                            ((unsigned long)leaf_bh->b_data));
+               curr->ea_rec_len = cpu_to_be32(max_size - offset);
+       }
+       if (!prev)
+               curr->ea_type = GFS2_EATYPE_UNUSED;
+       else {
+               uint32_t tmp32 = be32_to_cpu(curr->ea_rec_len) +
+                       be32_to_cpu(prev->ea_rec_len);
+               prev->ea_rec_len = cpu_to_be32(tmp32);
+               if (curr->ea_flags & GFS2_EAFLAG_LAST)
+                       prev->ea_flags |= GFS2_EAFLAG_LAST;     
+       }
+       log_err( _("Bad Extended Attribute at block #%llu"
+                  " (0x%llx) removed.\n"),
+                (unsigned long long)leaf_bh->b_blocknr,
+                (unsigned long long)leaf_bh->b_blocknr);
+       bmodified(leaf_bh);
+       return 1;
+}
+
 static int check_eattr_entries(struct gfs2_inode *ip,
                               struct gfs2_buffer_head *leaf_bh,
                               struct gfs2_ea_header *ea_hdr,
@@ -871,12 +875,32 @@ static int check_eattr_entries(struct gfs2_inode *ip,
 {
        struct gfs2_sbd *sdp = ip->i_sbd;
        char ea_name[256];
+       uint32_t offset = (uint32_t)(((unsigned long)ea_hdr) -
+                                    ((unsigned long)leaf_bh->b_data));
+       uint32_t max_size = sdp->sd_sb.sb_bsize;
        uint32_t avail_size;
        int max_ptrs;
 
        if (!ea_hdr->ea_name_len){
-               /* Skip this entry for now */
-               return 1;
+               log_err( _("EA has name length of zero\n"));
+               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
+                                             ea_hdr_prev, 1, 1);
+       }
+       if (offset + be32_to_cpu(ea_hdr->ea_rec_len) > max_size){
+               log_err( _("EA rec length too long\n"));
+               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
+                                             ea_hdr_prev, 1, 1);
+       }
+       if (offset + be32_to_cpu(ea_hdr->ea_rec_len) == max_size &&
+          (ea_hdr->ea_flags & GFS2_EAFLAG_LAST) == 0){
+               log_err( _("last EA has no last entry flag\n"));
+               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
+                                             ea_hdr_prev, 0, 0);
+       }
+       if (!ea_hdr->ea_name_len){
+               log_err( _("EA has name length of zero\n"));
+               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
+                                             ea_hdr_prev, 0, 0);
        }
 
        memset(ea_name, 0, sizeof(ea_name));
@@ -888,7 +912,8 @@ static int check_eattr_entries(struct gfs2_inode *ip,
                /* Skip invalid entry */
                log_err(_("EA (%s) type is invalid (%d > %d).\n"),
                        ea_name, ea_hdr->ea_type, GFS2_EATYPE_LAST);
-               return 1;
+               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
+                                             ea_hdr_prev, 0, 0);
        }
 
        if (!ea_hdr->ea_num_ptrs)
@@ -902,7 +927,8 @@ static int check_eattr_entries(struct gfs2_inode *ip,
                        ea_name);
                log_err(_("  Required:  %d\n  Reported:  %d\n"),
                        max_ptrs, ea_hdr->ea_num_ptrs);
-               return 1;
+               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
+                                             ea_hdr_prev, 0, 0);
        } else {
                log_debug( _("  Pointers Required: %d\n  Pointers Reported: 
%d\n"),
                           max_ptrs, ea_hdr->ea_num_ptrs);
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
deleted file mode 100644
index aa905da..0000000
--- a/gfs2/fsck/pass1c.c
+++ /dev/null
@@ -1,285 +0,0 @@
-#include "clusterautoconfig.h"
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <libintl.h>
-#define _(String) gettext(String)
-
-#include <logging.h>
-#include "libgfs2.h"
-#include "fsck.h"
-#include "util.h"
-#include "metawalk.h"
-
-struct metawalk_fxns pass1c_fxns_delete = {
-       .private = NULL,
-       .check_eattr_indir = delete_eattr_indir,
-       .check_eattr_leaf = delete_eattr_leaf,
-};
-
-static int remove_eattr_entry(struct gfs2_sbd *sdp,
-                             struct gfs2_buffer_head *leaf_bh,
-                             struct gfs2_ea_header *curr,
-                             struct gfs2_ea_header *prev)
-{
-       if (!prev)
-               curr->ea_type = GFS2_EATYPE_UNUSED;
-       else {
-               uint32_t tmp32 = be32_to_cpu(curr->ea_rec_len) +
-                       be32_to_cpu(prev->ea_rec_len);
-               prev->ea_rec_len = cpu_to_be32(tmp32);
-               if (curr->ea_flags & GFS2_EAFLAG_LAST)
-                       prev->ea_flags |= GFS2_EAFLAG_LAST;     
-       }
-       log_err( _("Bad Extended Attribute at block #%llu"
-                  " (0x%llx) removed.\n"),
-                (unsigned long long)leaf_bh->b_blocknr,
-                (unsigned long long)leaf_bh->b_blocknr);
-       bmodified(leaf_bh);
-       return 0;
-}
-
-static int ask_remove_eattr_entry(struct gfs2_sbd *sdp,
-                                 struct gfs2_buffer_head *leaf_bh,
-                                 struct gfs2_ea_header *curr,
-                                 struct gfs2_ea_header *prev,
-                                 int fix_curr, int fix_curr_len)
-{
-       if (query( _("Remove the bad Extended Attribute entry? (y/n) "))) {
-               if (fix_curr)
-                       curr->ea_flags |= GFS2_EAFLAG_LAST;
-               if (fix_curr_len) {
-                       uint32_t max_size = sdp->sd_sb.sb_bsize;
-                       uint32_t offset = (uint32_t)(((unsigned long)curr) -
-                                            ((unsigned long)leaf_bh->b_data));
-                       curr->ea_rec_len = cpu_to_be32(max_size - offset);
-               }
-               if (remove_eattr_entry(sdp, leaf_bh, curr, prev)) {
-                       stack;
-                       return -1;
-               }
-       } else {
-               log_err( _("Bad Extended Attribute not removed.\n"));
-       }
-       return 1;
-}
-
-static int ask_remove_eattr(struct gfs2_inode *ip)
-{
-       if (query( _("Remove the bad Extended Attribute? (y/n) "))) {
-               check_inode_eattr(ip, &pass1c_fxns_delete);
-               bmodified(ip->i_bh);
-               log_err( _("Bad Extended Attribute removed.\n"));
-               return 1;
-       }
-       log_err( _("Bad Extended Attribute not removed.\n"));
-       return 0;
-}
-
-static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
-                     uint64_t parent, struct gfs2_buffer_head **bh,
-                     void *private)
-{
-       struct gfs2_sbd *sdp = ip->i_sbd;
-       uint8_t q;
-       struct gfs2_buffer_head *indir_bh = NULL;
-
-       if (!valid_block(sdp, block)) {
-               log_err( _("Extended attributes indirect block #%llu"
-                       " (0x%llx) for inode #%llu"
-                       " (0x%llx) is invalid...removing\n"),
-                       (unsigned long long)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);
-               return ask_remove_eattr(ip);
-       }
-       q = block_type(block);
-       if (q != (sdp->gfs1 ? GFS2_BLKST_DINODE : GFS2_BLKST_USED)) {
-               log_err( _("Extended attributes indirect block #%llu"
-                       " (0x%llx) for inode #%llu"
-                       " (0x%llx) is invalid.\n"),
-                       (unsigned long long)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);
-               return ask_remove_eattr(ip);
-       }
-       else
-               indir_bh = bread(sdp, block);
-
-       *bh = indir_bh;
-       return 0;
-}
-
-static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
-                    uint64_t parent, struct gfs2_buffer_head **bh,
-                    void *private)
-{
-       struct gfs2_sbd *sdp = ip->i_sbd;
-       uint8_t q;
-
-       if (!valid_block(sdp, block)) {
-               log_err( _("Extended attributes block %lld (0x%llx) for "
-                          "inode #%llu (0x%llx) is invalid.\n"),
-                        (unsigned long long)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);
-               return ask_remove_eattr(ip);
-       }
-       q = block_type(block);
-       if (q != (sdp->gfs1 ? GFS2_BLKST_DINODE : GFS2_BLKST_USED)) {
-               log_err( _("Extended attributes block %lld (0x%llx) for "
-                          "inode #%llu (0x%llx) invalid.\n"),
-                        (unsigned long long)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);
-               return ask_remove_eattr(ip);
-       }
-       else 
-               *bh = bread(sdp, block);
-
-       return 0;
-}
-
-static int check_eattr_entry(struct gfs2_inode *ip,
-                            struct gfs2_buffer_head *leaf_bh,
-                            struct gfs2_ea_header *ea_hdr,
-                            struct gfs2_ea_header *ea_hdr_prev,
-                            void *private)
-{
-       struct gfs2_sbd *sdp = ip->i_sbd;
-       char ea_name[256];
-       uint32_t offset = (uint32_t)(((unsigned long)ea_hdr) -
-                                         ((unsigned long)leaf_bh->b_data));
-       uint32_t max_size = sdp->sd_sb.sb_bsize;
-
-       if (!ea_hdr->ea_name_len){
-               log_err( _("EA has name length of zero\n"));
-               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
-                                             ea_hdr_prev, 1, 1);
-       }
-       if (offset + be32_to_cpu(ea_hdr->ea_rec_len) > max_size){
-               log_err( _("EA rec length too long\n"));
-               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
-                                             ea_hdr_prev, 1, 1);
-       }
-       if (offset + be32_to_cpu(ea_hdr->ea_rec_len) == max_size &&
-          (ea_hdr->ea_flags & GFS2_EAFLAG_LAST) == 0){
-               log_err( _("last EA has no last entry flag\n"));
-               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
-                                             ea_hdr_prev, 0, 0);
-       }
-       if (!ea_hdr->ea_name_len){
-               log_err( _("EA has name length of zero\n"));
-               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
-                                             ea_hdr_prev, 0, 0);
-       }
-
-       memset(ea_name, 0, sizeof(ea_name));
-       strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
-               ea_hdr->ea_name_len);
-
-       if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
-          ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
-               log_err( _("EA (%s) type is invalid (%d > %d).\n"),
-                       ea_name, ea_hdr->ea_type, GFS2_EATYPE_LAST);
-               return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
-                                             ea_hdr_prev, 0, 0);
-       }
-
-       if (ea_hdr->ea_num_ptrs){
-               uint32_t avail_size;
-               int max_ptrs;
-
-               avail_size = sdp->sd_sb.sb_bsize - sizeof(struct 
gfs2_meta_header);
-               max_ptrs = 
(be32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size;
-
-               if (max_ptrs > ea_hdr->ea_num_ptrs){
-                       log_err( _("EA (%s) has incorrect number of 
pointers.\n"), ea_name);
-                       log_err( _("  Required:  %d\n  Reported:  %d\n"),
-                                max_ptrs, ea_hdr->ea_num_ptrs);
-                       return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
-                                                     ea_hdr_prev, 0, 0);
-               } else {
-                       log_debug( _(" Pointers Required: %d\n  Pointers 
Reported: %d\n"),
-                                         max_ptrs, ea_hdr->ea_num_ptrs);
-               }
-       }
-       return 0;
-}
-
-static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr,
-                        struct gfs2_buffer_head *leaf_bh,
-                        struct gfs2_ea_header *ea_hdr,
-                        struct gfs2_ea_header *ea_hdr_prev, void *private)
-{
-       uint8_t q;
-       struct gfs2_sbd *sdp = ip->i_sbd;
-
-       q = block_type(be64_to_cpu(*ea_ptr));
-       if (q != (sdp->gfs1 ? GFS2_BLKST_DINODE : GFS2_BLKST_USED)) {
-               if (remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
-                       stack;
-                       return -1;
-               }
-               return 1;
-       }
-       return 0;
-}
-
-/* Go over all inodes with extended attributes and verify the EAs are
- * valid */
-int pass1c(struct gfs2_sbd *sdp)
-{
-       uint64_t block_no = 0;
-       struct gfs2_buffer_head *bh;
-       struct gfs2_inode *ip = NULL;
-       struct metawalk_fxns pass1c_fxns = { 0 };
-       int error = 0;
-       osi_list_t *tmp, *x;
-       struct special_blocks *ea_block;
-
-       pass1c_fxns.check_eattr_indir = &check_eattr_indir;
-       pass1c_fxns.check_eattr_leaf = &check_eattr_leaf;
-       pass1c_fxns.check_eattr_entry = &check_eattr_entry;
-       pass1c_fxns.check_eattr_extentry = &check_eattr_extentry;
-       pass1c_fxns.private = NULL;
-
-       log_info( _("Looking for inodes containing ea blocks...\n"));
-       osi_list_foreach_safe(tmp, &sdp->eattr_blocks.list, x) {
-               ea_block = osi_list_entry(tmp, struct special_blocks, list);
-               block_no = ea_block->block;
-               warm_fuzzy_stuff(block_no);
-
-               if (skip_this_pass || fsck_abort) /* if asked to skip the rest 
*/
-                       return FSCK_OK;
-               bh = bread(sdp, block_no);
-               if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* if a dinode */
-                       log_info( _("EA in inode %llu (0x%llx)\n"),
-                                (unsigned long long)block_no,
-                                (unsigned long long)block_no);
-                       gfs2_special_clear(&sdp->eattr_blocks, block_no);
-                       ip = fsck_inode_get(sdp, bh);
-                       ip->bh_owned = 1;
-
-                       log_debug( _("Found eattr at %llu (0x%llx)\n"),
-                                 (unsigned long long)ip->i_di.di_eattr,
-                                 (unsigned long long)ip->i_di.di_eattr);
-                       /* FIXME: Handle walking the eattr here */
-                       error = check_inode_eattr(ip, &pass1c_fxns);
-                       if (error < 0) {
-                               stack;
-                               brelse(bh);
-                               return FSCK_ERROR;
-                       }
-
-                       fsck_inode_put(&ip); /* dinode_out, brelse, free */
-               } else {
-                       brelse(bh);
-               }
-       }
-       return FSCK_OK;
-}
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index b22abc6..2745692 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -556,7 +556,6 @@ struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, 
uint64_t size,
                free(il);
                il = NULL;
        }
-       osi_list_init(&sdp->eattr_blocks.list);
        return il;
 }
 
@@ -584,7 +583,6 @@ void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct 
gfs2_bmap *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 ccae721..12d57c7 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -304,8 +304,6 @@ struct gfs2_sbd {
        struct gfs2_inode *master_dir;
        struct master_dir md;
 
-       struct special_blocks eattr_blocks;
-
        uint64_t rg_one_length;
        uint64_t rg_length;
        int gfs1;
-- 
2.4.3

Reply via email to