⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsys_reiserfs.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef REISERDEBUG  printf ("search_stat:\n  key %d:%d:0:0\n", dir_id, objectid);#endif /* REISERDEBUG */    depth = INFO->tree_depth;  cache = ROOT;    while (depth > DISK_LEAF_NODE_LEVEL)    {      struct key *key;      nr_item = BLOCKHEAD (cache)->blk_nr_item;            key = KEY (cache);            for (i = 0; i < nr_item; i++) 	{	  if (key->k_dir_id > dir_id	      || (key->k_dir_id == dir_id 		  && (key->k_objectid > objectid		      || (key->k_objectid == objectid			  && (key->u.v1.k_offset			      | key->u.v1.k_uniqueness) > 0))))	    break;	  key++;	}      #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;}intreiserfs_read (char *buf, int len){  unsigned int blocksize;  unsigned int offset;  unsigned int 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];	      int 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  int do_possibilities = 0;#endif /* ! STAGE1_5 */  char linkbuf[PATH_MAX];	/* buffer for following symbolic links */  int link_count = 0;  int 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))	{	  int 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++;	  if (filemax + len > sizeof (linkbuf) - 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;	}      for (rest = dirname; (ch = *rest) && ! isspace (ch) && ch != '/'; rest++);      *rest = 0;      # ifndef STAGE1_5      if (print_possibilities && ch != '/')	do_possibilities = 1;# endif /* ! STAGE1_5 */            while (1)	{	  char *name_end;	  int 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;	      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, filename);		  *name_end = tmp;# ifndef STAGE1_5		  if (do_possibilities)		    {		      if (cmp <= 0)			{			  if (print_possibilities > 0)			    print_possibilities = -print_possibilities;			  *name_end = 0;			  print_a_completion (filename);			  *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;    }}intreiserfs_embed (int *start_sector, int needed_sectors){  struct reiserfs_super_block super;  int 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       || substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) <= 0       || substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) <= 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 + -