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

📄 fsys_ext2fs.c

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 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. *//* * The patch about "ext3 with 256-byte inode size" was made by * Stefan Lippers-Hollmann <s.L-H@gmx.de> for Debian in 2008-01-30. * Thank Barton for submittal of this patch. * 						---- Tinybit, 2008-06-24 */#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 */    /*     * These fields are for EXT2_DYNAMIC_REV superblocks only.     *     * Note: the difference between the compatible feature set and     * the incompatible feature set is that if there is a bit set     * in the incompatible feature set that the kernel doesn't     * know about, it should refuse to mount the filesystem.     *     * e2fsck's requirements are more strict; if it doesn't know     * about a feature in either the compatible or incompatible     * feature set, it must abort and not try to meddle with     * things it doesn't understand...     */    __u32 s_first_ino;		/* First non-reserved inode */    __u16 s_inode_size;		/* size of inode structure */    __u16 s_block_group_nr;	/* block group # of this superblock */    __u32 s_feature_compat;	/* compatible feature set */    __u32 s_feature_incompat;	/* incompatible feature set */    __u32 s_feature_ro_compat;	/* readonly-compatible feature set */    __u8 s_uuid[16];		/* 128-bit uuid for volume */    char s_volume_name[16];	/* volume name */    char s_last_mounted[64];	/* directory where last mounted */    __u32 s_algorithm_usage_bitmap;	/* For compression */    /*     * Performance hints. Directory preallocation should only     * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.     */    __u8 s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/    __u8 s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */    __u16 s_reserved_gdt_blocks;/* Per group table for online growth */    /*     * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.     */    __u8 s_journal_uuid[16];	/* uuid of journal superblock */    __u32 s_journal_inum;	/* inode number of journal file */    __u32 s_journal_dev;	/* device number of journal file */    __u32 s_last_orphan;	/* start of list of inodes to delete */    __u32 s_hash_seed[4];	/* HTREE hash seed */    __u8 s_def_hash_version;	/* Default hash version to use */    __u8 s_jnl_backup_type;	/* Default type of journal backup */    __u16 s_reserved_word_pad;    __u32 s_default_mount_opts;    __u32 s_first_meta_bg;	/* First metablock group */    __u32 s_mkfs_time;		/* When the filesystem was created */    __u32 s_jnl_blocks[17];	/* Backup of the journal inode */    __u32 s_reserved[172];	/* 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 NAME_BUF ((char *)(FSYS_BUF))	/* 512 bytes */#define SUPERBLOCK \    ((struct ext2_super_block *)((FSYS_BUF)+512))	/* 1024 bytes */#define GROUP_DESC \    ((struct ext2_group_desc *) \     ((int)SUPERBLOCK + sizeof(struct ext2_super_block)))	/* 32 bytes */#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_tmp(EXT2_ADDR_PER_BLOCK(s)))/* Revision levels */#define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */#define EXT2_DYNAMIC_REV	1	/* V2 format w/ dynamic inode sizes */#define EXT2_CURRENT_REV	EXT2_GOOD_OLD_REV#define EXT2_MAX_SUPP_REV	EXT2_DYNAMIC_REV#define EXT2_GOOD_OLD_INODE_SIZE	128#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)//#define EXT2_INODE_SIZE(s)		(SUPERBLOCK->s_inode_size)#define EXT2_INODES_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(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)#ifndef GRUB_UTILstatic char *linkbuf = (char *)(FSYS_BUF - PATH_MAX);	/* buffer for following symbolic links */#elsestatic char linkbuf[PATH_MAX];	/* buffer for following symbolic links */#endif/* 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 long//ffz (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){//  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)))//      return 0;        if (part_length < (SBLOCK + (sizeof(struct ext2_super_block) / DEV_BSIZE)))      return 0;  if (!devread(SBLOCK, 0, sizeof(struct ext2_super_block), (char *)SUPERBLOCK))      return 0;  if (SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)      return 0;  if (SUPERBLOCK->s_inodes_count == 0)      return 0;  if (SUPERBLOCK->s_blocks_count == 0)      return 0;  if (SUPERBLOCK->s_blocks_per_group == 0)      return 0;  if (SUPERBLOCK->s_inodes_per_group == 0)      return 0;  if (SUPERBLOCK->s_first_data_block > 1) /* 1 for 1K block, 0 otherwise */      return 0;  if (SUPERBLOCK->s_log_block_size > 4)	/* max size of block is 16K. 0 for 1K */      return 0;  if (SUPERBLOCK->s_first_data_block)  {	if (SUPERBLOCK->s_log_block_size)		return 0;  } else {	if (SUPERBLOCK->s_log_block_size == 0)		return 0;  }  if (SUPERBLOCK->s_rev_level)  {	if (SUPERBLOCK->s_inode_size == 0)		return 0;	if (EXT2_BLOCK_SIZE(SUPERBLOCK) % (SUPERBLOCK->s_inode_size))		return 0;  }  return 1;}/* 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 (unsigned long 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));  

⌨️ 快捷键说明

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