2 * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
4 * GRUB -- GRand Unified Bootloader
5 * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
7 * (C) Copyright 2003 - 2004
8 * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* An implementation for the ReiserFS filesystem ported from GRUB.
27 * Some parts of this code (mainly the structures and defines) are
28 * from the original reiser fs code, as found in the linux kernel.
32 #if (CONFIG_COMMANDS & CFG_CMD_REISER)
35 #include <linux/ctype.h>
36 #include <linux/time.h>
37 #include <asm/byteorder.h>
40 #include "reiserfs_private.h"
44 /* Some parts of this code (mainly the structures and defines) are
45 * from the original reiser fs code, as found in the linux kernel.
48 static char fsys_buf
[FSYS_BUFLEN
];
49 static reiserfs_error_t errnum
= ERR_NONE
;
50 static int print_possibilities
;
51 static unsigned int filepos
, filemax
;
54 substring (const char *s1
, const char *s2
)
58 /* The strings match exactly. */
64 /* S1 is a substring of S2. */
68 /* S1 isn't a substring. */
72 static void sd_print_item (struct item_head
* ih
, char * item
)
77 if (stat_data_v1 (ih
)) {
78 struct stat_data_v1
* sd
= (struct stat_data_v1
*)item
;
79 ttime
= sd_v1_mtime(sd
);
80 ctime_r(&ttime
, filetime
);
81 printf ("%-10s %4hd %6d %6d %9d %24.24s",
82 bb_mode_string(sd_v1_mode(sd
)), sd_v1_nlink(sd
),sd_v1_uid(sd
), sd_v1_gid(sd
),
83 sd_v1_size(sd
), filetime
);
85 struct stat_data
* sd
= (struct stat_data
*)item
;
86 ttime
= sd_v2_mtime(sd
);
87 ctime_r(&ttime
, filetime
);
88 printf ("%-10s %4d %6d %6d %9d %24.24s",
89 bb_mode_string(sd_v2_mode(sd
)), sd_v2_nlink(sd
),sd_v2_uid(sd
),sd_v2_gid(sd
),
90 (__u32
) sd_v2_size(sd
), filetime
);
95 journal_read (int block
, int len
, char *buffer
)
97 return reiserfs_devread ((INFO
->journal_block
+ block
) << INFO
->blocksize_shift
,
101 /* Read a block from ReiserFS file system, taking the journal into
102 * account. If the block nr is in the journal, the block from the
106 block_read (unsigned int blockNr
, int start
, int len
, char *buffer
)
108 int transactions
= INFO
->journal_transactions
;
109 int desc_block
= INFO
->journal_first_desc
;
110 int journal_mask
= INFO
->journal_block_count
- 1;
111 int translatedNr
= blockNr
;
112 __u32
*journal_table
= JOURNAL_START
;
113 while (transactions
-- > 0)
117 if (__le32_to_cpu(*journal_table
) != 0xffffffff)
119 /* Search for the blockNr in cached journal */
120 j_len
= __le32_to_cpu(*journal_table
++);
123 if (__le32_to_cpu(*journal_table
++) == blockNr
)
125 journal_table
+= j_len
- i
;
132 /* This is the end of cached journal marker. The remaining
133 * transactions are still on disk.
135 struct reiserfs_journal_desc desc
;
136 struct reiserfs_journal_commit commit
;
138 if (! journal_read (desc_block
, sizeof (desc
), (char *) &desc
))
141 j_len
= __le32_to_cpu(desc
.j_len
);
142 while (i
< j_len
&& i
< JOURNAL_TRANS_HALF
)
143 if (__le32_to_cpu(desc
.j_realblock
[i
++]) == blockNr
)
146 if (j_len
>= JOURNAL_TRANS_HALF
)
148 int commit_block
= (desc_block
+ 1 + j_len
) & journal_mask
;
149 if (! journal_read (commit_block
,
150 sizeof (commit
), (char *) &commit
))
153 if (__le32_to_cpu(commit
.j_realblock
[i
++ - JOURNAL_TRANS_HALF
]) == blockNr
)
160 translatedNr
= INFO
->journal_block
+ ((desc_block
+ i
) & journal_mask
);
162 printf ("block_read: block %d is mapped to journal block %d.\n",
163 blockNr
, translatedNr
- INFO
->journal_block
);
165 /* We must continue the search, as this block may be overwritten
166 * in later transactions.
169 desc_block
= (desc_block
+ 2 + j_len
) & journal_mask
;
171 return reiserfs_devread (translatedNr
<< INFO
->blocksize_shift
, start
, len
, buffer
);
174 /* Init the journal data structure. We try to cache as much as
175 * possible in the JOURNAL_START-JOURNAL_END space, but if it is full
176 * we can still read the rest from the disk on demand.
178 * The first number of valid transactions and the descriptor block of the
179 * first valid transaction are held in INFO. The transactions are all
180 * adjacent, but we must take care of the journal wrap around.
185 unsigned int block_count
= INFO
->journal_block_count
;
186 unsigned int desc_block
;
187 unsigned int commit_block
;
188 unsigned int next_trans_id
;
189 struct reiserfs_journal_header header
;
190 struct reiserfs_journal_desc desc
;
191 struct reiserfs_journal_commit commit
;
192 __u32
*journal_table
= JOURNAL_START
;
194 journal_read (block_count
, sizeof (header
), (char *) &header
);
195 desc_block
= __le32_to_cpu(header
.j_first_unflushed_offset
);
196 if (desc_block
>= block_count
)
199 INFO
->journal_first_desc
= desc_block
;
200 next_trans_id
= __le32_to_cpu(header
.j_last_flush_trans_id
) + 1;
203 printf ("journal_init: last flushed %d\n",
204 __le32_to_cpu(header
.j_last_flush_trans_id
));
209 journal_read (desc_block
, sizeof (desc
), (char *) &desc
);
210 if (substring (JOURNAL_DESC_MAGIC
, desc
.j_magic
) > 0
211 || __le32_to_cpu(desc
.j_trans_id
) != next_trans_id
212 || __le32_to_cpu(desc
.j_mount_id
) != __le32_to_cpu(header
.j_mount_id
))
213 /* no more valid transactions */
216 commit_block
= (desc_block
+ __le32_to_cpu(desc
.j_len
) + 1) & (block_count
- 1);
217 journal_read (commit_block
, sizeof (commit
), (char *) &commit
);
218 if (__le32_to_cpu(desc
.j_trans_id
) != commit
.j_trans_id
219 || __le32_to_cpu(desc
.j_len
) != __le32_to_cpu(commit
.j_len
))
220 /* no more valid transactions */
224 printf ("Found valid transaction %d/%d at %d.\n",
225 __le32_to_cpu(desc
.j_trans_id
), __le32_to_cpu(desc
.j_mount_id
), desc_block
);
229 if (journal_table
< JOURNAL_END
)
231 if ((journal_table
+ 1 + __le32_to_cpu(desc
.j_len
)) >= JOURNAL_END
)
233 /* The table is almost full; mark the end of the cached
235 *journal_table
= __cpu_to_le32(0xffffffff);
236 journal_table
= JOURNAL_END
;
241 /* Cache the length and the realblock numbers in the table.
242 * The block number of descriptor can easily be computed.
243 * and need not to be stored here.
246 /* both are in the little endian format */
247 *journal_table
++ = desc
.j_len
;
248 for (i
= 0; i
< __le32_to_cpu(desc
.j_len
) && i
< JOURNAL_TRANS_HALF
; i
++)
250 /* both are in the little endian format */
251 *journal_table
++ = desc
.j_realblock
[i
];
253 printf ("block %d is in journal %d.\n",
254 __le32_to_cpu(desc
.j_realblock
[i
]), desc_block
);
257 for ( ; i
< __le32_to_cpu(desc
.j_len
); i
++)
259 /* both are in the little endian format */
260 *journal_table
++ = commit
.j_realblock
[i
-JOURNAL_TRANS_HALF
];
262 printf ("block %d is in journal %d.\n",
263 __le32_to_cpu(commit
.j_realblock
[i
-JOURNAL_TRANS_HALF
]),
269 desc_block
= (commit_block
+ 1) & (block_count
- 1);
272 printf ("Transaction %d/%d at %d isn't valid.\n",
273 __le32_to_cpu(desc
.j_trans_id
), __le32_to_cpu(desc
.j_mount_id
), desc_block
);
276 INFO
->journal_transactions
277 = next_trans_id
- __le32_to_cpu(header
.j_last_flush_trans_id
) - 1;
281 /* check filesystem types and read superblock into memory buffer */
283 reiserfs_mount (unsigned part_length
)
285 struct reiserfs_super_block super
;
286 int superblock
= REISERFS_DISK_OFFSET_IN_BYTES
>> SECTOR_BITS
;
288 if (part_length
< superblock
+ (sizeof (super
) >> SECTOR_BITS
)
289 || ! reiserfs_devread (superblock
, 0, sizeof (struct reiserfs_super_block
),
291 || (substring (REISER3FS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0
292 && substring (REISER2FS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0
293 && substring (REISERFS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0)
294 || (/* check that this is not a copy inside the journal log */
295 sb_journal_block(&super
) * sb_blocksize(&super
)
296 <= REISERFS_DISK_OFFSET_IN_BYTES
))
298 /* Try old super block position */
299 superblock
= REISERFS_OLD_DISK_OFFSET_IN_BYTES
>> SECTOR_BITS
;
300 if (part_length
< superblock
+ (sizeof (super
) >> SECTOR_BITS
)
301 || ! reiserfs_devread (superblock
, 0, sizeof (struct reiserfs_super_block
),
305 if (substring (REISER2FS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0
306 && substring (REISERFS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0)
308 /* pre journaling super block ? */
309 if (substring (REISERFS_SUPER_MAGIC_STRING
,
310 (char*) ((int) &super
+ 20)) > 0)
313 set_sb_blocksize(&super
, REISERFS_OLD_BLOCKSIZE
);
314 set_sb_journal_block(&super
, 0);
315 set_sb_version(&super
, 0);
319 /* check the version number. */
320 if (sb_version(&super
) > REISERFS_MAX_SUPPORTED_VERSION
)
323 INFO
->version
= sb_version(&super
);
324 INFO
->blocksize
= sb_blocksize(&super
);
325 INFO
->fullblocksize_shift
= log2 (sb_blocksize(&super
));
326 INFO
->blocksize_shift
= INFO
->fullblocksize_shift
- SECTOR_BITS
;
328 (FSYSREISER_CACHE_SIZE
>> INFO
->fullblocksize_shift
) - 1;
331 printf ("reiserfs_mount: version=%d, blocksize=%d\n",
332 INFO
->version
, INFO
->blocksize
);
333 #endif /* REISERDEBUG */
335 /* Clear node cache. */
336 memset (INFO
->blocks
, 0, sizeof (INFO
->blocks
));
338 if (sb_blocksize(&super
) < FSYSREISER_MIN_BLOCKSIZE
339 || sb_blocksize(&super
) > FSYSREISER_MAX_BLOCKSIZE
340 || (SECTOR_SIZE
<< INFO
->blocksize_shift
) != sb_blocksize(&super
))
343 /* Initialize journal code. If something fails we end with zero
344 * journal_transactions, so we don't access the journal at all.
346 INFO
->journal_transactions
= 0;
347 if (sb_journal_block(&super
) != 0 && super
.s_journal_dev
== 0)
349 INFO
->journal_block
= sb_journal_block(&super
);
350 INFO
->journal_block_count
= sb_journal_size(&super
);
351 if (is_power_of_two (INFO
->journal_block_count
))
354 /* Read in super block again, maybe it is in the journal */
355 block_read (superblock
>> INFO
->blocksize_shift
,
356 0, sizeof (struct reiserfs_super_block
), (char *) &super
);
359 if (! block_read (sb_root_block(&super
), 0, INFO
->blocksize
, (char*) ROOT
))
362 INFO
->tree_depth
= __le16_to_cpu(BLOCKHEAD (ROOT
)->blk_level
);
365 printf ("root read_in: block=%d, depth=%d\n",
366 sb_root_block(&super
), INFO
->tree_depth
);
367 #endif /* REISERDEBUG */
369 if (INFO
->tree_depth
>= MAX_HEIGHT
)
371 if (INFO
->tree_depth
== DISK_LEAF_NODE_LEVEL
)
373 /* There is only one node in the whole filesystem,
374 * which is simultanously leaf and root */
375 memcpy (LEAF
, ROOT
, INFO
->blocksize
);
380 /***************** TREE ACCESSING METHODS *****************************/
382 /* I assume you are familiar with the ReiserFS tree, if not go to
383 * http://www.namesys.com/content_table.html
385 * My tree node cache is organized as following
387 * 1 LEAF node (if the ROOT is also a LEAF it is copied here
388 * 2-n other nodes on current path from bottom to top.
389 * if there is not enough space in the cache, the top most are
392 * I have only two methods to find a key in the tree:
393 * search_stat(dir_id, objectid) searches for the stat entry (always
394 * the first entry) of an object.
395 * next_key() gets the next key in tree order.
397 * This means, that I can only sequential reads of files are
398 * efficient, but this really doesn't hurt for grub.
401 /* Read in the node at the current path and depth into the node cache.
402 * You must set INFO->blocks[depth] before.
405 read_tree_node (unsigned int blockNr
, int depth
)
407 char* cache
= CACHE(depth
);
408 int num_cached
= INFO
->cached_slots
;
409 if (depth
< num_cached
)
411 /* This is the cached part of the path. Check if same block is
414 if (blockNr
== INFO
->blocks
[depth
])
418 cache
= CACHE(num_cached
);
421 printf (" next read_in: block=%d (depth=%d)\n",
423 #endif /* REISERDEBUG */
424 if (! block_read (blockNr
, 0, INFO
->blocksize
, cache
))
426 /* Make sure it has the right node level */
427 if (__le16_to_cpu(BLOCKHEAD (cache
)->blk_level
) != depth
)
429 errnum
= ERR_FSYS_CORRUPT
;
433 INFO
->blocks
[depth
] = blockNr
;
437 /* Get the next key, i.e. the key following the last retrieved key in
438 * tree order. INFO->current_ih and
439 * INFO->current_info are adapted accordingly. */
444 struct item_head
*ih
= INFO
->current_ih
+ 1;
448 printf ("next_key:\n old ih: key %d:%d:%d:%d version:%d\n",
449 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_dir_id
),
450 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
),
451 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_offset
),
452 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_uniqueness
),
453 __le16_to_cpu(INFO
->current_ih
->ih_version
));
454 #endif /* REISERDEBUG */
456 if (ih
== &ITEMHEAD
[__le16_to_cpu(BLOCKHEAD (LEAF
)->blk_nr_item
)])
458 depth
= DISK_LEAF_NODE_LEVEL
;
459 /* The last item, was the last in the leaf node.
460 * Read in the next block
464 if (depth
== INFO
->tree_depth
)
466 /* There are no more keys at all.
467 * Return a dummy item with MAX_KEY */
468 ih
= (struct item_head
*) &BLOCKHEAD (LEAF
)->blk_right_delim_key
;
473 printf (" depth=%d, i=%d\n", depth
, INFO
->next_key_nr
[depth
]);
474 #endif /* REISERDEBUG */
476 while (INFO
->next_key_nr
[depth
] == 0);
478 if (depth
== INFO
->tree_depth
)
480 else if (depth
<= INFO
->cached_slots
)
481 cache
= CACHE (depth
);
484 cache
= read_tree_node (INFO
->blocks
[depth
], depth
);
491 int nr_item
= __le16_to_cpu(BLOCKHEAD (cache
)->blk_nr_item
);
492 int key_nr
= INFO
->next_key_nr
[depth
]++;
494 printf (" depth=%d, i=%d/%d\n", depth
, key_nr
, nr_item
);
495 #endif /* REISERDEBUG */
496 if (key_nr
== nr_item
)
497 /* This is the last item in this block, set the next_key_nr to 0 */
498 INFO
->next_key_nr
[depth
] = 0;
500 cache
= read_tree_node (dc_block_number(&(DC (cache
)[key_nr
])), --depth
);
504 while (depth
> DISK_LEAF_NODE_LEVEL
);
509 INFO
->current_ih
= ih
;
510 INFO
->current_item
= &LEAF
[__le16_to_cpu(ih
->ih_item_location
)];
512 printf (" new ih: key %d:%d:%d:%d version:%d\n",
513 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_dir_id
),
514 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
),
515 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_offset
),
516 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_uniqueness
),
517 __le16_to_cpu(INFO
->current_ih
->ih_version
));
518 #endif /* REISERDEBUG */
522 /* preconditions: reiserfs_mount already executed, therefore
523 * INFO block is valid
524 * returns: 0 if error (errnum is set),
525 * nonzero iff we were able to find the key successfully.
526 * postconditions: on a nonzero return, the current_ih and
527 * current_item fields describe the key that equals the
528 * searched key. INFO->next_key contains the next key after
530 * side effects: messes around with the cache.
533 search_stat (__u32 dir_id
, __u32 objectid
)
539 struct item_head
*ih
;
541 printf ("search_stat:\n key %d:%d:0:0\n", dir_id
, objectid
);
542 #endif /* REISERDEBUG */
544 depth
= INFO
->tree_depth
;
547 while (depth
> DISK_LEAF_NODE_LEVEL
)
550 nr_item
= __le16_to_cpu(BLOCKHEAD (cache
)->blk_nr_item
);
554 for (i
= 0; i
< nr_item
; i
++)
556 if (__le32_to_cpu(key
->k_dir_id
) > dir_id
557 || (__le32_to_cpu(key
->k_dir_id
) == dir_id
558 && (__le32_to_cpu(key
->k_objectid
) > objectid
559 || (__le32_to_cpu(key
->k_objectid
) == objectid
560 && (__le32_to_cpu(key
->u
.v1
.k_offset
)
561 | __le32_to_cpu(key
->u
.v1
.k_uniqueness
)) > 0))))
567 printf (" depth=%d, i=%d/%d\n", depth
, i
, nr_item
);
568 #endif /* REISERDEBUG */
569 INFO
->next_key_nr
[depth
] = (i
== nr_item
) ? 0 : i
+1;
570 cache
= read_tree_node (dc_block_number(&(DC (cache
)[i
])), --depth
);
576 nr_item
= __le16_to_cpu(BLOCKHEAD (LEAF
)->blk_nr_item
);
578 for (i
= 0; i
< nr_item
; i
++)
580 if (__le32_to_cpu(ih
->ih_key
.k_dir_id
) == dir_id
581 && __le32_to_cpu(ih
->ih_key
.k_objectid
) == objectid
582 && __le32_to_cpu(ih
->ih_key
.u
.v1
.k_offset
) == 0
583 && __le32_to_cpu(ih
->ih_key
.u
.v1
.k_uniqueness
) == 0)
586 printf (" depth=%d, i=%d/%d\n", depth
, i
, nr_item
);
587 #endif /* REISERDEBUG */
588 INFO
->current_ih
= ih
;
589 INFO
->current_item
= &LEAF
[__le16_to_cpu(ih
->ih_item_location
)];
594 errnum
= ERR_FSYS_CORRUPT
;
599 reiserfs_read (char *buf
, unsigned len
)
601 unsigned int blocksize
;
603 unsigned int to_read
;
604 char *prev_buf
= buf
;
607 printf ("reiserfs_read: filepos=%d len=%d, offset=%Lx\n",
608 filepos
, len
, (__u64
) IH_KEY_OFFSET (INFO
->current_ih
) - 1);
609 #endif /* REISERDEBUG */
611 if (__le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
) != INFO
->fileinfo
.k_objectid
612 || IH_KEY_OFFSET (INFO
->current_ih
) > filepos
+ 1)
614 search_stat (INFO
->fileinfo
.k_dir_id
, INFO
->fileinfo
.k_objectid
);
620 if (__le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
) != INFO
->fileinfo
.k_objectid
) {
624 offset
= filepos
- IH_KEY_OFFSET (INFO
->current_ih
) + 1;
625 blocksize
= __le16_to_cpu(INFO
->current_ih
->ih_item_len
);
628 printf (" loop: filepos=%d len=%d, offset=%d blocksize=%d\n",
629 filepos
, len
, offset
, blocksize
);
630 #endif /* REISERDEBUG */
632 if (IH_KEY_ISTYPE(INFO
->current_ih
, TYPE_DIRECT
)
633 && offset
< blocksize
)
636 printf ("direct_read: offset=%d, blocksize=%d\n",
638 #endif /* REISERDEBUG */
639 to_read
= blocksize
- offset
;
643 memcpy (buf
, INFO
->current_item
+ offset
, to_read
);
646 else if (IH_KEY_ISTYPE(INFO
->current_ih
, TYPE_INDIRECT
))
648 blocksize
= (blocksize
>> 2) << INFO
->fullblocksize_shift
;
650 printf ("indirect_read: offset=%d, blocksize=%d\n",
652 #endif /* REISERDEBUG */
654 while (offset
< blocksize
)
656 __u32 blocknr
= __le32_to_cpu(((__u32
*) INFO
->current_item
)
657 [offset
>> INFO
->fullblocksize_shift
]);
658 int blk_offset
= offset
& (INFO
->blocksize
-1);
659 to_read
= INFO
->blocksize
- blk_offset
;
663 /* Journal is only for meta data. Data blocks can be read
664 * directly without using block_read
666 reiserfs_devread (blocknr
<< INFO
->blocksize_shift
,
667 blk_offset
, to_read
, buf
);
681 return errnum
? 0 : buf
- prev_buf
;
685 /* preconditions: reiserfs_mount already executed, therefore
686 * INFO block is valid
687 * returns: 0 if error, nonzero iff we were able to find the file successfully
688 * postconditions: on a nonzero return, INFO->fileinfo contains the info
689 * of the file we were trying to look up, filepos is 0 and filemax is
690 * the size of the file.
693 reiserfs_dir (char *dirname
)
695 struct reiserfs_de_head
*de_head
;
697 __u32 dir_id
, objectid
, parent_dir_id
= 0, parent_objectid
= 0;
699 int do_possibilities
= 0;
700 #endif /* ! STAGE1_5 */
701 char linkbuf
[PATH_MAX
]; /* buffer for following symbolic links */
705 dir_id
= REISERFS_ROOT_PARENT_OBJECTID
;
706 objectid
= REISERFS_ROOT_OBJECTID
;
711 printf ("dirname=%s\n", dirname
);
712 #endif /* REISERDEBUG */
714 /* Search for the stat info first. */
715 if (! search_stat (dir_id
, objectid
))
719 printf ("sd_mode=%x sd_size=%d\n",
720 stat_data_v1(INFO
->current_ih
) ? sd_v1_mode((struct stat_data_v1
*) INFO
->current_item
) :
721 sd_v2_mode((struct stat_data
*) (INFO
->current_item
)),
722 stat_data_v1(INFO
->current_ih
) ? sd_v1_size((struct stat_data_v1
*) INFO
->current_item
) :
723 sd_v2_size((struct stat_data
*) INFO
->current_item
)
726 #endif /* REISERDEBUG */
727 mode
= stat_data_v1(INFO
->current_ih
) ?
728 sd_v1_mode((struct stat_data_v1
*) INFO
->current_item
) :
729 sd_v2_mode((struct stat_data
*) INFO
->current_item
);
731 /* If we've got a symbolic link, then chase it. */
735 if (++link_count
> MAX_LINK_COUNT
)
737 errnum
= ERR_SYMLINK_LOOP
;
741 /* Get the symlink size. */
742 filemax
= stat_data_v1(INFO
->current_ih
) ?
743 sd_v1_size((struct stat_data_v1
*) INFO
->current_item
) :
744 sd_v2_size((struct stat_data
*) INFO
->current_item
);
746 /* Find out how long our remaining name is. */
748 while (dirname
[len
] && !isspace (dirname
[len
]))
751 if (filemax
+ len
> sizeof (linkbuf
) - 1)
753 errnum
= ERR_FILELENGTH
;
757 /* Copy the remaining name to the end of the symlink data.
758 Note that DIRNAME and LINKBUF may overlap! */
759 memmove (linkbuf
+ filemax
, dirname
, len
+1);
761 INFO
->fileinfo
.k_dir_id
= dir_id
;
762 INFO
->fileinfo
.k_objectid
= objectid
;
765 || reiserfs_read (linkbuf
, filemax
) != filemax
)
768 errnum
= ERR_FSYS_CORRUPT
;
773 printf ("symlink=%s\n", linkbuf
);
774 #endif /* REISERDEBUG */
779 /* It's an absolute link, so look it up in root. */
780 dir_id
= REISERFS_ROOT_PARENT_OBJECTID
;
781 objectid
= REISERFS_ROOT_OBJECTID
;
785 /* Relative, so look it up in our parent directory. */
786 dir_id
= parent_dir_id
;
787 objectid
= parent_objectid
;
790 /* Now lookup the new name. */
794 /* if we have a real file (and we're not just printing possibilities),
795 then this is where we want to exit */
797 if (! *dirname
|| isspace (*dirname
))
799 if (! S_ISREG (mode
))
801 errnum
= ERR_BAD_FILETYPE
;
806 filemax
= stat_data_v1(INFO
->current_ih
) ?
807 sd_v1_size((struct stat_data_v1
*) INFO
->current_item
) :
808 sd_v2_size((struct stat_data
*) INFO
->current_item
);
810 /* If this is a new stat data and size is > 4GB set filemax to
813 if (__le16_to_cpu(INFO
->current_ih
->ih_version
) == ITEM_VERSION_2
814 && sd_size_hi((struct stat_data
*) INFO
->current_item
) > 0)
815 filemax
= 0xffffffff;
817 INFO
->fileinfo
.k_dir_id
= dir_id
;
818 INFO
->fileinfo
.k_objectid
= objectid
;
822 /* continue with the file/directory name interpretation */
823 while (*dirname
== '/')
825 if (! S_ISDIR (mode
))
827 errnum
= ERR_BAD_FILETYPE
;
830 for (rest
= dirname
; (ch
= *rest
) && ! isspace (ch
) && ch
!= '/'; rest
++);
834 if (print_possibilities
&& ch
!= '/')
835 do_possibilities
= 1;
836 # endif /* ! STAGE1_5 */
846 printf ("ih: key %d:%d:%d:%d version:%d\n",
847 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_dir_id
),
848 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
),
849 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_offset
),
850 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_uniqueness
),
851 __le16_to_cpu(INFO
->current_ih
->ih_version
));
852 #endif /* REISERDEBUG */
854 if (__le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
) != objectid
)
857 name_end
= INFO
->current_item
+ __le16_to_cpu(INFO
->current_ih
->ih_item_len
);
858 de_head
= (struct reiserfs_de_head
*) INFO
->current_item
;
859 num_entries
= __le16_to_cpu(INFO
->current_ih
->u
.ih_entry_count
);
860 while (num_entries
> 0)
862 char *filename
= INFO
->current_item
+ deh_location(de_head
);
863 char tmp
= *name_end
;
864 if ((deh_state(de_head
) & DEH_Visible
))
867 /* Directory names in ReiserFS are not null
868 * terminated. We write a temporary 0 behind it.
869 * NOTE: that this may overwrite the first block in
870 * the tree cache. That doesn't hurt as long as we
871 * don't call next_key () in between.
874 cmp
= substring (dirname
, filename
);
877 if (do_possibilities
)
882 struct fsys_reiser_info info_save
;
884 if (print_possibilities
> 0)
885 print_possibilities
= -print_possibilities
;
887 strcpy(fn
, filename
);
890 /* If NAME is "." or "..", do not count it. */
891 if (strcmp (fn
, ".") != 0 && strcmp (fn
, "..") != 0) {
892 memcpy(&info_save
, INFO
, sizeof(struct fsys_reiser_info
));
893 search_stat (deh_dir_id(de_head
), deh_objectid(de_head
));
894 sd_print_item(INFO
->current_ih
, INFO
->current_item
);
896 search_stat (dir_id
, objectid
);
897 memcpy(INFO
, &info_save
, sizeof(struct fsys_reiser_info
));
902 # endif /* ! STAGE1_5 */
906 /* The beginning of this name marks the end of the next name.
915 if (print_possibilities
< 0)
917 # endif /* ! STAGE1_5 */
919 errnum
= ERR_FILE_NOT_FOUND
;
927 parent_dir_id
= dir_id
;
928 parent_objectid
= objectid
;
929 dir_id
= deh_dir_id(de_head
);
930 objectid
= deh_objectid(de_head
);
935 * U-Boot interface functions
939 * List given directory
941 * RETURN: 0 - OK, else grub_error_t errnum
944 reiserfs_ls (char *dirname
)
950 dir_slash
= malloc(strlen(dirname
) + 1);
951 if (dir_slash
== NULL
) {
952 return ERR_NUMBER_OVERFLOW
;
954 strcpy(dir_slash
, dirname
);
955 /* add "/" to the directory name */
956 strcat(dir_slash
, "/");
958 print_possibilities
= 1;
959 res
= reiserfs_dir (dir_slash
);
961 if (!res
|| errnum
) {
969 * Open file for reading
971 * RETURN: >0 - OK, size of opened file
972 * <0 - ERROR -grub_error_t errnum
975 reiserfs_open (char *filename
)
979 print_possibilities
= 0;
980 if (!reiserfs_dir (filename
) || errnum
) {
986 #endif /* CFG_CMD_REISER */