15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* fsys_reiserfs.c - an implementation for the ReiserFS filesystem */
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  GRUB  --  GRand Unified Bootloader
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This program is free software; you can redistribute it and/or modify
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  it under the terms of the GNU General Public License as published by
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  the Free Software Foundation; either version 2 of the License, or
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  (at your option) any later version.
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This program is distributed in the hope that it will be useful,
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  GNU General Public License for more details.
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  You should have received a copy of the GNU General Public License
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  along with this program; if not, write to the Free Software
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef FSYS_REISERFS
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "shared.h"
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "filesys.h"
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#undef REISERDEBUG
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Some parts of this code (mainly the structures and defines) are
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * from the original reiser fs code, as found in the linux kernel.
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* include/asm-i386/types.h */
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef __signed__ char __s8;
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef unsigned char __u8;
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef __signed__ short __s16;
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef unsigned short __u16;
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef __signed__ int __s32;
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef unsigned int __u32;
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef unsigned long long __u64;
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* linux/posix_type.h */
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef long linux_off_t;
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* linux/little_endian.h */
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define __cpu_to_le64(x) ((__u64) (x))
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define __le64_to_cpu(x) ((__u64) (x))
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define __cpu_to_le32(x) ((__u32) (x))
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define __le32_to_cpu(x) ((__u32) (x))
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define __cpu_to_le16(x) ((__u16) (x))
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define __le16_to_cpu(x) ((__u16) (x))
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* include/linux/reiser_fs.h */
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* This is the new super block of a journaling reiserfs system */
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct reiserfs_super_block
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_block_count;			/* blocks count         */
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_free_blocks;                  /* free blocks count    */
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_root_block;           	/* root block number    */
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_journal_block;           	/* journal block number    */
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_journal_dev;           	/* journal device number  */
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_journal_size; 		/* size of the journal on FS creation.  used to make sure they don't overflow it */
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_journal_trans_max;            /* max number of blocks in a transaction.  */
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_journal_magic;                /* random value made on fs creation */
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_journal_max_batch;            /* max number of blocks to batch into a trans */
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_journal_max_commit_age;       /* in seconds, how old can an async commit be */
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 s_journal_max_trans_age;        /* in seconds, how old can a transaction be */
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 s_blocksize;                   	/* block size           */
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 s_oid_maxsize;			/* max size of object id array  */
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 s_oid_cursize;			/* current size of object id array */
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 s_state;                       	/* valid or error       */
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char s_magic[16];                     /* reiserfs magic string indicates that file system is reiserfs */
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 s_tree_height;                  /* height of disk tree */
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 s_bmap_nr;                      /* amount of bitmap blocks needed to address each block of file system */
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 s_version;
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char s_unused[128];			/* zero filled by mkreiserfs */
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISERFS_MAX_SUPPORTED_VERSION 2
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISER3FS_SUPER_MAGIC_STRING "ReIsEr3Fs"
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define MAX_HEIGHT 7
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* must be correct to keep the desc and commit structs at 4k */
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define JOURNAL_TRANS_HALF 1018
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* first block written in a commit.  */
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct reiserfs_journal_desc {
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_trans_id;			/* id of commit */
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_len;				/* length of commit. len +1 is the commit block */
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_mount_id;			/* mount id of this trans*/
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the first blocks */
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char j_magic[12];
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* last block written in a commit */
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct reiserfs_journal_commit {
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_trans_id;			/* must match j_trans_id from the desc block */
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_len;			/* ditto */
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the last blocks */
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char j_digest[16];			/* md5 sum of all the blocks involved, including desc and commit. not used, kill it */
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* this header block gets written whenever a transaction is considered
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   fully flushed, and is more recent than the last fully flushed
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   transaction.
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   fully flushed means all the log blocks and all the real blocks are
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   on disk, and this transaction does not need to be replayed.
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct reiserfs_journal_header {
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* id of last fully flushed transaction */
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_last_flush_trans_id;
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* offset in the log of where to start replay after a crash */
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_first_unflushed_offset;
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* mount id to detect very old transactions */
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 j_mount_id;
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* magic string to find desc blocks in the journal */
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define JOURNAL_DESC_MAGIC "ReIsErLB"
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * directories use this key as well as old files
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct offset_v1
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /*
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * for regular files this is the offset to the first byte of the
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * body, contained in the object-item, as measured from the start of
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * the entire body of the object.
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * for directory entries, k_offset consists of hash derived from
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * hashing the name and using few bits (23 or more) of the resulting
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * hash, and generation number that allows distinguishing names with
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * hash collisions. If number of collisions overflows generation
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * number, we return EEXIST.  High order bit is 0 always
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   */
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 k_offset;
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 k_uniqueness;
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct offset_v2
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /*
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * for regular files this is the offset to the first byte of the
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * body, contained in the object-item, as measured from the start of
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * the entire body of the object.
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * for directory entries, k_offset consists of hash derived from
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * hashing the name and using few bits (23 or more) of the resulting
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * hash, and generation number that allows distinguishing names with
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * hash collisions. If number of collisions overflows generation
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * number, we return EEXIST.  High order bit is 0 always
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   */
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u64 k_offset:60;
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u64 k_type: 4;
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct key
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* packing locality: by default parent directory object id */
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 k_dir_id;
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* object identifier */
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 k_objectid;
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* the offset and node type (old and new form) */
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  union
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    struct offset_v1 v1;
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    struct offset_v2 v2;
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  u;
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define KEY_SIZE (sizeof (struct key))
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Header of a disk block.  More precisely, header of a formatted leaf
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   or internal node, and not the header of an unformatted node. */
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct block_head
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 blk_level;        /* Level of a block in the tree. */
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 blk_nr_item;      /* Number of keys/items in a block. */
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 blk_free_space;   /* Block free space in bytes. */
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct key  blk_right_delim_key; /* Right delimiting key for this block (supported for leaf level nodes
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				      only) */
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define BLKH_SIZE (sizeof (struct block_head))
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DISK_LEAF_NODE_LEVEL  1 /* Leaf node level.                       */
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct item_head
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct key ih_key; 	/* Everything in the tree is found by searching for it based on its key.*/
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  union
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    __u16 ih_free_space; /* The free space in the last unformatted node of an indirect item if this
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    is an indirect item.  This equals 0xFFFF iff this is a direct item or
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    stat data item. Note that the key, not this field, is used to determine
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    the item type, and thus which field this union contains. */
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    __u16 ih_entry_count; /* Iff this is a directory item, this field equals the number of directory
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			     entries in the directory item. */
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  u;
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 ih_item_len;           /* total size of the item body                  */
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 ih_item_location;      /* an offset to the item body within the block  */
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 ih_version;	       /* ITEM_VERSION_1 for all old items,
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				  ITEM_VERSION_2 for new ones.
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				  Highest bit is set by fsck
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                                  temporary, cleaned after all done */
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* size of item header     */
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define IH_SIZE (sizeof (struct item_head))
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ITEM_VERSION_1 0
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ITEM_VERSION_2 1
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define IH_KEY_OFFSET(ih) ((ih)->ih_version == ITEM_VERSION_1 \
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			   ? (ih)->ih_key.u.v1.k_offset \
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			   : (ih)->ih_key.u.v2.k_offset)
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define IH_KEY_ISTYPE(ih, type) ((ih)->ih_version == ITEM_VERSION_1 \
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				 ? (ih)->ih_key.u.v1.k_uniqueness == V1_##type \
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				 : (ih)->ih_key.u.v2.k_type == V2_##type)
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct disk_child
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long       dc_block_number;              /* Disk child's block number. */
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned short      dc_size;		            /* Disk child's used space.   */
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DC_SIZE (sizeof (struct disk_child))
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Stat Data on disk.
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Note that reiserfs has two different forms of stat data.  Luckily
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the fields needed by grub are at the same position.
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct stat_data
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 sd_mode;	/* file type, permissions */
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 sd_notused1[3]; /* fields not needed by reiserfs */
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 sd_size;	/* file size */
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 sd_size_hi;	/* file size high 32 bits (since version 2) */
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct reiserfs_de_head
2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 deh_offset;  /* third component of the directory entry key */
2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 deh_dir_id;  /* objectid of the parent directory of the
2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			object, that is referenced by directory entry */
2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 deh_objectid;/* objectid of the object, that is referenced by
2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                        directory entry */
2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 deh_location;/* offset of name in the whole item */
2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 deh_state;   /* whether 1) entry contains stat data (for
2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			future), and 2) whether entry is hidden
2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			(unlinked) */
2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DEH_SIZE (sizeof (struct reiserfs_de_head))
2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DEH_Statdata (1 << 0)			/* not used now */
2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DEH_Visible  (1 << 2)
2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define SD_OFFSET  0
2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define SD_UNIQUENESS 0
2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DOT_OFFSET 1
2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DOT_DOT_OFFSET 2
2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DIRENTRY_UNIQUENESS 500
2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define V1_TYPE_STAT_DATA 0x0
2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define V1_TYPE_DIRECT 0xffffffff
2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define V1_TYPE_INDIRECT 0xfffffffe
2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define V1_TYPE_DIRECTORY_MAX 0xfffffffd
2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define V2_TYPE_STAT_DATA 0
2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define V2_TYPE_INDIRECT 1
2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define V2_TYPE_DIRECT 2
2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define V2_TYPE_DIRENTRY 3
2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISERFS_ROOT_OBJECTID 2
2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISERFS_ROOT_PARENT_OBJECTID 1
2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */
2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define REISERFS_OLD_BLOCKSIZE 4096
2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define S_ISREG(mode) (((mode) & 0170000) == 0100000)
2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define S_ISDIR(mode) (((mode) & 0170000) == 0040000)
2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define S_ISLNK(mode) (((mode) & 0170000) == 0120000)
2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define PATH_MAX       1024	/* include/linux/limits.h */
2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define MAX_LINK_COUNT    5	/* number of symbolic links to follow */
2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The size of the node cache */
2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define FSYSREISER_CACHE_SIZE 24*1024
2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE
2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3
2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Info about currently opened file */
2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct fsys_reiser_fileinfo
3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 k_dir_id;
3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 k_objectid;
3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* In memory info about the currently mounted filesystem */
3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct fsys_reiser_info
3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The last read item head */
3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct item_head *current_ih;
3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The last read item */
3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *current_item;
3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The information for the currently opened file */
3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct fsys_reiser_fileinfo fileinfo;
3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The start of the journal */
3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 journal_block;
3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The size of the journal */
3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 journal_block_count;
3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The first valid descriptor block in journal
3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     (relative to journal_block) */
3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 journal_first_desc;
3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The ReiserFS version. */
3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 version;
3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The current depth of the reiser tree. */
3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 tree_depth;
3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* SECTOR_SIZE << blocksize_shift == blocksize. */
3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u8  blocksize_shift;
3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* 1 << full_blocksize_shift == blocksize. */
3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u8  fullblocksize_shift;
3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The reiserfs block size  (must be a power of 2) */
3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 blocksize;
3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The number of cached tree nodes */
3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 cached_slots;
3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The number of valid transactions in journal */
3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u16 journal_transactions;
3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int blocks[MAX_HEIGHT];
3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int next_key_nr[MAX_HEIGHT];
3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The cached s+tree blocks in FSYS_BUF,  see below
3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * for a more detailed description.
3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ROOT     ((char *) ((int) FSYS_BUF))
3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CACHE(i) (ROOT + ((i) << INFO->fullblocksize_shift))
3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LEAF     CACHE (DISK_LEAF_NODE_LEVEL)
3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define BLOCKHEAD(cache) ((struct block_head *) cache)
3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ITEMHEAD         ((struct item_head  *) ((int) LEAF + BLKH_SIZE))
3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define KEY(cache)       ((struct key        *) ((int) cache + BLKH_SIZE))
3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DC(cache)        ((struct disk_child *) \
3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))
3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The fsys_reiser_info block.
3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define INFO \
3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    ((struct fsys_reiser_info *) ((int) FSYS_BUF + FSYSREISER_CACHE_SIZE))
3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * The journal cache.  For each transaction it contains the number of
3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * blocks followed by the real block numbers of this transaction.
3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * If the block numbers of some transaction won't fit in this space,
3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * this list is stopped with a 0xffffffff marker and the remaining
3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * uncommitted transactions aren't cached.
3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define JOURNAL_START    ((__u32 *) (INFO + 1))
3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define JOURNAL_END      ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic __inline__ unsigned long
3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectlog2 (unsigned long word)
3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __asm__ ("bsfl %1,%0"
3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   : "=r" (word)
3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   : "r" (word));
3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return word;
3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic __inline__ int
3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectis_power_of_two (unsigned long word)
3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return (word & -word) == word;
3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectjournal_read (int block, int len, char *buffer)
3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return devread ((INFO->journal_block + block) << INFO->blocksize_shift,
3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  0, len, buffer);
3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Read a block from ReiserFS file system, taking the journal into
3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * account.  If the block nr is in the journal, the block from the
3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * journal taken.
3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectblock_read (int blockNr, int start, int len, char *buffer)
3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int transactions = INFO->journal_transactions;
3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int desc_block = INFO->journal_first_desc;
4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int journal_mask = INFO->journal_block_count - 1;
4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int translatedNr = blockNr;
4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 *journal_table = JOURNAL_START;
4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (transactions-- > 0)
4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int i = 0;
4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int j_len;
4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (*journal_table != 0xffffffff)
4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Search for the blockNr in cached journal */
4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  j_len = *journal_table++;
4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  while (i++ < j_len)
4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (*journal_table++ == blockNr)
4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  journal_table += j_len - i;
4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  goto found;
4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* This is the end of cached journal marker.  The remaining
4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   * transactions are still on disk.
4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   */
4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  struct reiserfs_journal_desc   desc;
4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  struct reiserfs_journal_commit commit;
4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! journal_read (desc_block, sizeof (desc), (char *) &desc))
4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 0;
4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  j_len = desc.j_len;
4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  while (i < j_len && i < JOURNAL_TRANS_HALF)
4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    if (desc.j_realblock[i++] == blockNr)
4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      goto found;
4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (j_len >= JOURNAL_TRANS_HALF)
4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      int commit_block = (desc_block + 1 + j_len) & journal_mask;
4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (! journal_read (commit_block,
4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				  sizeof (commit), (char *) &commit))
4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      while (i < j_len)
4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (commit.j_realblock[i++ - JOURNAL_TRANS_HALF] == blockNr)
4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  goto found;
4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      goto not_found;
4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    found:
4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      translatedNr = INFO->journal_block + ((desc_block + i) & journal_mask);
4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("block_read: block %d is mapped to journal block %d.\n",
4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      blockNr, translatedNr - INFO->journal_block);
4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* We must continue the search, as this block may be overwritten
4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       * in later transactions.
4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       */
4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    not_found:
4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      desc_block = (desc_block + 2 + j_len) & journal_mask;
4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return devread (translatedNr << INFO->blocksize_shift, start, len, buffer);
4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Init the journal data structure.  We try to cache as much as
4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * possible in the JOURNAL_START-JOURNAL_END space, but if it is full
4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * we can still read the rest from the disk on demand.
4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * The first number of valid transactions and the descriptor block of the
4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * first valid transaction are held in INFO.  The transactions are all
4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * adjacent, but we must take care of the journal wrap around.
4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectjournal_init (void)
4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int block_count = INFO->journal_block_count;
4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int desc_block;
4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int commit_block;
4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int next_trans_id;
4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct reiserfs_journal_header header;
4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct reiserfs_journal_desc   desc;
4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct reiserfs_journal_commit commit;
4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 *journal_table = JOURNAL_START;
4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  journal_read (block_count, sizeof (header), (char *) &header);
4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  desc_block = header.j_first_unflushed_offset;
4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (desc_block >= block_count)
4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->journal_first_desc = desc_block;
4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  next_trans_id = header.j_last_flush_trans_id + 1;
4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("journal_init: last flushed %d\n",
4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  header.j_last_flush_trans_id);
4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (1)
4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      journal_read (desc_block, sizeof (desc), (char *) &desc);
5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (substring (JOURNAL_DESC_MAGIC, desc.j_magic) > 0
5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || desc.j_trans_id != next_trans_id
5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || desc.j_mount_id != header.j_mount_id)
5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* no more valid transactions */
5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	break;
5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      commit_block = (desc_block + desc.j_len + 1) & (block_count - 1);
5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      journal_read (commit_block, sizeof (commit), (char *) &commit);
5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (desc.j_trans_id != commit.j_trans_id
5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || desc.j_len != commit.j_len)
5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* no more valid transactions */
5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	break;
5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("Found valid transaction %d/%d at %d.\n",
5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      desc.j_trans_id, desc.j_mount_id, desc_block);
5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      next_trans_id++;
5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (journal_table < JOURNAL_END)
5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if ((journal_table + 1 + desc.j_len) >= JOURNAL_END)
5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* The table is almost full; mark the end of the cached
5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       * journal.*/
5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *journal_table = 0xffffffff;
5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      journal_table = JOURNAL_END;
5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  else
5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      int i;
5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* Cache the length and the realblock numbers in the table.
5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       * The block number of descriptor can easily be computed.
5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       * and need not to be stored here.
5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       */
5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *journal_table++ = desc.j_len;
5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      for (i = 0; i < desc.j_len && i < JOURNAL_TRANS_HALF; i++)
5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *journal_table++ = desc.j_realblock[i];
5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  printf ("block %d is in journal %d.\n",
5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  desc.j_realblock[i], desc_block);
5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      for (     ; i < desc.j_len; i++)
5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *journal_table++ = commit.j_realblock[i-JOURNAL_TRANS_HALF];
5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  printf ("block %d is in journal %d.\n",
5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  commit.j_realblock[i-JOURNAL_TRANS_HALF],
5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  desc_block);
5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      desc_block = (commit_block + 1) & (block_count - 1);
5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("Transaction %d/%d at %d isn't valid.\n",
5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  desc.j_trans_id, desc.j_mount_id, desc_block);
5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->journal_transactions
5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    = next_trans_id - header.j_last_flush_trans_id - 1;
5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return errnum == 0;
5655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
5665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* check filesystem types and read superblock into memory buffer */
5685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
5695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectreiserfs_mount (void)
5705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
5715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct reiserfs_super_block super;
5725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
5735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
5755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || ! devread (superblock, 0, sizeof (struct reiserfs_super_block),
5765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		(char *) &super)
5775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0
5785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0
5795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0)
5805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || (/* check that this is not a copy inside the journal log */
5815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  super.s_journal_block * super.s_blocksize
5825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  <= REISERFS_DISK_OFFSET_IN_BYTES))
5835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
5845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Try old super block position */
5855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
5865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
5875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || ! devread (superblock, 0, sizeof (struct reiserfs_super_block),
5885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			(char *) &super))
5895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
5905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0
5925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0
5935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0)
5945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* pre journaling super block ? */
5965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (substring (REISERFS_SUPER_MAGIC_STRING,
5975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			 (char*) ((int) &super + 20)) > 0)
5985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 0;
5995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  super.s_blocksize = REISERFS_OLD_BLOCKSIZE;
6015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  super.s_journal_block = 0;
6025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  super.s_version = 0;
6035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
6055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* check the version number.  */
6075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (super.s_version > REISERFS_MAX_SUPPORTED_VERSION)
6085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
6095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->version = super.s_version;
6115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->blocksize = super.s_blocksize;
6125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->fullblocksize_shift = log2 (super.s_blocksize);
6135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->blocksize_shift = INFO->fullblocksize_shift - SECTOR_BITS;
6145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->cached_slots =
6155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    (FSYSREISER_CACHE_SIZE >> INFO->fullblocksize_shift) - 1;
6165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
6185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("reiserfs_mount: version=%d, blocksize=%d\n",
6195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->version, INFO->blocksize);
6205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
6215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Clear node cache. */
6235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  memset (INFO->blocks, 0, sizeof (INFO->blocks));
6245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (super.s_blocksize < FSYSREISER_MIN_BLOCKSIZE
6265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || super.s_blocksize > FSYSREISER_MAX_BLOCKSIZE
6275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || (SECTOR_SIZE << INFO->blocksize_shift) != super.s_blocksize)
6285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
6295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Initialize journal code.  If something fails we end with zero
6315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   * journal_transactions, so we don't access the journal at all.
6325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   */
6335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->journal_transactions = 0;
6345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (super.s_journal_block != 0 && super.s_journal_dev == 0)
6355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
6365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      INFO->journal_block = super.s_journal_block;
6375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      INFO->journal_block_count = super.s_journal_size;
6385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (is_power_of_two (INFO->journal_block_count))
6395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	journal_init ();
6405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Read in super block again, maybe it is in the journal */
6425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      block_read (superblock >> INFO->blocksize_shift,
6435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  0, sizeof (struct reiserfs_super_block), (char *) &super);
6445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
6455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! block_read (super.s_root_block, 0, INFO->blocksize, (char*) ROOT))
6475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
6485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->tree_depth = BLOCKHEAD (ROOT)->blk_level;
6505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
6525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("root read_in: block=%d, depth=%d\n",
6535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  super.s_root_block, INFO->tree_depth);
6545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
6555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (INFO->tree_depth >= MAX_HEIGHT)
6575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
6585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (INFO->tree_depth == DISK_LEAF_NODE_LEVEL)
6595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
6605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* There is only one node in the whole filesystem,
6615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       * which is simultanously leaf and root */
6625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      memcpy (LEAF, ROOT, INFO->blocksize);
6635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
6645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
6655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
6665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/***************** TREE ACCESSING METHODS *****************************/
6685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* I assume you are familiar with the ReiserFS tree, if not go to
6705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * http://www.namesys.com/content_table.html
6715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
6725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * My tree node cache is organized as following
6735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   0   ROOT node
6745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   1   LEAF node  (if the ROOT is also a LEAF it is copied here
6755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   2-n other nodes on current path from bottom to top.
6765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *       if there is not enough space in the cache, the top most are
6775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *       omitted.
6785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
6795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * I have only two methods to find a key in the tree:
6805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   search_stat(dir_id, objectid) searches for the stat entry (always
6815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *       the first entry) of an object.
6825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   next_key() gets the next key in tree order.
6835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
6845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * This means, that I can only sequential reads of files are
6855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * efficient, but this really doesn't hurt for grub.
6865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
6875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Read in the node at the current path and depth into the node cache.
6895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * You must set INFO->blocks[depth] before.
6905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
6915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic char *
6925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectread_tree_node (unsigned int blockNr, int depth)
6935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
6945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char* cache = CACHE(depth);
6955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int num_cached = INFO->cached_slots;
6965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (depth < num_cached)
6975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
6985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* This is the cached part of the path.  Check if same block is
6995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       * needed.
7005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       */
7015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (blockNr == INFO->blocks[depth])
7025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return cache;
7035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
7045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
7055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    cache = CACHE(num_cached);
7065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
7085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("  next read_in: block=%d (depth=%d)\n",
7095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  blockNr, depth);
7105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
7115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! block_read (blockNr, 0, INFO->blocksize, cache))
7125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
7135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Make sure it has the right node level */
7145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (BLOCKHEAD (cache)->blk_level != depth)
7155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
7165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_FSYS_CORRUPT;
7175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
7185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
7195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->blocks[depth] = blockNr;
7215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return cache;
7225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
7235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Get the next key, i.e. the key following the last retrieved key in
7255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * tree order.  INFO->current_ih and
7265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * INFO->current_info are adapted accordingly.  */
7275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
7285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectnext_key (void)
7295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
7305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int depth;
7315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct item_head *ih = INFO->current_ih + 1;
7325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *cache;
7335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
7355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("next_key:\n  old ih: key %d:%d:%d:%d version:%d\n",
7365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_key.k_dir_id,
7375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_key.k_objectid,
7385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_key.u.v1.k_offset,
7395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_key.u.v1.k_uniqueness,
7405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_version);
7415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
7425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (ih == &ITEMHEAD[BLOCKHEAD (LEAF)->blk_nr_item])
7445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
7455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      depth = DISK_LEAF_NODE_LEVEL;
7465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* The last item, was the last in the leaf node.
7475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       * Read in the next block
7485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       */
7495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      do
7505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
7515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (depth == INFO->tree_depth)
7525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
7535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* There are no more keys at all.
7545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       * Return a dummy item with MAX_KEY */
7555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      ih = (struct item_head *) &BLOCKHEAD (LEAF)->blk_right_delim_key;
7565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      goto found;
7575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
7585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  depth++;
7595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
7605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf ("  depth=%d, i=%d\n", depth, INFO->next_key_nr[depth]);
7615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
7625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
7635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      while (INFO->next_key_nr[depth] == 0);
7645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (depth == INFO->tree_depth)
7665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	cache = ROOT;
7675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else if (depth <= INFO->cached_slots)
7685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	cache = CACHE (depth);
7695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
7705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
7715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  cache = read_tree_node (INFO->blocks[depth], depth);
7725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! cache)
7735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 0;
7745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
7755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      do
7775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
7785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int nr_item = BLOCKHEAD (cache)->blk_nr_item;
7795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int key_nr = INFO->next_key_nr[depth]++;
7805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
7815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf ("  depth=%d, i=%d/%d\n", depth, key_nr, nr_item);
7825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
7835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (key_nr == nr_item)
7845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    /* This is the last item in this block, set the next_key_nr to 0 */
7855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    INFO->next_key_nr[depth] = 0;
7865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  cache = read_tree_node (DC (cache)[key_nr].dc_block_number, --depth);
7885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! cache)
7895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 0;
7905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
7915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      while (depth > DISK_LEAF_NODE_LEVEL);
7925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      ih = ITEMHEAD;
7945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
7955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project found:
7965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->current_ih   = ih;
7975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  INFO->current_item = &LEAF[ih->ih_item_location];
7985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
7995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("  new ih: key %d:%d:%d:%d version:%d\n",
8005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_key.k_dir_id,
8015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_key.k_objectid,
8025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_key.u.v1.k_offset,
8035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_key.u.v1.k_uniqueness,
8045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih->ih_version);
8055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
8065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
8075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
8085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* preconditions: reiserfs_mount already executed, therefore
8105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   INFO block is valid
8115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * returns: 0 if error (errnum is set),
8125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   nonzero iff we were able to find the key successfully.
8135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * postconditions: on a nonzero return, the current_ih and
8145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   current_item fields describe the key that equals the
8155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   searched key.  INFO->next_key contains the next key after
8165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   the searched key.
8175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * side effects: messes around with the cache.
8185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
8195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
8205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsearch_stat (__u32 dir_id, __u32 objectid)
8215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
8225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *cache;
8235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int depth;
8245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int nr_item;
8255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int i;
8265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct item_head *ih;
8275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
8285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("search_stat:\n  key %d:%d:0:0\n", dir_id, objectid);
8295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
8305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  depth = INFO->tree_depth;
8325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  cache = ROOT;
8335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (depth > DISK_LEAF_NODE_LEVEL)
8355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
8365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      struct key *key;
8375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      nr_item = BLOCKHEAD (cache)->blk_nr_item;
8385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      key = KEY (cache);
8405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      for (i = 0; i < nr_item; i++)
8425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
8435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (key->k_dir_id > dir_id
8445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || (key->k_dir_id == dir_id
8455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  && (key->k_objectid > objectid
8465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      || (key->k_objectid == objectid
8475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  && (key->u.v1.k_offset
8485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			      | key->u.v1.k_uniqueness) > 0))))
8495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    break;
8505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  key++;
8515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
8525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
8545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("  depth=%d, i=%d/%d\n", depth, i, nr_item);
8555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
8565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      INFO->next_key_nr[depth] = (i == nr_item) ? 0 : i+1;
8575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      cache = read_tree_node (DC (cache)[i].dc_block_number, --depth);
8585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! cache)
8595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
8605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
8615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* cache == LEAF */
8635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  nr_item = BLOCKHEAD (LEAF)->blk_nr_item;
8645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  ih = ITEMHEAD;
8655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i = 0; i < nr_item; i++)
8665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
8675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (ih->ih_key.k_dir_id == dir_id
8685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && ih->ih_key.k_objectid == objectid
8695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && ih->ih_key.u.v1.k_offset == 0
8705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && ih->ih_key.u.v1.k_uniqueness == 0)
8715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
8725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
8735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf ("  depth=%d, i=%d/%d\n", depth, i, nr_item);
8745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
8755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_ih   = ih;
8765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->current_item = &LEAF[ih->ih_item_location];
8775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 1;
8785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
8795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      ih++;
8805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
8815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  errnum = ERR_FSYS_CORRUPT;
8825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 0;
8835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
8845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
8865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectreiserfs_read (char *buf, int len)
8875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
8885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int blocksize;
8895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int offset;
8905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int to_read;
8915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *prev_buf = buf;
8925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
8945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf ("reiserfs_read: filepos=%d len=%d, offset=%x:%x\n",
8955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1);
8965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
8975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
8995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || IH_KEY_OFFSET (INFO->current_ih) > filepos + 1)
9005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
9015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid);
9025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      goto get_next_key;
9035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
9045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (! errnum)
9065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
9075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid)
9085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	break;
9095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1;
9115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      blocksize = INFO->current_ih->ih_item_len;
9125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
9145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("  loop: filepos=%d len=%d, offset=%d blocksize=%d\n",
9155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      filepos, len, offset, blocksize);
9165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
9175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_DIRECT)
9195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && offset < blocksize)
9205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
9215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
9225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf ("direct_read: offset=%d, blocksize=%d\n",
9235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  offset, blocksize);
9245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
9255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  to_read = blocksize - offset;
9265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (to_read > len)
9275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    to_read = len;
9285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (disk_read_hook != NULL)
9305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
9315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      disk_read_func = disk_read_hook;
9325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      block_read (INFO->blocks[DISK_LEAF_NODE_LEVEL],
9345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  (INFO->current_item - LEAF + offset), to_read, buf);
9355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      disk_read_func = NULL;
9375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
9385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  else
9395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    memcpy (buf, INFO->current_item + offset, to_read);
9405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  goto update_buf_len;
9415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
9425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_INDIRECT))
9435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
9445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  blocksize = (blocksize >> 2) << INFO->fullblocksize_shift;
9455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
9465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf ("indirect_read: offset=%d, blocksize=%d\n",
9475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  offset, blocksize);
9485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
9495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  while (offset < blocksize)
9515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
9525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      __u32 blocknr = ((__u32 *) INFO->current_item)
9535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		[offset >> INFO->fullblocksize_shift];
9545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      int blk_offset = offset & (INFO->blocksize-1);
9555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      to_read = INFO->blocksize - blk_offset;
9575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (to_read > len)
9585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		to_read = len;
9595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      disk_read_func = disk_read_hook;
9615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* Journal is only for meta data.  Data blocks can be read
9635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       * directly without using block_read
9645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       */
9655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      devread (blocknr << INFO->blocksize_shift,
9665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		       blk_offset, to_read, buf);
9675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      disk_read_func = NULL;
9695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    update_buf_len:
9705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      len -= to_read;
9715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      buf += to_read;
9725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      offset += to_read;
9735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      filepos += to_read;
9745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (len == 0)
9755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		goto done;
9765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
9775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
9785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    get_next_key:
9795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      next_key ();
9805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
9815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project done:
9825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return errnum ? 0 : buf - prev_buf;
9835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
9845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* preconditions: reiserfs_mount already executed, therefore
9875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   INFO block is valid
9885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * returns: 0 if error, nonzero iff we were able to find the file successfully
9895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * postconditions: on a nonzero return, INFO->fileinfo contains the info
9905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   of the file we were trying to look up, filepos is 0 and filemax is
9915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *   the size of the file.
9925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
9935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
9945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectreiserfs_dir (char *dirname)
9955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
9965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct reiserfs_de_head *de_head;
9975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *rest, ch;
9985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
9995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
10005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int do_possibilities = 0;
10015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
10025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
10035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int link_count = 0;
10045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int mode;
10055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  dir_id = REISERFS_ROOT_PARENT_OBJECTID;
10075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  objectid = REISERFS_ROOT_OBJECTID;
10085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (1)
10105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
10115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
10125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("dirname=%s\n", dirname);
10135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
10145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Search for the stat info first. */
10165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! search_stat (dir_id, objectid))
10175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
10185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
10205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("sd_mode=%x sd_size=%d\n",
10215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      ((struct stat_data *) INFO->current_item)->sd_mode,
10225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      ((struct stat_data *) INFO->current_item)->sd_size);
10235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
10245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      mode = ((struct stat_data *) INFO->current_item)->sd_mode;
10265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If we've got a symbolic link, then chase it. */
10285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (S_ISLNK (mode))
10295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
10305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int len;
10315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (++link_count > MAX_LINK_COUNT)
10325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      errnum = ERR_SYMLINK_LOOP;
10345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
10355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Get the symlink size. */
10385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  filemax = ((struct stat_data *) INFO->current_item)->sd_size;
10395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Find out how long our remaining name is. */
10415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  len = 0;
10425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  while (dirname[len] && !isspace (dirname[len]))
10435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    len++;
10445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (filemax + len > sizeof (linkbuf) - 1)
10465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      errnum = ERR_FILELENGTH;
10485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
10495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Copy the remaining name to the end of the symlink data.
10525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	     Note that DIRNAME and LINKBUF may overlap! */
10535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  grub_memmove (linkbuf + filemax, dirname, len+1);
10545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->fileinfo.k_dir_id = dir_id;
10565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->fileinfo.k_objectid = objectid;
10575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  	  filepos = 0;
10585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! next_key ()
10595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || reiserfs_read (linkbuf, filemax) != filemax)
10605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (! errnum)
10625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		errnum = ERR_FSYS_CORRUPT;
10635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
10645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
10675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf ("symlink=%s\n", linkbuf);
10685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
10695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  dirname = linkbuf;
10715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (*dirname == '/')
10725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* It's an absolute link, so look it up in root. */
10745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      dir_id = REISERFS_ROOT_PARENT_OBJECTID;
10755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      objectid = REISERFS_ROOT_OBJECTID;
10765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  else
10785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* Relative, so look it up in our parent directory. */
10805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      dir_id   = parent_dir_id;
10815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      objectid = parent_objectid;
10825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Now lookup the new name. */
10855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  continue;
10865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
10875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* if we have a real file (and we're not just printing possibilities),
10895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 then this is where we want to exit */
10905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! *dirname || isspace (*dirname))
10925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
10935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! S_ISREG (mode))
10945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      errnum = ERR_BAD_FILETYPE;
10965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
10975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  filepos = 0;
11005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  filemax = ((struct stat_data *) INFO->current_item)->sd_size;
11015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* If this is a new stat data and size is > 4GB set filemax to
11035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   * maximum
11045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   */
11055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (INFO->current_ih->ih_version == ITEM_VERSION_2
11065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      && ((struct stat_data *) INFO->current_item)->sd_size_hi > 0)
11075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    filemax = 0xffffffff;
11085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->fileinfo.k_dir_id = dir_id;
11105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  INFO->fileinfo.k_objectid = objectid;
11115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return next_key ();
11125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
11135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* continue with the file/directory name interpretation */
11155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      while (*dirname == '/')
11165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	dirname++;
11175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! S_ISDIR (mode))
11185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
11195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_BAD_FILETYPE;
11205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
11215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
11225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      for (rest = dirname; (ch = *rest) && ! isspace (ch) && ch != '/'; rest++);
11235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *rest = 0;
11245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifndef STAGE1_5
11265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (print_possibilities && ch != '/')
11275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	do_possibilities = 1;
11285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif /* ! STAGE1_5 */
11295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      while (1)
11315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
11325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  char *name_end;
11335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int num_entries;
11345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! next_key ())
11365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 0;
11375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef REISERDEBUG
11385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf ("ih: key %d:%d:%d:%d version:%d\n",
11395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  INFO->current_ih->ih_key.k_dir_id,
11405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  INFO->current_ih->ih_key.k_objectid,
11415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  INFO->current_ih->ih_key.u.v1.k_offset,
11425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  INFO->current_ih->ih_key.u.v1.k_uniqueness,
11435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  INFO->current_ih->ih_version);
11445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* REISERDEBUG */
11455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (INFO->current_ih->ih_key.k_objectid != objectid)
11475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    break;
11485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  name_end = INFO->current_item + INFO->current_ih->ih_item_len;
11505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  de_head = (struct reiserfs_de_head *) INFO->current_item;
11515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  num_entries = INFO->current_ih->u.ih_entry_count;
11525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  while (num_entries > 0)
11535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
11545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      char *filename = INFO->current_item + de_head->deh_location;
11555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      char  tmp = *name_end;
11565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if ((de_head->deh_state & DEH_Visible))
11575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
11585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  int cmp;
11595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  /* Directory names in ReiserFS are not null
11605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   * terminated.  We write a temporary 0 behind it.
11615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   * NOTE: that this may overwrite the first block in
11625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   * the tree cache.  That doesn't hurt as long as we
11635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   * don't call next_key () in between.
11645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   */
11655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *name_end = 0;
11665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  cmp = substring (dirname, filename);
11675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *name_end = tmp;
11685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifndef STAGE1_5
11695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (do_possibilities)
11705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
11715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      if (cmp <= 0)
11725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			{
11735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  if (print_possibilities > 0)
11745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    print_possibilities = -print_possibilities;
11755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  *name_end = 0;
11765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  print_a_completion (filename);
11775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  *name_end = tmp;
11785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			}
11795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
11805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  else
11815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif /* ! STAGE1_5 */
11825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    if (cmp == 0)
11835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      goto found;
11845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
11855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* The beginning of this name marks the end of the next name.
11865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       */
11875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      name_end = filename;
11885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      de_head++;
11895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      num_entries--;
11905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
11915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
11925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifndef STAGE1_5
11945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (print_possibilities < 0)
11955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 1;
11965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif /* ! STAGE1_5 */
11975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_FILE_NOT_FOUND;
11995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *rest = ch;
12005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
12015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    found:
12035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *rest = ch;
12055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      dirname = rest;
12065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      parent_dir_id = dir_id;
12085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      parent_objectid = objectid;
12095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      dir_id = de_head->deh_dir_id;
12105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      objectid = de_head->deh_objectid;
12115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
12125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
12135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
12155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectreiserfs_embed (int *start_sector, int needed_sectors)
12165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
12175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct reiserfs_super_block super;
12185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int num_sectors;
12195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! devread (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS, 0,
12215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 sizeof (struct reiserfs_super_block), (char *) &super))
12225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
12235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  *start_sector = 1; /* reserve first sector for stage1 */
12255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) <= 0
12265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       || substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) <= 0
12275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       || substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) <= 0)
12285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      && (/* check that this is not a super block copy inside
12295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   * the journal log */
12305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  super.s_journal_block * super.s_blocksize
12315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  > REISERFS_DISK_OFFSET_IN_BYTES))
12325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    num_sectors = (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1;
12335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
12345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    num_sectors = (REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1;
12355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return (needed_sectors <= num_sectors);
12375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
12385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* FSYS_REISERFS */
1239