"Fossies" - the Fresh Open Source Software Archive

Member "reiserfsprogs-3.6.25/fsck/semantic_check.c" (13 Mar 2014, 25062 Bytes) of archive /linux/misc/reiserfsprogs-3.6.25.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "semantic_check.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright 1996-2004 by Hans Reiser, licensing governed by reiserfsprogs/README
    3  */
    4 
    5 #include "fsck.h"
    6 
    7 static struct reiserfs_key *trunc_links = NULL;
    8 static __u32 links_num = 0;
    9 
   10 int wrong_mode(const struct reiserfs_key *key, __u16 * mode, __u64 real_size,
   11            int symlink);
   12 int wrong_st_blocks(const struct reiserfs_key *key, __u32 * blocks,
   13             __u32 sd_blocks, __u16 mode, int new_format);
   14 int wrong_st_size(const struct reiserfs_key *key,
   15           unsigned long long max_file_size, int blocksize,
   16           __u64 * size, __u64 sd_size, int type);
   17 int wrong_first_direct_byte(const struct reiserfs_key *key, int blocksize,
   18                 __u32 * first_direct_byte,
   19                 __u32 sd_first_direct_byte, __u32 size);
   20 void get_object_key(struct reiserfs_de_head *deh, struct reiserfs_key *key,
   21             struct reiserfs_key *entry_key, struct item_head *ih);
   22 void print_name(char *name, int len);
   23 void erase_name(int len);
   24 
   25 struct reiserfs_path_key {
   26     struct short_key {
   27         __u32 k_dir_id;
   28         __u32 k_objectid;
   29     } key;
   30     struct reiserfs_path_key *next, *prev;
   31 };
   32 
   33 static struct reiserfs_path_key *head_key = NULL;
   34 static struct reiserfs_path_key *tail_key = NULL;
   35 
   36 static int check_path_key(const struct reiserfs_key *key)
   37 {
   38     struct reiserfs_path_key *cur = head_key;
   39 
   40     while (cur != NULL) {
   41         if (!comp_short_keys(&cur->key, key)) {
   42             fsck_log
   43                 ("\nsemantic check: The directory %k has 2 names.",
   44                  key);
   45             return LOOP_FOUND;
   46         }
   47         cur = cur->next;
   48     }
   49     return 0;
   50 }
   51 
   52 static int add_path_key(const struct reiserfs_key *key)
   53 {
   54     if (check_path_key(key))
   55         return LOOP_FOUND;
   56 
   57     if (tail_key == NULL) {
   58         tail_key = getmem(sizeof(struct reiserfs_path_key));
   59         head_key = tail_key;
   60         tail_key->prev = NULL;
   61     } else {
   62         tail_key->next = getmem(sizeof(struct reiserfs_path_key));
   63         tail_key->next->prev = tail_key;
   64         tail_key = tail_key->next;
   65     }
   66     copy_short_key(&tail_key->key, key);
   67     tail_key->next = NULL;
   68 
   69     return 0;
   70 }
   71 
   72 static void del_path_key(void)
   73 {
   74     if (tail_key == NULL)
   75         die("Wrong path_key structure");
   76 
   77     if (tail_key->prev == NULL) {
   78         freemem(tail_key);
   79         tail_key = head_key = NULL;
   80     } else {
   81         tail_key = tail_key->prev;
   82         freemem(tail_key->next);
   83         tail_key->next = NULL;
   84     }
   85 }
   86 
   87 /* path is path to stat data. If file will be relocated - new_ih will contain
   88    a key file was relocated with */
   89 static int check_check_regular_file(struct reiserfs_path *path, void *sd,
   90                     struct item_head *new_ih)
   91 {
   92     int is_new_file;
   93 //    struct reiserfs_key key, sd_key;
   94     __u16 mode;
   95     __u32 nlink;
   96     __u64 real_size, sd_size;
   97     __u32 blocks, sd_blocks;    /* proper values and value in stat data */
   98     __u32 first_direct_byte, sd_first_direct_byte;
   99 
  100     struct item_head *ih, sd_ih;
  101     int fix_sd;
  102     int symlnk = 0;
  103     int retval = OK;
  104     __u32 tmp_position;
  105 
  106     ih = tp_item_head(path);
  107 
  108     if (new_ih) {
  109         /* this objectid is used already */
  110         *new_ih = *ih;
  111         pathrelse(path);
  112         rewrite_file(new_ih, 1, 1);
  113         linked_already(&new_ih->ih_key);
  114         one_less_corruption(fs, FIXABLE);
  115         sem_pass_stat(fs)->oid_sharing_files_relocated++;
  116         retval = RELOCATED;
  117         if (reiserfs_search_by_key_4(fs, &(new_ih->ih_key), path) ==
  118             ITEM_NOT_FOUND)
  119             reiserfs_panic
  120                 ("check_check_regular_file: Could not find a StatData of "
  121                  "the relocated file %K", &new_ih->ih_key);
  122         /* stat data is marked unreachable again due to relocation, fix that */
  123         ih = tp_item_head(path);
  124         sd = tp_item_body(path);
  125     }
  126 
  127     if (get_ih_item_len(ih) == SD_SIZE)
  128         is_new_file = 1;
  129     else
  130         is_new_file = 0;
  131 
  132     get_sd_nlink(ih, sd, &nlink);
  133     get_sd_mode(ih, sd, &mode);
  134     get_sd_size(ih, sd, &sd_size);
  135     get_sd_blocks(ih, sd, &sd_blocks);
  136 
  137 /*  
  138     if (fsck_mode (fs) == FSCK_FIX_FIXABLE) {
  139         // check and set nlink first
  140         nlink ++;
  141         set_sd_nlink (ih, sd, &nlink);
  142         mark_buffer_dirty (bh);
  143 
  144         if (nlink > 1)
  145         return OK;
  146     }
  147 */
  148 
  149     if (!is_new_file)
  150         get_sd_first_direct_byte(ih, sd, &sd_first_direct_byte);
  151 
  152     if (S_ISLNK(mode))
  153         symlnk = 1;
  154 
  155     sd_ih = *ih;
  156 //    sd_key = sd_ih.ih_key;
  157     pathrelse(path);
  158 
  159     if (are_file_items_correct
  160         (&sd_ih, sd, &real_size, &blocks, 0 /* do not mark reachable */ ,
  161          &symlnk) != 1) {
  162         one_more_corruption(fs, FATAL);
  163         fsck_log
  164             ("check_regular_file: The file %K with the corrupted structure found\n",
  165              &sd_ih.ih_key);
  166     } else {
  167         fix_sd = 0;
  168 
  169         fix_sd += wrong_mode(&sd_ih.ih_key, &mode, real_size, symlnk);
  170         if (!is_new_file)
  171             fix_sd +=
  172                 wrong_first_direct_byte(&sd_ih.ih_key,
  173                             fs->fs_blocksize,
  174                             &first_direct_byte,
  175                             sd_first_direct_byte,
  176                             real_size);
  177 
  178         if (reiserfs_bin_search
  179             (&sd_ih.ih_key, trunc_links, links_num,
  180              sizeof(sd_ih.ih_key), &tmp_position,
  181              comp_short_keys) != POSITION_FOUND) {
  182             fix_sd +=
  183                 wrong_st_size(&sd_ih.ih_key,
  184                       is_new_file ? MAX_FILE_SIZE_V2 :
  185                       MAX_FILE_SIZE_V1, fs->fs_blocksize,
  186                       &real_size, sd_size,
  187                       symlnk ? TYPE_SYMLINK : 0);
  188         } else {
  189             real_size = sd_size;
  190         }
  191 
  192         fix_sd +=
  193             wrong_st_blocks(&sd_ih.ih_key, &blocks, sd_blocks, mode,
  194                     is_new_file);
  195 
  196         if (fix_sd) {
  197             if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  198                 struct buffer_head *bh;
  199                 /* find stat data and correct it */
  200                 set_type_and_offset(KEY_FORMAT_1, &sd_ih.ih_key,
  201                             SD_OFFSET, TYPE_STAT_DATA);
  202                 if (reiserfs_search_by_key_4
  203                     (fs, &sd_ih.ih_key, path) != ITEM_FOUND) {
  204                     fsck_log
  205                         ("check_regular_file: A StatData of the file %K cannot be "
  206                          "found\n", &sd_ih.ih_key);
  207                     one_more_corruption(fs, FATAL);
  208                     return STAT_DATA_NOT_FOUND;
  209                 }
  210 
  211                 bh = get_bh(path);
  212                 ih = tp_item_head(path);
  213                 sd = tp_item_body(path);
  214                 set_sd_size(ih, sd, &real_size);
  215                 set_sd_blocks(ih, sd, &blocks);
  216                 set_sd_mode(ih, sd, &mode);
  217                 if (!is_new_file)
  218                     set_sd_first_direct_byte(ih, sd,
  219                                  &first_direct_byte);
  220                 mark_buffer_dirty(bh);
  221             } else {
  222                 fsck_check_stat(fs)->fixable_corruptions +=
  223                     fix_sd;
  224             }
  225         }
  226     }
  227     return retval;
  228 }
  229 
  230 /* returns buffer, containing found directory item.*/
  231 static char *get_next_directory_item(struct reiserfs_key *key,  /* on return this will contain key of next item in the tree */
  232                      const struct reiserfs_key *parent,
  233                      struct item_head *ih, __u32 * pos_in_item,
  234                      int dir_format)
  235 {
  236     INITIALIZE_REISERFS_PATH(path);
  237     char *dir_item;
  238     struct reiserfs_key *rdkey;
  239     struct buffer_head *bh;
  240     struct reiserfs_de_head *deh;
  241     int i;
  242     int retval;
  243 
  244 start_again:
  245 
  246     retval = reiserfs_search_by_entry_key(fs, key, &path);
  247 
  248     if (retval != POSITION_FOUND && get_offset(key) != DOT_OFFSET)
  249         reiserfs_panic
  250             ("get_next_directory_item: The current directory %k cannot be found",
  251              key);
  252 
  253     /* leaf containing directory item */
  254     bh = PATH_PLAST_BUFFER(&path);
  255     *pos_in_item = path.pos_in_item;
  256     *ih = *tp_item_head(&path);
  257     deh = B_I_DEH(bh, ih);
  258 
  259     /* position was not found for '.' or there is no '..' */
  260     if (retval != POSITION_FOUND || ((get_offset(key) == DOT_OFFSET) &&
  261                      (get_ih_entry_count(ih) < 2
  262                       || name_in_entry_length(ih, deh + 1,
  263                                   1) != 2
  264                       || strncmp(name_in_entry(deh + 1, 1),
  265                              "..", 2)))) {
  266 
  267         fsck_log
  268             ("get_next_directory_item: The %s %k cannot be found in %k",
  269              (retval == POSITION_NOT_FOUND) ? "entry" : "directory",
  270              key, &ih->ih_key);
  271 
  272         if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  273             /* add "." and ".." exist */
  274             pathrelse(&path);
  275             reiserfs_add_entry(fs, key, ".",
  276                        name_length(".", dir_format), key,
  277                        0);
  278             reiserfs_add_entry(fs, key, "..",
  279                        name_length("..", dir_format),
  280                        parent, 0);
  281             fsck_log(" - entry was added\n");
  282             goto start_again;
  283         } else {
  284             one_more_corruption(fs, FIXABLE);
  285             fsck_log("\n");
  286             if (retval == DIRECTORY_NOT_FOUND)
  287                 return NULL;
  288         }
  289     }
  290 
  291     /* make sure, that ".." exists as well */
  292 /*
  293     if (get_offset (key) == DOT_OFFSET) {
  294     if (get_ih_entry_count (ih) < 2 ||
  295         name_in_entry_length (ih, deh + 1, 1) != 2 ||
  296         strncmp (name_in_entry (deh + 1, 1), "..", 2))
  297     {
  298         fsck_log ("get_next_directory_item: \"..\" not found in %H\n", ih);
  299         pathrelse (&path);
  300         return 0;
  301     }
  302     }
  303 */
  304     /* mark hidden entries as visible, set "." and ".." correctly */
  305     deh += *pos_in_item;
  306     for (i = *pos_in_item; i < get_ih_entry_count(ih); i++, deh++) {
  307 /*  int namelen;
  308     char * name;
  309 
  310     name = name_in_entry (deh, i);
  311     namelen = name_in_entry_length (ih, deh, i);
  312     if (de_hidden (deh)) // handled in check_tree
  313         reiserfs_panic ("get_next_directory_item: item %k: hidden entry %d \'%.*s\'\n",
  314                 key, i, namelen, name);
  315 */
  316 
  317         if (get_deh_offset(deh) == DOT_OFFSET) {
  318             if (not_of_one_file(&(deh->deh2_dir_id), key)) {
  319                 /* "." must point to the directory it is in */
  320 
  321                 //deh->deh_objectid != REISERFS_ROOT_PARENT_OBJECTID)/*????*/ {
  322                 fsck_log
  323                     ("get_next_directory_item: The entry \".\" of the directory %K "
  324                      "pointes to %K, instead of %K", key,
  325                      (struct reiserfs_key
  326                       *)(&(deh->deh2_dir_id)), key);
  327                 if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  328                     set_deh_dirid(deh, get_key_dirid(key));
  329                     set_deh_objectid(deh,
  330                              get_key_objectid(key));
  331                     mark_buffer_dirty(bh);
  332                     fsck_log(" - corrected\n");
  333                 } else {
  334                     one_more_corruption(fs, FIXABLE);
  335                     fsck_log("\n");
  336                 }
  337             }
  338         }
  339 
  340         if (get_deh_offset(deh) == DOT_DOT_OFFSET) {
  341             /* set ".." so that it points to the correct parent directory */
  342             if (comp_short_keys(&(deh->deh2_dir_id), parent)) {
  343                 fsck_log
  344                     ("get_next_directory_item: The entry \"..\" of the directory %K "
  345                      "pointes to %K, instead of %K", key,
  346                      (struct reiserfs_key
  347                       *)(&(deh->deh2_dir_id)));
  348                 if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  349                     set_deh_dirid(deh,
  350                               get_key_dirid(parent));
  351                     set_deh_objectid(deh,
  352                              get_key_objectid
  353                              (parent));
  354                     mark_buffer_dirty(bh);
  355                     fsck_log(" - corrected\n");
  356                 } else {
  357                     one_more_corruption(fs, FIXABLE);
  358                     fsck_log("\n");
  359                 }
  360             }
  361         }
  362     }
  363 
  364     /* copy directory item to the temporary buffer */
  365     dir_item = getmem(get_ih_item_len(ih));
  366     memcpy(dir_item, ih_item_body(bh, ih), get_ih_item_len(ih));
  367 
  368     /* next item key */
  369     if (PATH_LAST_POSITION(&path) == (B_NR_ITEMS(bh) - 1) &&
  370         (rdkey = uget_rkey(&path)))
  371         copy_key(key, rdkey);
  372     else {
  373         set_key_dirid(key, 0);
  374         set_key_objectid(key, 0);
  375     }
  376 
  377     if (fsck_mode(fs) == FSCK_REBUILD)
  378         mark_item_reachable(tp_item_head(&path), bh);
  379     pathrelse(&path);
  380 
  381     return dir_item;
  382 }
  383 
  384 /* semantic pass of --check */
  385 static int check_semantic_pass(struct reiserfs_key *key,
  386                    const struct reiserfs_key *parent, int dot_dot,
  387                    struct item_head *new_ih)
  388 {
  389     struct reiserfs_path path;
  390     void *sd;
  391     __u32 nlink;
  392     int is_new_dir;
  393     struct buffer_head *bh;
  394     struct item_head *ih;
  395     int retval;
  396     char *dir_item;
  397     __u32 pos_in_item;
  398     struct item_head tmp_ih;
  399     struct reiserfs_key next_item_key, entry_key, object_key;
  400     __u64 dir_size = 0;
  401     __u32 blocks;
  402     __u64 sd_size;
  403     __u32 sd_blocks;
  404     int fix_sd;
  405     /*int relocate; */
  406     int dir_format = 0;
  407     __u16 mode;
  408 
  409     retval = OK;
  410 
  411     /* start_again: when directory was relocated */
  412 
  413     if (!KEY_IS_STAT_DATA_KEY(key)) {
  414         fsck_log
  415             ("check_semantic_pass: The key %k must be key of a StatData\n",
  416              key);
  417         one_more_corruption(fs, FATAL);
  418         return STAT_DATA_NOT_FOUND;
  419     }
  420 
  421     /* look for stat data of an object */
  422     if (reiserfs_search_by_key_4(fs, key, &path) == ITEM_NOT_FOUND) {
  423         pathrelse(&path);
  424         return STAT_DATA_NOT_FOUND;
  425     }
  426 
  427     /* stat data has been found */
  428     ih = tp_item_head(&path);
  429     sd = tp_item_body(&path);
  430 
  431     get_sd_nlink(ih, sd, &nlink);
  432 
  433     /* It seems quite difficult to relocate objects on fix-fixable -
  434      * rewrite_file calls reiserfs_file_write which can convert tails
  435      * to unfm, plus unreachable, was_tail flags, etc. */
  436 #if 0
  437     if (( /* relocate = */ should_be_relocated(&ih->ih_key))) {
  438         /*
  439            if (fsck_mode(fs) == FSCK_CHECK)
  440            relocate = 0;
  441          */
  442         one_more_corruption(fs, FATAL);
  443     }
  444 #endif
  445 
  446     if (fix_obviously_wrong_sd_mode(&path)) {
  447         one_more_corruption(fs, FIXABLE);
  448         pathrelse(&path);
  449         return OK;
  450     }
  451 
  452     if (nlink == 0) {
  453         fsck_log
  454             ("%s: block %lu: The StatData %k has bad nlink number (%u)\n",
  455              __FUNCTION__, get_bh(&path)->b_blocknr, &ih->ih_key,
  456              nlink);
  457         one_more_corruption(fs, FATAL);
  458     }
  459 
  460     if (not_a_directory(sd)) {
  461         fsck_check_stat(fs)->files++;
  462 
  463         retval =
  464             check_check_regular_file(&path, sd,
  465                          /* relocate ? new_ih : */ NULL);
  466         pathrelse(&path);
  467         return retval;
  468     }
  469 
  470 /*
  471     if (relocate) {
  472     if (!new_ih)
  473         reiserfs_panic ("check_semantic_pass: Memory is not prepared for relocation of "
  474         "%K", &ih->ih_key);
  475     *new_ih = *ih;
  476     pathrelse (&path);
  477     sem_pass_stat (fs)->oid_sharing_dirs_relocated ++;
  478     relocate_dir (new_ih, 1);
  479     linked_already(&new_ih->ih_key);
  480     one_less_corruption (fs, FIXABLE);
  481     *key = new_ih->ih_key;
  482     retval = RELOCATED;
  483     goto start_again;
  484     }
  485 */
  486 
  487 /*
  488     if (fsck_mode (fs) == FSCK_FIX_FIXABLE) {
  489         // it looks like stat data of a directory found
  490         if (nlink) {
  491         // we saw this directory already
  492         if (!dot_dot) {
  493             // this name is not ".."  - and hard links are not allowed on directories
  494             pathrelse (&path);
  495             return STAT_DATA_NOT_FOUND;
  496         } else {
  497             // ".." found
  498             nlink ++;
  499             set_sd_nlink (ih, sd, &nlink);
  500             mark_buffer_dirty (get_bh (&path));
  501             pathrelse (&path);
  502             return OK;
  503         }
  504         } // do not run it for dot_dot on check at all
  505         
  506         nlink = 2;
  507         if (get_key_objectid (key) == REISERFS_ROOT_OBJECTID)
  508         nlink ++;
  509         set_sd_nlink (ih, sd, &nlink);
  510         mark_buffer_dirty (get_bh (&path));
  511     }
  512 */
  513 
  514     /* directory stat data found */
  515     if (get_ih_item_len(ih) == SD_SIZE)
  516         is_new_dir = 1;
  517     else
  518         is_new_dir = 0;
  519 
  520     /* save stat data's size and st_blocks */
  521     get_sd_size(ih, sd, &sd_size);
  522     get_sd_blocks(ih, sd, &sd_blocks);
  523     get_sd_mode(ih, sd, &mode);
  524 
  525     dir_format =
  526         (get_ih_item_len(tp_item_head(&path)) ==
  527          SD_SIZE) ? KEY_FORMAT_2 : KEY_FORMAT_1;
  528 
  529     /* release path pointing to stat data */
  530     pathrelse(&path);
  531 
  532     fsck_check_stat(fs)->dirs++;
  533 
  534     set_key_dirid(&next_item_key, get_key_dirid(key));
  535     set_key_objectid(&next_item_key, get_key_objectid(key));
  536     set_key_offset_v1(&next_item_key, DOT_OFFSET);
  537     set_key_uniqueness(&next_item_key, DIRENTRY_UNIQUENESS);
  538 
  539     dir_size = 0;
  540     while ((dir_item =
  541         get_next_directory_item(&next_item_key, parent, &tmp_ih,
  542                     &pos_in_item, dir_format)) != NULL) {
  543         /* dir_item is copy of the item in separately allocated memory,
  544            item_key is a key of next item in the tree */
  545         int i;
  546         char *name = NULL;
  547         int namelen, entry_len;
  548         struct reiserfs_de_head *deh =
  549             (struct reiserfs_de_head *)dir_item + pos_in_item;
  550 
  551         for (i = pos_in_item; i < get_ih_entry_count(&tmp_ih);
  552              i++, deh++) {
  553             struct item_head relocated_ih;
  554             int ret = OK;
  555 
  556             if (name) {
  557                 free(name);
  558                 name = NULL;
  559             }
  560 
  561             namelen = name_in_entry_length(&tmp_ih, deh, i);
  562             asprintf(&name, "%.*s", namelen, name_in_entry(deh, i));
  563             entry_len = entry_length(&tmp_ih, deh, i);
  564 
  565             get_object_key(deh, &object_key, &entry_key, &tmp_ih);
  566 
  567             if ((dir_format == KEY_FORMAT_2)
  568                 && (entry_len % 8 != 0)) {
  569                 /* not alighed directory of new format - delete it */
  570                 if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  571                     fsck_log
  572                         ("Entry %K (\"%.*s\") in the directory %K is not formated "
  573                          "properly - deleted\n",
  574                          (struct reiserfs_key *)&(deh->
  575                                       deh2_dir_id),
  576                          namelen, name, &tmp_ih.ih_key);
  577                     reiserfs_remove_entry(fs, &entry_key);
  578                     entry_len =
  579                         name_length(name, dir_format);
  580                     reiserfs_add_entry(fs, key, name,
  581                                entry_len,
  582                                (struct reiserfs_key
  583                                 *)&(deh->
  584                                 deh2_dir_id),
  585                                0);
  586                 } else {
  587                     fsck_log
  588                         ("Entry %K (\"%.*s\") in the directory %K is not formated "
  589                          "properly.\n",
  590                          (struct reiserfs_key *)&(deh->
  591                                       deh2_dir_id),
  592                          namelen, name, &tmp_ih.ih_key);
  593                     one_more_corruption(fs, FIXABLE);
  594                 }
  595             }
  596 
  597             print_name(name, namelen);
  598 
  599             if (!is_properly_hashed
  600                 (fs, name, namelen, get_deh_offset(deh))) {
  601                 one_more_corruption(fs, FATAL);
  602                 fsck_log
  603                     ("check_semantic_pass: Hash mismatch detected for (%.*s) in "
  604                      "directory %K\n", namelen, name,
  605                      &tmp_ih.ih_key);
  606             }
  607 
  608             if (is_dot(name, namelen)
  609                 || (is_dot_dot(name, namelen))) {
  610                 /* do not go through "." and ".." */
  611                 ret = OK;
  612             } else {
  613                 if ((ret = add_path_key(&object_key)) == 0) {
  614                     ret =
  615                         check_semantic_pass(&object_key,
  616                                 key,
  617                                 is_dot_dot(name,
  618                                        namelen),
  619                                 &relocated_ih);
  620                     del_path_key();
  621                 }
  622             }
  623 
  624             erase_name(namelen);
  625 
  626             /* check what check_semantic_tree returned */
  627             switch (ret) {
  628             case OK:
  629                 dir_size += DEH_SIZE + entry_len;
  630                 break;
  631 
  632             case STAT_DATA_NOT_FOUND:
  633                 fsck_log
  634                     ("check_semantic_pass: Name \"%.*s\" in directory %K points to "
  635                      "nowhere\n", namelen, name,
  636                      &tmp_ih.ih_key);
  637             case LOOP_FOUND:
  638                 if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  639                     reiserfs_remove_entry(fs, &entry_key);
  640                     fsck_log(" - removed");
  641                 } else {
  642                     one_more_corruption(fs, FIXABLE);
  643                 }
  644                 fsck_log("\n");
  645                 break;
  646 
  647             case DIRECTORY_HAS_NO_ITEMS:
  648                 fsck_log
  649                     ("check_semantic_pass: Name \"%.*s\" in directory %K points a "
  650                      "directory without body\n", namelen, name,
  651                      &tmp_ih.ih_key);
  652 
  653                 /* fixme: stat data should be deleted as well */
  654                 /*
  655                    if (fsck_fix_fixable (fs)) {
  656                    reiserfs_remove_entry (fs, &entry_key);
  657                    fsck_data(fs)->deleted_entries ++;
  658                    fsck_log (" - removed");
  659                    }
  660                    fsck_log ("\n"); */
  661                 break;
  662 
  663             case RELOCATED:
  664                 /* file was relocated, update key in corresponding directory entry */
  665                 if (reiserfs_search_by_entry_key
  666                     (fs, &entry_key, &path) != POSITION_FOUND) {
  667                     fsck_log
  668                         ("Cannot find a name of the relocated file %K in the directory "
  669                          "%K\n", &entry_key,
  670                          &tmp_ih.ih_key);
  671                 } else {
  672                     /* update key dir entry points to */
  673                     struct reiserfs_de_head *tmp_deh;
  674 
  675                     tmp_deh =
  676                         B_I_DEH(get_bh(&path),
  677                             tp_item_head(&path)) +
  678                         path.pos_in_item;
  679                     fsck_log
  680                         ("The directory %K pointing to %K (\"%.*s\") updated to point "
  681                          "to ", &tmp_ih.ih_key,
  682                          &tmp_deh->deh2_dir_id, namelen,
  683                          name);
  684                     set_deh_dirid(tmp_deh,
  685                               get_key_dirid
  686                               (&relocated_ih.ih_key));
  687                     set_deh_objectid(tmp_deh,
  688                              get_key_objectid
  689                              (&relocated_ih.
  690                               ih_key));
  691 
  692                     fsck_log("%K (\"%.*s\")\n",
  693                          &tmp_deh->deh2_dir_id, namelen,
  694                          name);
  695                     mark_buffer_dirty(get_bh(&path));
  696                 }
  697                 dir_size += DEH_SIZE + entry_len;
  698                 pathrelse(&path);
  699                 break;
  700             }
  701         }       /* for */
  702 
  703         freemem(dir_item);
  704         free(name);
  705         name = NULL;
  706 
  707         if (not_of_one_file(&next_item_key, key))
  708             /* next key is not of this directory */
  709             break;
  710 
  711     }           /* while (dir_item) */
  712 
  713     if (dir_size == 0)
  714         /* FIXME: is it possible? */
  715         return DIRECTORY_HAS_NO_ITEMS;
  716 
  717     /* calc correct value of sd_blocks field of stat data */
  718     blocks = dir_size2st_blocks(dir_size);
  719 
  720     fix_sd = 0;
  721     fix_sd += wrong_st_blocks(key, &blocks, sd_blocks, mode, is_new_dir);
  722     fix_sd +=
  723         wrong_st_size(key, is_new_dir ? MAX_FILE_SIZE_V2 : MAX_FILE_SIZE_V1,
  724               fs->fs_blocksize, &dir_size, sd_size, TYPE_DIRENTRY);
  725 
  726     if (fix_sd) {
  727         if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  728             /* we have to fix either sd_size or sd_blocks, so look for stat data again */
  729             if (reiserfs_search_by_key_4(fs, key, &path) !=
  730                 ITEM_FOUND) {
  731                 fsck_log
  732                     ("check_semantic_tree: The StatData of the file %K was not found\n",
  733                      key);
  734                 one_more_corruption(fs, FATAL);
  735                 return STAT_DATA_NOT_FOUND;
  736             }
  737 
  738             bh = get_bh(&path);
  739             ih = tp_item_head(&path);
  740             sd = tp_item_body(&path);
  741 
  742             set_sd_size(ih, sd, &dir_size);
  743             set_sd_blocks(ih, sd, &blocks);
  744             mark_buffer_dirty(bh);
  745             pathrelse(&path);
  746         } else {
  747             fsck_check_stat(fs)->fixable_corruptions += fix_sd;
  748         }
  749     }
  750 
  751     return retval;
  752 }
  753 
  754 static int check_safe_links(void)
  755 {
  756     struct reiserfs_path safe_link_path, path;
  757     struct reiserfs_key safe_link_key = { cpu_to_le32(-1), 0, {{0, 0}} };
  758     struct reiserfs_key key = { 0, 0, {{0, 0}} };
  759     struct reiserfs_key *rkey;
  760     struct item_head *tmp_ih;
  761 
  762     while (1) {
  763         if (get_key_dirid(&safe_link_key) == 0)
  764             break;
  765 
  766         reiserfs_search_by_key_4(fs, &safe_link_key, &safe_link_path);
  767 
  768         if (get_blkh_nr_items(B_BLK_HEAD(get_bh(&safe_link_path))) <=
  769             PATH_LAST_POSITION(&safe_link_path)) {
  770             pathrelse(&safe_link_path);
  771             break;
  772         }
  773 
  774         tmp_ih = tp_item_head(&safe_link_path);
  775 
  776         if (get_key_dirid(&tmp_ih->ih_key) != (__u32) - 1 ||
  777             get_key_objectid(&tmp_ih->ih_key) == (__u32) - 1) {
  778             pathrelse(&safe_link_path);
  779             break;
  780         }
  781 
  782         if (get_ih_item_len(tmp_ih) != 4)
  783             reiserfs_panic("Safe Link %k cannot be of the size %d",
  784                        &tmp_ih->ih_key,
  785                        get_ih_item_len(tmp_ih));
  786 
  787         set_key_dirid(&key,
  788                   d32_get((__le32 *) tp_item_body(&safe_link_path), 0));
  789         set_key_objectid(&key, get_key_objectid(&tmp_ih->ih_key));
  790         if ((rkey = reiserfs_next_key(&safe_link_path)) == NULL)
  791             set_key_dirid(&safe_link_key, 0);
  792         else
  793             safe_link_key = *rkey;
  794 
  795         if (reiserfs_search_by_key_4(fs, &key, &path) == ITEM_NOT_FOUND) {
  796             /*sware on check, delete on fix-fixable */
  797             if (fsck_mode(fs) == FSCK_CHECK) {
  798                 fsck_log
  799                     ("Invalid safe link %k: cannot find the pointed object (%K)\n",
  800                      &tmp_ih->ih_key, &key);
  801                 one_more_corruption(fs, FIXABLE);
  802             } else if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  803                 fsck_log
  804                     ("Invalid safe link %k: cannot find the pointed object (%K) - "
  805                      "safe link was deleted\n", &tmp_ih->ih_key,
  806                      &key);
  807                 d32_put((__le32 *) tp_item_body(&safe_link_path), 0,
  808                     0);
  809                 pathrelse(&path);
  810                 reiserfsck_delete_item(&safe_link_path, 0);
  811                 continue;
  812             }
  813         } else if (get_offset(&tmp_ih->ih_key) == 0x1) {
  814             /* Truncate */
  815             if (!not_a_directory(tp_item_body(&path))) {
  816                 /*truncate on directory should not happen */
  817                 /*sware on check, delete on fix-fixable */
  818                 if (fsck_mode(fs) == FSCK_CHECK) {
  819                     fsck_log
  820                         ("Invalid 'truncate' safe link %k, cannot happen for "
  821                          "directory (%K)\n",
  822                          &tmp_ih->ih_key, &key);
  823                     one_more_corruption(fs, FIXABLE);
  824                 } else if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  825                     fsck_log
  826                         ("Invalid 'truncate' safe link %k, cannot happen for "
  827                          "a directory (%K) - safe link was deleted\n",
  828                          &tmp_ih->ih_key, &key);
  829                     d32_put((__le32 *)
  830                         tp_item_body(&safe_link_path), 0,
  831                         0);
  832                     pathrelse(&path);
  833                     reiserfsck_delete_item(&safe_link_path,
  834                                    0);
  835                     continue;
  836                 }
  837             } else {
  838                 /* save 'safe truncate links' to avoid swaring on wrong sizes. */
  839                 __u32 position;
  840 
  841                 if (reiserfs_bin_search
  842                     (&key, trunc_links, links_num, sizeof(key),
  843                      &position,
  844                      comp_short_keys) != POSITION_FOUND) {
  845                     blocklist__insert_in_position(&key,
  846                                       (void *)
  847                                       &trunc_links,
  848                                       &links_num,
  849                                       sizeof
  850                                       (key),
  851                                       &position);
  852                 }
  853             }
  854         }
  855         pathrelse(&path);
  856         pathrelse(&safe_link_path);
  857     }
  858 
  859     return OK;
  860 }
  861 
  862 static void release_safe_links(void)
  863 {
  864     freemem(trunc_links);
  865 }
  866 
  867 /* called when --check is given */
  868 void semantic_check(void)
  869 {
  870     if (fsck_data(fs)->check.bad_nodes) {
  871         fsck_progress("Bad nodes were found, Semantic pass skipped\n");
  872         goto clean;
  873     }
  874 
  875     if (fsck_data(fs)->check.fatal_corruptions) {
  876         fsck_progress
  877             ("Fatal corruptions were found, Semantic pass skipped\n");
  878         goto clean;
  879     }
  880 
  881     fsck_progress("Checking Semantic tree:\n");
  882 
  883     if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  884         /*create new_bitmap, and initialize new_bitmap & allocable bitmap */
  885         fsck_new_bitmap(fs) =
  886             reiserfs_create_bitmap(get_sb_block_count
  887                        (fs->fs_ondisk_sb));
  888         reiserfs_bitmap_copy(fsck_new_bitmap(fs), fs->fs_bitmap2);
  889         fsck_allocable_bitmap(fs) =
  890             reiserfs_create_bitmap(get_sb_block_count
  891                        (fs->fs_ondisk_sb));
  892         reiserfs_bitmap_copy(fsck_allocable_bitmap(fs), fs->fs_bitmap2);
  893         fs->block_allocator = reiserfsck_reiserfs_new_blocknrs;
  894         fs->block_deallocator = reiserfsck_reiserfs_free_block;
  895     }
  896 
  897     check_safe_links();
  898 
  899     if (check_semantic_pass(&root_dir_key, &parent_root_dir_key, 0, NULL) !=
  900         OK) {
  901         fsck_log("check_semantic_tree: No root directory found");
  902         one_more_corruption(fs, FATAL);
  903     }
  904 
  905     release_safe_links();
  906 
  907     if (fsck_mode(fs) == FSCK_FIX_FIXABLE) {
  908         reiserfs_delete_bitmap(fs->fs_bitmap2);
  909         reiserfs_bitmap_delta(fsck_new_bitmap(fs),
  910                       fsck_deallocate_bitmap(fs));
  911         fs->fs_bitmap2 = fsck_new_bitmap(fs);
  912         reiserfs_delete_bitmap(fsck_allocable_bitmap(fs));
  913         fsck_allocable_bitmap(fs) = NULL;
  914         set_sb_free_blocks(fs->fs_ondisk_sb,
  915                    reiserfs_bitmap_zeros(fs->fs_bitmap2));
  916         mark_buffer_dirty(fs->fs_super_bh);
  917         add_badblock_list(fs, 1);
  918     }
  919 
  920     fsck_progress("finished\n");
  921 
  922 clean:
  923     if (fsck_deallocate_bitmap(fs))
  924         reiserfs_delete_bitmap(fsck_deallocate_bitmap(fs));
  925 }