📄 fsys_reiserfs.c
字号:
#ifdef REISERDEBUG printf (" depth=%d, i=%d/%d\n", depth, i, nr_item);#endif /* REISERDEBUG */ INFO->next_key_nr[depth] = (i == nr_item) ? 0 : i+1; cache = read_tree_node (DC (cache)[i].dc_block_number, --depth); if (! cache) return 0; } /* cache == LEAF */ nr_item = BLOCKHEAD (LEAF)->blk_nr_item; ih = ITEMHEAD; for (i = 0; i < nr_item; i++) { if (ih->ih_key.k_dir_id == dir_id && ih->ih_key.k_objectid == objectid && ih->ih_key.u.v1.k_offset == 0 && ih->ih_key.u.v1.k_uniqueness == 0) {#ifdef REISERDEBUG printf (" depth=%d, i=%d/%d\n", depth, i, nr_item);#endif /* REISERDEBUG */ INFO->current_ih = ih; INFO->current_item = &LEAF[ih->ih_item_location]; return 1; } ih++; } errnum = ERR_FSYS_CORRUPT; return 0;}unsigned longreiserfs_read (char *buf, unsigned long len){ unsigned long blocksize; unsigned long offset; unsigned long to_read; char *prev_buf = buf; #ifdef REISERDEBUG printf ("reiserfs_read: filepos=%d len=%d, offset=%x:%x\n", filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1);#endif /* REISERDEBUG */ if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid || IH_KEY_OFFSET (INFO->current_ih) > filepos + 1) { search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid); goto get_next_key; } while (! errnum) { if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid) break; offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1; blocksize = INFO->current_ih->ih_item_len; #ifdef REISERDEBUG printf (" loop: filepos=%d len=%d, offset=%d blocksize=%d\n", filepos, len, offset, blocksize);#endif /* REISERDEBUG */ if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_DIRECT) && offset < blocksize) {#ifdef REISERDEBUG printf ("direct_read: offset=%d, blocksize=%d\n", offset, blocksize);#endif /* REISERDEBUG */ to_read = blocksize - offset; if (to_read > len) to_read = len; if (disk_read_hook != NULL) { disk_read_func = disk_read_hook; block_read (INFO->blocks[DISK_LEAF_NODE_LEVEL], (INFO->current_item - LEAF + offset), to_read, buf); disk_read_func = NULL; } else memcpy (buf, INFO->current_item + offset, to_read); goto update_buf_len; } else if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_INDIRECT)) { blocksize = (blocksize >> 2) << INFO->fullblocksize_shift;#ifdef REISERDEBUG printf ("indirect_read: offset=%d, blocksize=%d\n", offset, blocksize);#endif /* REISERDEBUG */ while (offset < blocksize) { __u32 blocknr = ((__u32 *) INFO->current_item) [offset >> INFO->fullblocksize_shift]; unsigned long blk_offset = offset & (INFO->blocksize-1); to_read = INFO->blocksize - blk_offset; if (to_read > len) to_read = len; disk_read_func = disk_read_hook; /* Journal is only for meta data. Data blocks can be read * directly without using block_read */ devread (blocknr << INFO->blocksize_shift, blk_offset, to_read, buf); disk_read_func = NULL; update_buf_len: len -= to_read; buf += to_read; offset += to_read; filepos += to_read; if (len == 0) goto done; } } get_next_key: next_key (); } done: return errnum ? 0 : buf - prev_buf;}/* preconditions: reiserfs_mount already executed, therefore * INFO block is valid * returns: 0 if error, nonzero iff we were able to find the file successfully * postconditions: on a nonzero return, INFO->fileinfo contains the info * of the file we were trying to look up, filepos is 0 and filemax is * the size of the file. */intreiserfs_dir (char *dirname){ struct reiserfs_de_head *de_head; char *rest, ch; __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;//#ifndef STAGE1_5// unsigned long do_possibilities = 0;//#endif /* ! STAGE1_5 */#ifdef GRUB_UTIL//PATH_MAX=1024 is too long for the stack! char linkbuf[PATH_MAX]; /* buffer for following symbolic links */#endif unsigned long link_count = 0; unsigned long mode; dir_id = REISERFS_ROOT_PARENT_OBJECTID; objectid = REISERFS_ROOT_OBJECTID; while (1) {#ifdef REISERDEBUG printf ("dirname=%s\n", dirname);#endif /* REISERDEBUG */ /* Search for the stat info first. */ if (! search_stat (dir_id, objectid)) return 0; #ifdef REISERDEBUG printf ("sd_mode=%x sd_size=%d\n", ((struct stat_data *) INFO->current_item)->sd_mode, ((struct stat_data *) INFO->current_item)->sd_size);#endif /* REISERDEBUG */ mode = ((struct stat_data *) INFO->current_item)->sd_mode; /* If we've got a symbolic link, then chase it. */ if (S_ISLNK (mode)) { unsigned long len; if (++link_count > MAX_LINK_COUNT) { errnum = ERR_SYMLINK_LOOP; return 0; } /* Get the symlink size. */ filemax = ((struct stat_data *) INFO->current_item)->sd_size; /* Find out how long our remaining name is. */ //len = 0; //while (dirname[len] && !isspace (dirname[len])) // len++; for (len = 0; (ch = dirname[len]) && !isspace (ch); len++) { if (ch == '\\') { len++; if (! (ch = dirname[len])) break; } } if (filemax + len > PATH_MAX - 1) { errnum = ERR_FILELENGTH; return 0; } /* Copy the remaining name to the end of the symlink data. Note that DIRNAME and LINKBUF may overlap! */ grub_memmove (linkbuf + filemax, dirname, len+1); INFO->fileinfo.k_dir_id = dir_id; INFO->fileinfo.k_objectid = objectid; filepos = 0; if (! next_key () || reiserfs_read (linkbuf, filemax) != filemax) { if (! errnum) errnum = ERR_FSYS_CORRUPT; return 0; }#ifdef REISERDEBUG printf ("symlink=%s\n", linkbuf);#endif /* REISERDEBUG */ dirname = linkbuf; if (*dirname == '/') { /* It's an absolute link, so look it up in root. */ dir_id = REISERFS_ROOT_PARENT_OBJECTID; objectid = REISERFS_ROOT_OBJECTID; } else { /* Relative, so look it up in our parent directory. */ dir_id = parent_dir_id; objectid = parent_objectid; } /* Now lookup the new name. */ continue; } /* if we have a real file (and we're not just printing possibilities), then this is where we want to exit */ if (! *dirname || isspace (*dirname)) { if (! S_ISREG (mode)) { errnum = ERR_BAD_FILETYPE; return 0; } filepos = 0; filemax = ((struct stat_data *) INFO->current_item)->sd_size; /* If this is a new stat data and size is > 4GB set filemax to * maximum */ if (INFO->current_ih->ih_version == ITEM_VERSION_2 && ((struct stat_data *) INFO->current_item)->sd_size_hi > 0) filemax = 0xffffffff; INFO->fileinfo.k_dir_id = dir_id; INFO->fileinfo.k_objectid = objectid; return next_key (); } /* continue with the file/directory name interpretation */ while (*dirname == '/') dirname++; if (! S_ISDIR (mode)) { errnum = ERR_BAD_FILETYPE; return 0; } /* skip to next slash or end of filename (space) */// for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++); for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++) { if (ch == '\\') { rest++; if (! (ch = *rest)) break; } } *rest = 0; //# ifndef STAGE1_5// if (print_possibilities && ch != '/')// do_possibilities = 1;//# endif /* ! STAGE1_5 */ while (1) { char *name_end; unsigned long num_entries; if (! next_key ()) return 0;#ifdef REISERDEBUG printf ("ih: key %d:%d:%d:%d version:%d\n", INFO->current_ih->ih_key.k_dir_id, INFO->current_ih->ih_key.k_objectid, INFO->current_ih->ih_key.u.v1.k_offset, INFO->current_ih->ih_key.u.v1.k_uniqueness, INFO->current_ih->ih_version);#endif /* REISERDEBUG */ if (INFO->current_ih->ih_key.k_objectid != objectid) break; name_end = INFO->current_item + INFO->current_ih->ih_item_len; de_head = (struct reiserfs_de_head *) INFO->current_item; num_entries = INFO->current_ih->u.ih_entry_count; while (num_entries > 0) { char *filename = INFO->current_item + de_head->deh_location; //char tmp = *name_end; int j, k; char ch1; //char *tmp_name = NAME_BUF;#ifdef GRUB_UTIL char tmp_name[2048];#endif /* Name length = name_end - filename */ /* copy filename to tmp_name, and quote spaces with '\\' */ for (j = 0, k = 0; j < name_end - filename; j++) { if (! (ch1 = filename[j])) break; if (ch1 == ' ') tmp_name[k++] = '\\'; tmp_name[k++] = ch1; } tmp_name[k] = 0; if ((de_head->deh_state & DEH_Visible)) { int cmp; /* Directory names in ReiserFS are not null * terminated. We write a temporary 0 behind it. * NOTE: that this may overwrite the first block in * the tree cache. That doesn't hurt as long as we * don't call next_key () in between. */ //*name_end = 0; cmp = substring (dirname, tmp_name, 0); //*name_end = tmp;# ifndef STAGE1_5 if (print_possibilities && ch != '/') { if (cmp <= 0) { if (print_possibilities > 0) print_possibilities = -print_possibilities; //*name_end = 0; print_a_completion (tmp_name); //*name_end = tmp; } } else# endif /* ! STAGE1_5 */ if (cmp == 0) goto found; } /* The beginning of this name marks the end of the next name. */ name_end = filename; de_head++; num_entries--; } } # ifndef STAGE1_5 if (print_possibilities < 0) return 1;# endif /* ! STAGE1_5 */ errnum = ERR_FILE_NOT_FOUND; *rest = ch; return 0; found: *rest = ch; dirname = rest; parent_dir_id = dir_id; parent_objectid = objectid; dir_id = de_head->deh_dir_id; objectid = de_head->deh_objectid; }}unsigned longreiserfs_embed (unsigned long *start_sector, unsigned long needed_sectors){#ifdef GRUB_UTIL struct reiserfs_super_block super1; //struct size 202. Too many!! struct reiserfs_super_block *super = &super1;#endif unsigned long num_sectors; if (! devread (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS, 0, sizeof (struct reiserfs_super_block), (char *) super)) return 0; *start_sector = 1; /* reserve first sector for stage1 */ if ((substring (REISERFS_SUPER_MAGIC_STRING, super->s_magic, 0) <= 0 || substring (REISER2FS_SUPER_MAGIC_STRING, super->s_magic, 0) <= 0 || substring (REISER3FS_SUPER_MAGIC_STRING, super->s_magic, 0) <= 0) && (/* check that this is not a super block copy inside * the journal log */ super->s_journal_block * super->s_blocksize > REISERFS_DISK_OFFSET_IN_BYTES)) num_sectors = (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1; else num_sectors = (REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1; return (needed_sectors <= num_sectors);}#endif /* FSYS_REISERFS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -