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

📄 fsys_ext2fs.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  GRUB  --  GRand Unified Bootloader *  Copyright (C) 1999, 2001, 2003  Free Software Foundation, Inc. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#ifdef FSYS_EXT2FS#include "shared.h"#include "filesys.h"static int mapblock1, mapblock2;/* sizes are always in bytes, BLOCK values are always in DEV_BSIZE (sectors) */#define DEV_BSIZE 512/* include/linux/fs.h */#define BLOCK_SIZE 1024		/* initial block size for superblock read *//* made up, defaults to 1 but can be passed via mount_opts */#define WHICH_SUPER 1/* kind of from fs/ext2/super.c */#define SBLOCK (WHICH_SUPER * BLOCK_SIZE / DEV_BSIZE)	/* = 2 *//* include/asm-i386/types.h */typedef __signed__ char __s8;typedef unsigned char __u8;typedef __signed__ short __s16;typedef unsigned short __u16;typedef __signed__ int __s32;typedef unsigned int __u32;/* * Constants relative to the data blocks, from ext2_fs.h */#define EXT2_NDIR_BLOCKS                12#define EXT2_IND_BLOCK                  EXT2_NDIR_BLOCKS#define EXT2_DIND_BLOCK                 (EXT2_IND_BLOCK + 1)#define EXT2_TIND_BLOCK                 (EXT2_DIND_BLOCK + 1)#define EXT2_N_BLOCKS                   (EXT2_TIND_BLOCK + 1)/* include/linux/ext2_fs.h */struct ext2_super_block  {    __u32 s_inodes_count;	/* Inodes count */    __u32 s_blocks_count;	/* Blocks count */    __u32 s_r_blocks_count;	/* Reserved blocks count */    __u32 s_free_blocks_count;	/* Free blocks count */    __u32 s_free_inodes_count;	/* Free inodes count */    __u32 s_first_data_block;	/* First Data Block */    __u32 s_log_block_size;	/* Block size */    __s32 s_log_frag_size;	/* Fragment size */    __u32 s_blocks_per_group;	/* # Blocks per group */    __u32 s_frags_per_group;	/* # Fragments per group */    __u32 s_inodes_per_group;	/* # Inodes per group */    __u32 s_mtime;		/* Mount time */    __u32 s_wtime;		/* Write time */    __u16 s_mnt_count;		/* Mount count */    __s16 s_max_mnt_count;	/* Maximal mount count */    __u16 s_magic;		/* Magic signature */    __u16 s_state;		/* File system state */    __u16 s_errors;		/* Behaviour when detecting errors */    __u16 s_pad;    __u32 s_lastcheck;		/* time of last check */    __u32 s_checkinterval;	/* max. time between checks */    __u32 s_creator_os;		/* OS */    __u32 s_rev_level;		/* Revision level */    __u16 s_def_resuid;		/* Default uid for reserved blocks */    __u16 s_def_resgid;		/* Default gid for reserved blocks */    __u32 s_reserved[235];	/* Padding to the end of the block */  };struct ext2_group_desc  {    __u32 bg_block_bitmap;	/* Blocks bitmap block */    __u32 bg_inode_bitmap;	/* Inodes bitmap block */    __u32 bg_inode_table;	/* Inodes table block */    __u16 bg_free_blocks_count;	/* Free blocks count */    __u16 bg_free_inodes_count;	/* Free inodes count */    __u16 bg_used_dirs_count;	/* Directories count */    __u16 bg_pad;    __u32 bg_reserved[3];  };struct ext2_inode  {    __u16 i_mode;		/* File mode */    __u16 i_uid;		/* Owner Uid */    __u32 i_size;		/* 4: Size in bytes */    __u32 i_atime;		/* Access time */    __u32 i_ctime;		/* 12: Creation time */    __u32 i_mtime;		/* Modification time */    __u32 i_dtime;		/* 20: Deletion Time */    __u16 i_gid;		/* Group Id */    __u16 i_links_count;	/* 24: Links count */    __u32 i_blocks;		/* Blocks count */    __u32 i_flags;		/* 32: File flags */    union      {	struct	  {	    __u32 l_i_reserved1;	  }	linux1;	struct	  {	    __u32 h_i_translator;	  }	hurd1;	struct	  {	    __u32 m_i_reserved1;	  }	masix1;      }    osd1;			/* OS dependent 1 */    __u32 i_block[EXT2_N_BLOCKS];	/* 40: Pointers to blocks */    __u32 i_version;		/* File version (for NFS) */    __u32 i_file_acl;		/* File ACL */    __u32 i_dir_acl;		/* Directory ACL */    __u32 i_faddr;		/* Fragment address */    union      {	struct	  {	    __u8 l_i_frag;	/* Fragment number */	    __u8 l_i_fsize;	/* Fragment size */	    __u16 i_pad1;	    __u32 l_i_reserved2[2];	  }	linux2;	struct	  {	    __u8 h_i_frag;	/* Fragment number */	    __u8 h_i_fsize;	/* Fragment size */	    __u16 h_i_mode_high;	    __u16 h_i_uid_high;	    __u16 h_i_gid_high;	    __u32 h_i_author;	  }	hurd2;	struct	  {	    __u8 m_i_frag;	/* Fragment number */	    __u8 m_i_fsize;	/* Fragment size */	    __u16 m_pad1;	    __u32 m_i_reserved2[2];	  }	masix2;      }    osd2;			/* OS dependent 2 */  };/* linux/limits.h */#define NAME_MAX         255	/* # chars in a file name *//* linux/posix_type.h */typedef long linux_off_t;/* linux/ext2fs.h */#define EXT2_NAME_LEN 255struct ext2_dir_entry  {    __u32 inode;		/* Inode number */    __u16 rec_len;		/* Directory entry length */    __u8 name_len;		/* Name length */    __u8 file_type;    char name[EXT2_NAME_LEN];	/* File name */  };/* linux/ext2fs.h *//* * EXT2_DIR_PAD defines the directory entries boundaries * * NOTE: It must be a multiple of 4 */#define EXT2_DIR_PAD                    4#define EXT2_DIR_ROUND                  (EXT2_DIR_PAD - 1)#define EXT2_DIR_REC_LEN(name_len)      (((name_len) + 8 + EXT2_DIR_ROUND) & \                                         ~EXT2_DIR_ROUND)/* ext2/super.c */#define log2(n) ffz(~(n))#define EXT2_SUPER_MAGIC      0xEF53	/* include/linux/ext2_fs.h */#define EXT2_ROOT_INO              2	/* include/linux/ext2_fs.h */#define PATH_MAX                1024	/* include/linux/limits.h */#define MAX_LINK_COUNT             5	/* number of symbolic links to follow *//* made up, these are pointers into FSYS_BUF *//* read once, always stays there: */#define SUPERBLOCK \    ((struct ext2_super_block *)(FSYS_BUF))#define GROUP_DESC \    ((struct ext2_group_desc *) \     ((int)SUPERBLOCK + sizeof(struct ext2_super_block)))#define INODE \    ((struct ext2_inode *)((int)GROUP_DESC + EXT2_BLOCK_SIZE(SUPERBLOCK)))#define DATABLOCK1 \    ((int)((int)INODE + sizeof(struct ext2_inode)))#define DATABLOCK2 \    ((int)((int)DATABLOCK1 + EXT2_BLOCK_SIZE(SUPERBLOCK)))/* linux/ext2_fs.h */#define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))#define EXT2_ADDR_PER_BLOCK_BITS(s)		(log2(EXT2_ADDR_PER_BLOCK(s)))/* linux/ext2_fs.h */#define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)/* kind of from ext2/super.c */#define EXT2_BLOCK_SIZE(s)	(1 << EXT2_BLOCK_SIZE_BITS(s))/* linux/ext2fs.h */#define EXT2_DESC_PER_BLOCK(s) \     (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))/* linux/stat.h */#define S_IFMT  00170000#define S_IFLNK  0120000#define S_IFREG  0100000#define S_IFDIR  0040000#define S_ISLNK(m)	(((m) & S_IFMT) == S_IFLNK)#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)/* include/asm-i386/bitops.h *//* * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. */static __inline__ unsigned longffz (unsigned long word){  __asm__ ("bsfl %1,%0":	   "=r" (word):	   "r" (~word));  return word;}/* check filesystem types and read superblock into memory buffer */intext2fs_mount (void){  int retval = 1;  if ((((current_drive & 0x80) || (current_slice != 0))       && (current_slice != PC_SLICE_TYPE_EXT2FS)       && (current_slice != PC_SLICE_TYPE_LINUX_RAID)       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)))      || part_length < (SBLOCK + (sizeof (struct ext2_super_block) / DEV_BSIZE))      || !devread (SBLOCK, 0, sizeof (struct ext2_super_block),		   (char *) SUPERBLOCK)      || SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)      retval = 0;  return retval;}/* Takes a file system block number and reads it into BUFFER. */static intext2_rdfsb (int fsblock, int buffer){#ifdef E2DEBUG  printf ("fsblock %d buffer %d\n", fsblock, buffer);#endif /* E2DEBUG */  return devread (fsblock * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE), 0,		  EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);}/* from  ext2/inode.c:ext2_bmap()*//* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into   a physical block (the location in the file system) via an inode. */static intext2fs_block_map (int logical_block){#ifdef E2DEBUG  unsigned char *i;  for (i = (unsigned char *) INODE;       i < ((unsigned char *) INODE + sizeof (struct ext2_inode));       i++)    {      printf ("%c", "0123456789abcdef"[*i >> 4]);      printf ("%c", "0123456789abcdef"[*i % 16]);      if (!((i + 1 - (unsigned char *) INODE) % 16))	{	  printf ("\n");	}      else	{	  printf (" ");	}    }  printf ("logical block %d\n", logical_block);#endif /* E2DEBUG */  /* if it is directly pointed to by the inode, return that physical addr */  if (logical_block < EXT2_NDIR_BLOCKS)    {#ifdef E2DEBUG      printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));      printf ("returning %d\n", INODE->i_block[logical_block]);#endif /* E2DEBUG */      return INODE->i_block[logical_block];    }  /* else */  logical_block -= EXT2_NDIR_BLOCKS;  /* try the indirect block */  if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK))    {      if (mapblock1 != 1	  && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))	{	  errnum = ERR_FSYS_CORRUPT;	  return -1;	}      mapblock1 = 1;      return ((__u32 *) DATABLOCK1)[logical_block];    }  /* else */  logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK);  /* now try the double indirect block */  if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)))    {      int bnum;      if (mapblock1 != 2	  && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1))	{	  errnum = ERR_FSYS_CORRUPT;	  return -1;	}      mapblock1 = 2;      if ((bnum = (((__u32 *) DATABLOCK1)		   [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)]))	  != mapblock2	  && !ext2_rdfsb (bnum, DATABLOCK2))	{	  errnum = ERR_FSYS_CORRUPT;	  return -1;	}      mapblock2 = bnum;      return ((__u32 *) DATABLOCK2)	[logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];    }  /* else */  mapblock2 = -1;  logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));  if (mapblock1 != 3      && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))    {      errnum = ERR_FSYS_CORRUPT;      return -1;    }  mapblock1 = 3;  if (!ext2_rdfsb (((__u32 *) DATABLOCK1)		   [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)				      * 2)],		   DATABLOCK2))    {      errnum = ERR_FSYS_CORRUPT;      return -1;    }  if (!ext2_rdfsb (((__u32 *) DATABLOCK2)		   [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))		    & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],		   DATABLOCK2))    {      errnum = ERR_FSYS_CORRUPT;      return -1;    }  return ((__u32 *) DATABLOCK2)    [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];}/* preconditions: all preconds of ext2fs_block_map */intext2fs_read (char *buf, int len){  int logical_block;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -