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

📄 fsys_reiserfs.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 3 页
字号:
/* fsys_reiserfs.c - an implementation for the ReiserFS filesystem *//* *  GRUB  --  GRand Unified Bootloader *  Copyright (C) 2000, 2001  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_REISERFS#include "shared.h"#include "filesys.h"#undef REISERDEBUG/* Some parts of this code (mainly the structures and defines) are * from the original reiser fs code, as found in the linux kernel. *//* 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;typedef unsigned long long __u64;/* linux/posix_type.h */typedef long linux_off_t;/* linux/little_endian.h */#define __cpu_to_le64(x) ((__u64) (x))#define __le64_to_cpu(x) ((__u64) (x))#define __cpu_to_le32(x) ((__u32) (x))#define __le32_to_cpu(x) ((__u32) (x))#define __cpu_to_le16(x) ((__u16) (x))#define __le16_to_cpu(x) ((__u16) (x))/* include/linux/reiser_fs.h *//* This is the new super block of a journaling reiserfs system */struct reiserfs_super_block{  __u32 s_block_count;			/* blocks count         */  __u32 s_free_blocks;                  /* free blocks count    */  __u32 s_root_block;           	/* root block number    */  __u32 s_journal_block;           	/* journal block number    */  __u32 s_journal_dev;           	/* journal device number  */  __u32 s_journal_size; 		/* size of the journal on FS creation.  used to make sure they don't overflow it */  __u32 s_journal_trans_max;            /* max number of blocks in a transaction.  */  __u32 s_journal_magic;                /* random value made on fs creation */  __u32 s_journal_max_batch;            /* max number of blocks to batch into a trans */  __u32 s_journal_max_commit_age;       /* in seconds, how old can an async commit be */  __u32 s_journal_max_trans_age;        /* in seconds, how old can a transaction be */  __u16 s_blocksize;                   	/* block size           */  __u16 s_oid_maxsize;			/* max size of object id array  */  __u16 s_oid_cursize;			/* current size of object id array */  __u16 s_state;                       	/* valid or error       */  char s_magic[16];                     /* reiserfs magic string indicates that file system is reiserfs */  __u16 s_tree_height;                  /* height of disk tree */  __u16 s_bmap_nr;                      /* amount of bitmap blocks needed to address each block of file system */  __u16 s_version;  char s_unused[128];			/* zero filled by mkreiserfs */};#define REISERFS_MAX_SUPPORTED_VERSION 2#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"#define REISER3FS_SUPER_MAGIC_STRING "ReIsEr3Fs"#define MAX_HEIGHT 7/* must be correct to keep the desc and commit structs at 4k */#define JOURNAL_TRANS_HALF 1018/* first block written in a commit.  */struct reiserfs_journal_desc {  __u32 j_trans_id;			/* id of commit */  __u32 j_len;				/* length of commit. len +1 is the commit block */  __u32 j_mount_id;			/* mount id of this trans*/  __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the first blocks */  char j_magic[12];};/* last block written in a commit */struct reiserfs_journal_commit {  __u32 j_trans_id;			/* must match j_trans_id from the desc block */  __u32 j_len;			/* ditto */  __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the last blocks */  char j_digest[16];			/* md5 sum of all the blocks involved, including desc and commit. not used, kill it */};/* this header block gets written whenever a transaction is considered   fully flushed, and is more recent than the last fully flushed   transaction.     fully flushed means all the log blocks and all the real blocks are   on disk, and this transaction does not need to be replayed.  */struct reiserfs_journal_header {  /* id of last fully flushed transaction */  __u32 j_last_flush_trans_id;  /* offset in the log of where to start replay after a crash */  __u32 j_first_unflushed_offset;  /* mount id to detect very old transactions */  __u32 j_mount_id;};/* magic string to find desc blocks in the journal */#define JOURNAL_DESC_MAGIC "ReIsErLB" /* * directories use this key as well as old files */struct offset_v1{  /*   * for regular files this is the offset to the first byte of the   * body, contained in the object-item, as measured from the start of   * the entire body of the object.   *   * for directory entries, k_offset consists of hash derived from   * hashing the name and using few bits (23 or more) of the resulting   * hash, and generation number that allows distinguishing names with   * hash collisions. If number of collisions overflows generation   * number, we return EEXIST.  High order bit is 0 always    */  __u32 k_offset;  __u32 k_uniqueness;};struct offset_v2{  /*   * for regular files this is the offset to the first byte of the   * body, contained in the object-item, as measured from the start of   * the entire body of the object.   *   * for directory entries, k_offset consists of hash derived from   * hashing the name and using few bits (23 or more) of the resulting   * hash, and generation number that allows distinguishing names with   * hash collisions. If number of collisions overflows generation   * number, we return EEXIST.  High order bit is 0 always    */  __u64 k_offset:60;  __u64 k_type: 4;};struct key{  /* packing locality: by default parent directory object id */  __u32 k_dir_id;  /* object identifier */  __u32 k_objectid;  /* the offset and node type (old and new form) */  union  {    struct offset_v1 v1;    struct offset_v2 v2;  }  u;};#define KEY_SIZE (sizeof (struct key))/* Header of a disk block.  More precisely, header of a formatted leaf   or internal node, and not the header of an unformatted node. */struct block_head{         __u16 blk_level;        /* Level of a block in the tree. */  __u16 blk_nr_item;      /* Number of keys/items in a block. */  __u16 blk_free_space;   /* Block free space in bytes. */  struct key  blk_right_delim_key; /* Right delimiting key for this block (supported for leaf level nodes				      only) */};#define BLKH_SIZE (sizeof (struct block_head))#define DISK_LEAF_NODE_LEVEL  1 /* Leaf node level.                       */struct item_head{  struct key ih_key; 	/* Everything in the tree is found by searching for it based on its key.*/    union  {    __u16 ih_free_space; /* The free space in the last unformatted node of an indirect item if this			    is an indirect item.  This equals 0xFFFF iff this is a direct item or			    stat data item. Note that the key, not this field, is used to determine			    the item type, and thus which field this union contains. */    __u16 ih_entry_count; /* Iff this is a directory item, this field equals the number of directory			     entries in the directory item. */  }  u;  __u16 ih_item_len;           /* total size of the item body                  */  __u16 ih_item_location;      /* an offset to the item body within the block  */  __u16 ih_version;	       /* ITEM_VERSION_1 for all old items, 				  ITEM_VERSION_2 for new ones. 				  Highest bit is set by fsck                                  temporary, cleaned after all done */};/* size of item header     */#define IH_SIZE (sizeof (struct item_head))#define ITEM_VERSION_1 0#define ITEM_VERSION_2 1#define IH_KEY_OFFSET(ih) ((ih)->ih_version == ITEM_VERSION_1 \			   ? (ih)->ih_key.u.v1.k_offset \			   : (ih)->ih_key.u.v2.k_offset)#define IH_KEY_ISTYPE(ih, type) ((ih)->ih_version == ITEM_VERSION_1 \				 ? (ih)->ih_key.u.v1.k_uniqueness == V1_##type \				 : (ih)->ih_key.u.v2.k_type == V2_##type)struct disk_child{  unsigned long       dc_block_number;              /* Disk child's block number. */  unsigned short      dc_size;		            /* Disk child's used space.   */};#define DC_SIZE (sizeof (struct disk_child))/* Stat Data on disk. * * Note that reiserfs has two different forms of stat data.  Luckily * the fields needed by grub are at the same position. */struct stat_data{  __u16 sd_mode;	/* file type, permissions */  __u16 sd_notused1[3]; /* fields not needed by reiserfs */  __u32 sd_size;	/* file size */  __u32 sd_size_hi;	/* file size high 32 bits (since version 2) */};struct reiserfs_de_head{  __u32 deh_offset;  /* third component of the directory entry key */  __u32 deh_dir_id;  /* objectid of the parent directory of the			object, that is referenced by directory entry */  __u32 deh_objectid;/* objectid of the object, that is referenced by                        directory entry */  __u16 deh_location;/* offset of name in the whole item */  __u16 deh_state;   /* whether 1) entry contains stat data (for			future), and 2) whether entry is hidden			(unlinked) */};#define DEH_SIZE (sizeof (struct reiserfs_de_head))#define DEH_Statdata (1 << 0)			/* not used now */#define DEH_Visible  (1 << 2)#define SD_OFFSET  0#define SD_UNIQUENESS 0#define DOT_OFFSET 1#define DOT_DOT_OFFSET 2#define DIRENTRY_UNIQUENESS 500#define V1_TYPE_STAT_DATA 0x0#define V1_TYPE_DIRECT 0xffffffff#define V1_TYPE_INDIRECT 0xfffffffe#define V1_TYPE_DIRECTORY_MAX 0xfffffffd#define V2_TYPE_STAT_DATA 0#define V2_TYPE_INDIRECT 1#define V2_TYPE_DIRECT 2#define V2_TYPE_DIRENTRY 3 #define REISERFS_ROOT_OBJECTID 2#define REISERFS_ROOT_PARENT_OBJECTID 1#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)/* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)#define REISERFS_OLD_BLOCKSIZE 4096#define S_ISREG(mode) (((mode) & 0170000) == 0100000)#define S_ISDIR(mode) (((mode) & 0170000) == 0040000)#define S_ISLNK(mode) (((mode) & 0170000) == 0120000)#define PATH_MAX       1024	/* include/linux/limits.h */#define MAX_LINK_COUNT    5	/* number of symbolic links to follow *//* The size of the node cache */#define FSYSREISER_CACHE_SIZE 24*1024#define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE#define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3/* Info about currently opened file */struct fsys_reiser_fileinfo{  __u32 k_dir_id;  __u32 k_objectid;};/* In memory info about the currently mounted filesystem */struct fsys_reiser_info{  /* The last read item head */  struct item_head *current_ih;  /* The last read item */  char *current_item;  /* The information for the currently opened file */  struct fsys_reiser_fileinfo fileinfo;  /* The start of the journal */  __u32 journal_block;  /* The size of the journal */  __u32 journal_block_count;  /* The first valid descriptor block in journal     (relative to journal_block) */  __u32 journal_first_desc;  /* The ReiserFS version. */  __u16 version;  /* The current depth of the reiser tree. */  __u16 tree_depth;  /* SECTOR_SIZE << blocksize_shift == blocksize. */  __u8  blocksize_shift;  /* 1 << full_blocksize_shift == blocksize. */  __u8  fullblocksize_shift;  /* The reiserfs block size  (must be a power of 2) */  __u16 blocksize;  /* The number of cached tree nodes */  __u16 cached_slots;  /* The number of valid transactions in journal */  __u16 journal_transactions;    unsigned int blocks[MAX_HEIGHT];  unsigned int next_key_nr[MAX_HEIGHT];};/* The cached s+tree blocks in FSYS_BUF,  see below * for a more detailed description. */#define ROOT     ((char *) ((int) FSYS_BUF))#define CACHE(i) (ROOT + ((i) << INFO->fullblocksize_shift))#define LEAF     CACHE (DISK_LEAF_NODE_LEVEL)#define BLOCKHEAD(cache) ((struct block_head *) cache)#define ITEMHEAD         ((struct item_head  *) ((int) LEAF + BLKH_SIZE))#define KEY(cache)       ((struct key        *) ((int) cache + BLKH_SIZE))#define DC(cache)        ((struct disk_child *) \			  ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))/* The fsys_reiser_info block. */#define INFO \    ((struct fsys_reiser_info *) ((int) FSYS_BUF + FSYSREISER_CACHE_SIZE))/*  * The journal cache.  For each transaction it contains the number of * blocks followed by the real block numbers of this transaction.   * * If the block numbers of some transaction won't fit in this space, * this list is stopped with a 0xffffffff marker and the remaining * uncommitted transactions aren't cached.   */#define JOURNAL_START    ((__u32 *) (INFO + 1))#define JOURNAL_END      ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))static __inline__ unsigned longlog2 (unsigned long word){  __asm__ ("bsfl %1,%0"	   : "=r" (word)	   : "r" (word));  return word;}static __inline__ intis_power_of_two (unsigned long word){  return (word & -word) == word;}static int journal_read (int block, int len, char *buffer) {  return devread ((INFO->journal_block + block) << INFO->blocksize_shift, 		  0, len, buffer);}/* Read a block from ReiserFS file system, taking the journal into * account.  If the block nr is in the journal, the block from the * journal taken.   */static intblock_read (int blockNr, int start, int len, char *buffer){  int transactions = INFO->journal_transactions;  int desc_block = INFO->journal_first_desc;  int journal_mask = INFO->journal_block_count - 1;  int translatedNr = blockNr;  __u32 *journal_table = JOURNAL_START;  while (transactions-- > 0)     {      int i = 0;      int j_len;      if (*journal_table != 0xffffffff)	{	  /* Search for the blockNr in cached journal */	  j_len = *journal_table++;	  while (i++ < j_len)	    {	      if (*journal_table++ == blockNr)

⌨️ 快捷键说明

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