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

📄 hpfs.h

📁 主要内容为linux内核代码
💻 H
📖 第 1 页 / 共 2 页
字号:
  time_t write_date;			/* mtime */
  unsigned file_size;			/* file length, bytes */
  time_t read_date;			/* atime */
  time_t creation_date;			/* ctime */
  unsigned ea_size;			/* total EA length, bytes */
  unsigned char zero1;
  unsigned char locality;		/* 0=unk 1=seq 2=random 3=both */
  unsigned char namelen, name[1];	/* file name */
  /* dnode_secno down;	  btree down pointer, if present,
     			  follows name on next word boundary, or maybe it's
			  precedes next dirent, which is on a word boundary. */
};

/* The b-tree down pointer from a dir entry */

static inline dnode_secno de_down_pointer (struct hpfs_dirent *de)
{
  return *(dnode_secno *) ((void *) de + de->length - 4);
}

/* The first dir entry in a dnode */

static inline struct hpfs_dirent *dnode_first_de (struct dnode *dnode)
{
  return (void *) dnode->dirent;
}

/* The end+1 of the dir entries */

static inline struct hpfs_dirent *dnode_end_de (struct dnode *dnode)
{
  return (void *) dnode + dnode->first_free;
}

/* The dir entry after dir entry de */

static inline struct hpfs_dirent *de_next_de (struct hpfs_dirent *de)
{
  return (void *) de + de->length;
}


/* B+ tree: allocation info in fnodes and anodes */

/* dnodes point to fnodes which are responsible for listing the sectors
   assigned to the file.  This is done with trees of (length,address)
   pairs.  (Actually triples, of (length, file-address, disk-address)
   which can represent holes.  Find out if HPFS does that.)
   At any rate, fnodes contain a small tree; if subtrees are needed
   they occupy essentially a full block in anodes.  A leaf-level tree node
   has 3-word entries giving sector runs, a non-leaf node has 2-word
   entries giving subtree pointers.  A flag in the header says which. */

struct bplus_leaf_node
{
  unsigned file_secno;			/* first file sector in extent */
  unsigned length;			/* length, sectors */
  secno disk_secno;			/* first corresponding disk sector */
};

struct bplus_internal_node
{
  unsigned file_secno;			/* subtree maps sectors < this  */
  anode_secno down;			/* pointer to subtree */
};

struct bplus_header
{
  unsigned flag0: 1;
  unsigned flag1: 1;
  unsigned flag2: 1;
  unsigned flag3: 1;
  unsigned flag4: 1;
  unsigned fnode_parent: 1;		/* ? we're pointed to by an fnode,
					   the data btree or some ea or the
					   main ea bootage pointer ea_secno */
					/* also can get set in fnodes, which
					   may be a chkdsk glitch or may mean
					   this bit is irrelevant in fnodes,
					   or this interpretation is all wet */
  unsigned flag6: 1;
  unsigned internal: 1;			/* 1 -> (internal) tree of anodes
					   0 -> (leaf) list of extents */
  unsigned char fill[3];
  unsigned char n_free_nodes;		/* free nodes in following array */
  unsigned char n_used_nodes;		/* used nodes in following array */
  unsigned short first_free;		/* offset from start of header to
					   first free node in array */
  union {
    struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving
					       subtree pointers */
    struct bplus_leaf_node external[0];	    /* (external) 3-word entries giving
					       sector runs */
  } u;
};

/* fnode: root of allocation b+ tree, and EA's */

/* Every file and every directory has one fnode, pointed to by the directory
   entry and pointing to the file's sectors or directory's root dnode.  EA's
   are also stored here, and there are said to be ACL's somewhere here too. */

#define FNODE_MAGIC 0xf7e40aae

struct fnode
{
  unsigned magic;			/* f7e4 0aae */
  unsigned zero1[2];
  unsigned char len, name[15];		/* true length, truncated name */
  fnode_secno up;			/* pointer to file's directory fnode */
  unsigned zero2[3];
  unsigned ea_size_l;			/* length of disk-resident ea's */
  secno ea_secno;			/* first sector of disk-resident ea's*/
  unsigned short ea_size_s;		/* length of fnode-resident ea's */

  unsigned flag0: 1;
  unsigned ea_anode: 1;			/* 1 -> ea_secno is an anode */
  unsigned flag2: 1;
  unsigned flag3: 1;
  unsigned flag4: 1;
  unsigned flag5: 1;
  unsigned flag6: 1;
  unsigned flag7: 1;
  unsigned dirflag: 1;			/* 1 -> directory.  first & only extent
					   points to dnode. */
  unsigned flag9: 1;
  unsigned flag10: 1;
  unsigned flag11: 1;
  unsigned flag12: 1;
  unsigned flag13: 1;
  unsigned flag14: 1;
  unsigned flag15: 1;

  struct bplus_header btree;		/* b+ tree, 8 extents or 12 subtrees */
  union {
    struct bplus_leaf_node external[8];
    struct bplus_internal_node internal[12];
  } u;

  unsigned file_size;			/* file length, bytes */
  unsigned n_needea;			/* number of EA's with NEEDEA set */
  unsigned zero4[4];
  unsigned ea_offs;			/* offset from start of fnode
					   to first fnode-resident ea */
  unsigned zero5[2];
  unsigned char ea[316];		/* zero or more EA's, packed together
					   with no alignment padding.
					   (Do not use this name, get here
					   via fnode + ea_offs. I think.) */
};


/* anode: 99.44% pure allocation tree */

#define ANODE_MAGIC 0x37e40aae

struct anode
{
  unsigned magic;			/* 37e4 0aae */
  anode_secno self;			/* pointer to this anode */
  secno up;				/* parent anode or fnode */

  struct bplus_header btree;		/* b+tree, 40 extents or 60 subtrees */
  union {
    struct bplus_leaf_node external[40];
    struct bplus_internal_node internal[60];
  } u;

  unsigned fill[3];			/* unused */
};


/* extended attributes.

   A file's EA info is stored as a list of (name,value) pairs.  It is
   usually in the fnode, but (if it's large) it is moved to a single
   sector run outside the fnode, or to multiple runs with an anode tree
   that points to them.

   The value of a single EA is stored along with the name, or (if large)
   it is moved to a single sector run, or multiple runs pointed to by an
   anode tree, pointed to by the value field of the (name,value) pair.

   Flags in the EA tell whether the value is immediate, in a single sector
   run, or in multiple runs.  Flags in the fnode tell whether the EA list
   is immediate, in a single run, or in multiple runs. */

struct extended_attribute
{
  unsigned indirect: 1;			/* 1 -> value gives sector number
					   where real value starts */
  unsigned anode: 1;			/* 1 -> sector is an anode
					   that points to fragmented value */
  unsigned flag2: 1;
  unsigned flag3: 1;
  unsigned flag4: 1;
  unsigned flag5: 1;
  unsigned flag6: 1;
  unsigned needea: 1;			/* required ea */
  unsigned char namelen;		/* length of name, bytes */
  unsigned short valuelen;		/* length of value, bytes */
  /*
    unsigned char name[namelen];	ascii attrib name
    unsigned char nul;			terminating '\0', not counted
    unsigned char value[valuelen];	value, arbitrary
      if this.indirect, valuelen is 8 and the value is
        unsigned length;		real length of value, bytes
        secno secno;			sector address where it starts
      if this.anode, the above sector number is the root of an anode tree
        which points to the value.
  */
};

static inline unsigned char *ea_name (struct extended_attribute *ea)
{
  return (void *) ea + sizeof *ea;
}

static inline unsigned char *ea_value (struct extended_attribute *ea)
{
  return (void *) ea + sizeof *ea + ea->namelen + 1;
}

static inline struct extended_attribute *
    ea_next_ea (struct extended_attribute *ea)
{
  return (void *) ea + sizeof *ea + ea->namelen + 1 + ea->valuelen;
}

static inline unsigned ea_indirect_length (struct extended_attribute *ea)
{
  unsigned *v = (void *) ea_value (ea);
  return v[0];
}

static inline secno ea_indirect_secno (struct extended_attribute *ea)
{
  unsigned *v = (void *) ea_value (ea);
  return v[1];
}

/*
   Local Variables:
   comment-column: 40
   End:
*/

⌨️ 快捷键说明

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