📄 reiserfslib.c
字号:
do { ih = get_ih (&path); deh = B_I_DEH (get_bh (&path), ih) + path.pos_in_item; for (i = path.pos_in_item; i < get_ih_entry_count (ih); i ++, deh ++) { if (GET_HASH_VALUE (get_deh_offset (deh)) != GET_HASH_VALUE (hash)) { /* all entries having the same hash were scanned */ pathrelse (&path); return 0; } if (GET_GENERATION_NUMBER (get_deh_offset (deh)) == *min_gen_counter) (*min_gen_counter) ++; if ((name_in_entry_length (ih, deh, i) == (int)strlen (name)) && (!memcmp (name_in_entry (deh, i), name, strlen (name)))) { /* entry found in the directory */ if (key) { memset (key, 0, sizeof (struct key)); set_key_dirid (key, get_deh_dirid (deh)); set_key_objectid (key, get_deh_objectid (deh)); } pathrelse (&path); return 1;//get_deh_objectid (deh) ? get_deh_objectid (deh) : 1; } } rdkey = uget_rkey (&path); if (!rdkey || not_of_one_file (rdkey, dir)) { pathrelse (&path); return 0; } if (!is_direntry_key (rdkey)) reiserfs_panic ("reiserfs_find_entry: can not find name in broken directory yet"); /* next item is the item of the directory we are looking name in */ if (GET_HASH_VALUE (get_offset (rdkey)) != hash) { /* but there is no names with given hash */ pathrelse (&path); return 0; } /* first name of that item may be a name we are looking for */ entry_key = *rdkey; pathrelse (&path); retval = reiserfs_search_by_entry_key (fs, &entry_key, &path); if (retval != POSITION_FOUND) reiserfs_panic ("reiserfs_find_entry: wrong delimiting key in the tree"); } while (1); return 0;}/* compose directory entry: dir entry head and name itself */char * make_entry (char * entry, char * name, struct key * key, __u32 offset){ struct reiserfs_de_head * deh; __u16 state; if (!entry) entry = getmem (DEH_SIZE + ROUND_UP (strlen (name))); memset (entry, 0, DEH_SIZE + ROUND_UP (strlen (name))); deh = (struct reiserfs_de_head *)entry; set_deh_location (deh, 0); set_deh_offset (deh, offset); state = (1 << DEH_Visible2); set_deh_state (deh, state); /* key of object entry will point to */ set_deh_dirid (deh, get_key_dirid (key)); set_deh_objectid (deh, get_key_objectid (key)); memcpy ((char *)(deh + 1), name, strlen (name)); return entry;}/* add new name into a directory. If it exists in a directory - do nothing */int reiserfs_add_entry (reiserfs_filsys_t * fs, struct key * dir, char * name, int name_len, struct key * key, __u16 fsck_need){ struct item_head entry_ih = {{0,}, }; char * entry; int retval; INITIALIZE_PATH(path); unsigned int gen_counter; int item_len; __u32 hash; if (reiserfs_find_entry (fs, dir, name, &gen_counter, 0)) /* entry is in the directory already or directory was not found */ return 0; /* compose entry key to look for its place in the tree */ set_key_dirid (&(entry_ih.ih_key), get_key_dirid (dir)); set_key_objectid (&(entry_ih.ih_key), get_key_objectid (dir)); if (!strcmp (name, ".")) hash = DOT_OFFSET; else if (!strcmp (name, "..")) hash = DOT_DOT_OFFSET; else hash = hash_value (reiserfs_hash (fs), name, strlen (name)) + gen_counter; set_key_offset_v1 (&(entry_ih.ih_key), hash); set_key_uniqueness (&(entry_ih.ih_key), DIRENTRY_UNIQUENESS); set_ih_key_format (&entry_ih, KEY_FORMAT_1); set_ih_entry_count (&entry_ih, 1); item_len = DEH_SIZE + name_len;/* if (get_reiserfs_format (fs->fs_ondisk_sb) == REISERFS_FORMAT_3_5) item_len = DEH_SIZE + strlen (name); else if (get_reiserfs_format (fs->fs_ondisk_sb) == REISERFS_FORMAT_3_6) item_len = DEH_SIZE + ROUND_UP (strlen (name)); else reiserfs_panic ("unknown fs format");*/ set_ih_item_len (&entry_ih, item_len); /* fsck may need to insert item which was not reached yet */ set_ih_flags (&entry_ih, fsck_need); entry = make_entry (0, name, key, get_offset (&(entry_ih.ih_key))); retval = reiserfs_search_by_entry_key (fs, &(entry_ih.ih_key), &path); switch (retval) { case POSITION_NOT_FOUND: reiserfs_paste_into_item (fs, &path, entry, item_len); break; case DIRECTORY_NOT_FOUND: set_deh_location ((struct reiserfs_de_head *)entry, DEH_SIZE); reiserfs_insert_item (fs, &path, &entry_ih, entry); break; default: reiserfs_panic ("reiserfs_add_entry: looking for %k (inserting name \"%s\") " "search_by_entry_key returned %d", &(entry_ih.ih_key), name, retval); } freemem (entry); return item_len;}void copy_key (void * to, void * from){ memcpy (to, from, KEY_SIZE);}void copy_short_key (void * to, void * from){ memcpy (to, from, SHORT_KEY_SIZE);}void copy_item_head(void * p_v_to, void * p_v_from){ memcpy (p_v_to, p_v_from, IH_SIZE);}/* inserts new or old stat data of a directory (unreachable, nlinks == 0) */int create_dir_sd (reiserfs_filsys_t * fs, struct path * path, struct key * key, void (*modify_item)(struct item_head *, void *)){ struct item_head ih; struct stat_data sd; int key_format; if (fs->fs_format == REISERFS_FORMAT_3_5) key_format = KEY_FORMAT_1; else key_format = KEY_FORMAT_2; memset(&sd, 0, sizeof(sd)); make_dir_stat_data (fs->fs_blocksize, key_format, get_key_dirid (key), get_key_objectid (key), &ih, &sd); if (modify_item) modify_item (&ih, &sd);#if 0 /* set nlink count to 0 and make the item unreachable */ zero_nlink (&ih, &sd, 0); mark_item_unreachable (&ih);#endif reiserfs_insert_item (fs, path, &ih, &sd); return key_format;}void make_sure_root_dir_exists (reiserfs_filsys_t * fs, void (*modify_item)(struct item_head *, void *), int ih_flags){ INITIALIZE_PATH (path); /* is there root's stat data */ if (reiserfs_search_by_key_4 (fs, &root_dir_key, &path) == ITEM_NOT_FOUND) { root_dir_format = create_dir_sd (fs, &path, &root_dir_key, modify_item); } else { struct item_head * ih = get_ih (&path); if (!is_stat_data_ih (ih)) reiserfs_panic ("It must be root's stat data %k\n", &ih->ih_key); root_dir_format = (get_ih_item_len (get_ih (&path)) == SD_SIZE) ? KEY_FORMAT_2 : KEY_FORMAT_1; pathrelse (&path); } /* add "." and ".." if any of them do not exist. Last two parameters say: 0 - entry is not added on lost_found pass and 1 - mark item unreachable */ reiserfs_add_entry (fs, &root_dir_key, ".", name_length (".", root_dir_format), &root_dir_key, ih_flags); reiserfs_add_entry (fs, &root_dir_key, "..", name_length ("..", root_dir_format), &parent_root_dir_key, ih_flags);}/* we only can use a file for filesystem or journal if it is either not mounted block device or regular file and we are forced to use it */int can_we_format_it (char * device_name, int force){ mode_t mode; dev_t rdev; if (misc_device_mounted(device_name) > 0) { /* device looks mounted */ reiserfs_warning (stderr, "'%s' looks mounted.", device_name); check_forcing_ask_confirmation (force); } mode = misc_device_mode(device_name); rdev = misc_device_rdev(device_name); if (!S_ISBLK (mode)) { /* file is not a block device */ reiserfs_warning (stderr, "%s is not a block special device\n", device_name); check_forcing_ask_confirmation (force); } else { if ((IDE_DISK_MAJOR (major(rdev)) && minor(rdev) % 64 == 0) || (SCSI_BLK_MAJOR (major(rdev)) && minor(rdev) % 16 == 0)) { /* /dev/hda or similar */ reiserfs_warning (stderr, "%s is entire device, not just one partition!\n", device_name); check_forcing_ask_confirmation (force); } } return 1;}int create_badblock_bitmap (reiserfs_filsys_t * fs, char * badblocks_file) { FILE * fd; char buf[128]; __u32 blocknr; int count; fs->fs_badblocks_bm = reiserfs_create_bitmap(get_sb_block_count(fs->fs_ondisk_sb)); reiserfs_bitmap_zero (fs->fs_badblocks_bm); if (!badblocks_file) return 0; fd = fopen (badblocks_file, "r"); if (fd == NULL) { fprintf (stderr, "%s: Failed to open the given badblock file '%s'.\n\n", __FUNCTION__, badblocks_file); return 1; } while (!feof (fd)) { if (fgets(buf, sizeof(buf), fd) == NULL) break; count = sscanf(buf, "%u", &blocknr); if (count <= 0) continue; if (blocknr >= get_sb_block_count (fs->fs_ondisk_sb)) { fprintf (stderr, "%s: block number (%u) points out of fs size " "(%u).\n", __FUNCTION__, blocknr, get_sb_block_count(fs->fs_ondisk_sb)); } else if (not_data_block (fs, blocknr)) { fprintf (stderr, "%s: block number (%u) belongs to system " "reiserfs area. It cannot be relocated.\n", __FUNCTION__, blocknr); return 1; } else { reiserfs_bitmap_set_bit (fs->fs_badblocks_bm, blocknr); } } fclose (fd); return 0;}void badblock_list(reiserfs_filsys_t * fs, badblock_func_t action, void *data) { struct path badblock_path; struct key rd_key = badblock_key; struct key *key; badblock_path.path_length = ILLEGAL_PATH_ELEMENT_OFFSET; set_type_and_offset (KEY_FORMAT_2, &badblock_key, 1, TYPE_INDIRECT); while (1) { if (reiserfs_search_by_key_4 (fs, &rd_key, &badblock_path) == IO_ERROR) { fprintf (stderr, "%s: Some problems while searching by the key " "occured. Probably due to tree corruptions.\n", __FUNCTION__); pathrelse (&badblock_path); break; } if (get_blkh_nr_items (B_BLK_HEAD (get_bh (&badblock_path))) <= PATH_LAST_POSITION (&badblock_path)) { pathrelse (&badblock_path); break; } rd_key = get_ih(&badblock_path)->ih_key; if (get_key_dirid(&rd_key) != BADBLOCK_DIRID || get_key_objectid(&rd_key) != BADBLOCK_OBJID || !KEY_IS_INDIRECT_KEY(&rd_key)) { pathrelse (&badblock_path); break; } if ((key = reiserfs_next_key(&badblock_path))) rd_key = *key; else memset(&rd_key, 0, sizeof(rd_key)); action(fs, &badblock_path, data); if (get_key_dirid(&rd_key) == 0) break; }}static void callback_badblock_rm(reiserfs_filsys_t *fs, struct path *badblock_path, void *data) { struct tree_balance tb; struct item_head * tmp_ih; tmp_ih = get_ih(badblock_path); memset (get_item (badblock_path), 0, get_ih_item_len (tmp_ih)); init_tb_struct (&tb, fs, badblock_path, -(IH_SIZE + get_ih_item_len(PATH_PITEM_HEAD(badblock_path)))); if (fix_nodes (M_DELETE, &tb, 0) != CARRY_ON) die ("%s: fix_nodes failed", __FUNCTION__); do_balance (/*tb.transaction_handle,*/ &tb, 0, 0, M_DELETE, 0/*zero num*/);}void mark_badblock(reiserfs_filsys_t *fs, struct path *badblock_path, void *data) { struct item_head *tmp_ih; __u32 *ind_item; __u32 i; if (!fs->fs_badblocks_bm) create_badblock_bitmap(fs, NULL); tmp_ih = get_ih(badblock_path); ind_item = (__u32 *)get_item(badblock_path); for (i = 0; i < I_UNFM_NUM(tmp_ih); i++) { reiserfs_bitmap_set_bit(fs->fs_badblocks_bm, d32_get(ind_item, i)); } pathrelse (badblock_path);}void add_badblock_list (reiserfs_filsys_t * fs, int replace) { struct tree_balance tb; struct path badblock_path; struct item_head badblock_ih; __u32 ni; __u64 offset; __u32 i, j; if (fs->fs_badblocks_bm == NULL) return; /* delete all items with badblock_key */ if (replace) badblock_list(fs, callback_badblock_rm, NULL); memset(&badblock_ih, 0, sizeof(badblock_ih)); set_ih_key_format (&badblock_ih, KEY_FORMAT_2); set_ih_item_len (&badblock_ih, UNFM_P_SIZE); set_ih_free_space (&badblock_ih, 0); set_ih_location (&badblock_ih, 0); set_key_dirid (&badblock_ih.ih_key, BADBLOCK_DIRID); set_key_objectid (&badblock_ih.ih_key, BADBLOCK_OBJID); set_type (KEY_FORMAT_2, &badblock_ih.ih_key, TYPE_INDIRECT); j = 0; /* insert all badblock pointers */ for (i = 0; i < fs->fs_badblocks_bm->bm_bit_size; i++) { int retval; if (!reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i)) continue; offset = j * fs->fs_blocksize + 1; set_offset (KEY_FORMAT_2, &badblock_ih.ih_key, offset); ni = cpu_to_le32 (i); retval = usearch_by_position (fs, &badblock_ih.ih_key, key_format(&badblock_ih.ih_key), &badblock_path); switch (retval) { case (FILE_NOT_FOUND): init_tb_struct (&tb, fs, &badblock_path, IH_SIZE + get_ih_item_len(&badblock_ih)); if (fix_nodes (M_INSERT, &tb, &badblock_ih) != CARRY_ON) die ("reiserfsck_insert_item: fix_nodes failed"); do_balance (&tb, &badblock_ih, (void *)&ni , M_INSERT, 0); break; case (POSITION_NOT_FOUND): case (POSITION_FOUND): /* Insert the new item to the found position. */ init_tb_struct (&tb, fs, &badblock_path, UNFM_P_SIZE); if (fix_nodes (M_PASTE, &tb, 0) != CARRY_ON) die ("reiserfsck_paste_into_item: fix_nodes failed"); do_balance (&tb, 0, (const char *)&ni, M_PASTE, 0); break; } j++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -