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 * SPDX-License-Identifier: GPL-2.0+
14 /* An implementation for the ReiserFS filesystem ported from GRUB.
15 * Some parts of this code (mainly the structures and defines) are
16 * from the original reiser fs code, as found in the linux kernel.
21 #include <linux/ctype.h>
22 #include <linux/time.h>
23 #include <asm/byteorder.h>
26 #include "reiserfs_private.h"
30 /* Some parts of this code (mainly the structures and defines) are
31 * from the original reiser fs code, as found in the linux kernel.
34 static char fsys_buf
[FSYS_BUFLEN
];
35 static reiserfs_error_t errnum
= ERR_NONE
;
36 static int print_possibilities
;
37 static unsigned int filepos
, filemax
;
40 substring (const char *s1
, const char *s2
)
44 /* The strings match exactly. */
50 /* S1 is a substring of S2. */
54 /* S1 isn't a substring. */
58 static void sd_print_item (struct item_head
* ih
, char * item
)
63 if (stat_data_v1 (ih
)) {
64 struct stat_data_v1
* sd
= (struct stat_data_v1
*)item
;
65 ttime
= sd_v1_mtime(sd
);
66 ctime_r(&ttime
, filetime
);
67 printf ("%-10s %4hd %6d %6d %9d %24.24s",
68 bb_mode_string(sd_v1_mode(sd
)), sd_v1_nlink(sd
),sd_v1_uid(sd
), sd_v1_gid(sd
),
69 sd_v1_size(sd
), filetime
);
71 struct stat_data
* sd
= (struct stat_data
*)item
;
72 ttime
= sd_v2_mtime(sd
);
73 ctime_r(&ttime
, filetime
);
74 printf ("%-10s %4d %6d %6d %9d %24.24s",
75 bb_mode_string(sd_v2_mode(sd
)), sd_v2_nlink(sd
),sd_v2_uid(sd
),sd_v2_gid(sd
),
76 (__u32
) sd_v2_size(sd
), filetime
);
81 journal_read (int block
, int len
, char *buffer
)
83 return reiserfs_devread ((INFO
->journal_block
+ block
) << INFO
->blocksize_shift
,
87 /* Read a block from ReiserFS file system, taking the journal into
88 * account. If the block nr is in the journal, the block from the
92 block_read (unsigned int blockNr
, int start
, int len
, char *buffer
)
94 int transactions
= INFO
->journal_transactions
;
95 int desc_block
= INFO
->journal_first_desc
;
96 int journal_mask
= INFO
->journal_block_count
- 1;
97 int translatedNr
= blockNr
;
98 __u32
*journal_table
= JOURNAL_START
;
99 while (transactions
-- > 0)
103 if (__le32_to_cpu(*journal_table
) != 0xffffffff)
105 /* Search for the blockNr in cached journal */
106 j_len
= __le32_to_cpu(*journal_table
++);
109 if (__le32_to_cpu(*journal_table
++) == blockNr
)
111 journal_table
+= j_len
- i
;
118 /* This is the end of cached journal marker. The remaining
119 * transactions are still on disk.
121 struct reiserfs_journal_desc desc
;
122 struct reiserfs_journal_commit commit
;
124 if (! journal_read (desc_block
, sizeof (desc
), (char *) &desc
))
127 j_len
= __le32_to_cpu(desc
.j_len
);
128 while (i
< j_len
&& i
< JOURNAL_TRANS_HALF
)
129 if (__le32_to_cpu(desc
.j_realblock
[i
++]) == blockNr
)
132 if (j_len
>= JOURNAL_TRANS_HALF
)
134 int commit_block
= (desc_block
+ 1 + j_len
) & journal_mask
;
135 if (! journal_read (commit_block
,
136 sizeof (commit
), (char *) &commit
))
139 if (__le32_to_cpu(commit
.j_realblock
[i
++ - JOURNAL_TRANS_HALF
]) == blockNr
)
146 translatedNr
= INFO
->journal_block
+ ((desc_block
+ i
) & journal_mask
);
148 printf ("block_read: block %d is mapped to journal block %d.\n",
149 blockNr
, translatedNr
- INFO
->journal_block
);
151 /* We must continue the search, as this block may be overwritten
152 * in later transactions.
155 desc_block
= (desc_block
+ 2 + j_len
) & journal_mask
;
157 return reiserfs_devread (translatedNr
<< INFO
->blocksize_shift
, start
, len
, buffer
);
160 /* Init the journal data structure. We try to cache as much as
161 * possible in the JOURNAL_START-JOURNAL_END space, but if it is full
162 * we can still read the rest from the disk on demand.
164 * The first number of valid transactions and the descriptor block of the
165 * first valid transaction are held in INFO. The transactions are all
166 * adjacent, but we must take care of the journal wrap around.
171 unsigned int block_count
= INFO
->journal_block_count
;
172 unsigned int desc_block
;
173 unsigned int commit_block
;
174 unsigned int next_trans_id
;
175 struct reiserfs_journal_header header
;
176 struct reiserfs_journal_desc desc
;
177 struct reiserfs_journal_commit commit
;
178 __u32
*journal_table
= JOURNAL_START
;
180 journal_read (block_count
, sizeof (header
), (char *) &header
);
181 desc_block
= __le32_to_cpu(header
.j_first_unflushed_offset
);
182 if (desc_block
>= block_count
)
185 INFO
->journal_first_desc
= desc_block
;
186 next_trans_id
= __le32_to_cpu(header
.j_last_flush_trans_id
) + 1;
189 printf ("journal_init: last flushed %d\n",
190 __le32_to_cpu(header
.j_last_flush_trans_id
));
195 journal_read (desc_block
, sizeof (desc
), (char *) &desc
);
196 if (substring (JOURNAL_DESC_MAGIC
, desc
.j_magic
) > 0
197 || __le32_to_cpu(desc
.j_trans_id
) != next_trans_id
198 || __le32_to_cpu(desc
.j_mount_id
) != __le32_to_cpu(header
.j_mount_id
))
199 /* no more valid transactions */
202 commit_block
= (desc_block
+ __le32_to_cpu(desc
.j_len
) + 1) & (block_count
- 1);
203 journal_read (commit_block
, sizeof (commit
), (char *) &commit
);
204 if (__le32_to_cpu(desc
.j_trans_id
) != commit
.j_trans_id
205 || __le32_to_cpu(desc
.j_len
) != __le32_to_cpu(commit
.j_len
))
206 /* no more valid transactions */
210 printf ("Found valid transaction %d/%d at %d.\n",
211 __le32_to_cpu(desc
.j_trans_id
), __le32_to_cpu(desc
.j_mount_id
), desc_block
);
215 if (journal_table
< JOURNAL_END
)
217 if ((journal_table
+ 1 + __le32_to_cpu(desc
.j_len
)) >= JOURNAL_END
)
219 /* The table is almost full; mark the end of the cached
221 *journal_table
= __cpu_to_le32(0xffffffff);
222 journal_table
= JOURNAL_END
;
227 /* Cache the length and the realblock numbers in the table.
228 * The block number of descriptor can easily be computed.
229 * and need not to be stored here.
232 /* both are in the little endian format */
233 *journal_table
++ = desc
.j_len
;
234 for (i
= 0; i
< __le32_to_cpu(desc
.j_len
) && i
< JOURNAL_TRANS_HALF
; i
++)
236 /* both are in the little endian format */
237 *journal_table
++ = desc
.j_realblock
[i
];
239 printf ("block %d is in journal %d.\n",
240 __le32_to_cpu(desc
.j_realblock
[i
]), desc_block
);
243 for ( ; i
< __le32_to_cpu(desc
.j_len
); i
++)
245 /* both are in the little endian format */
246 *journal_table
++ = commit
.j_realblock
[i
-JOURNAL_TRANS_HALF
];
248 printf ("block %d is in journal %d.\n",
249 __le32_to_cpu(commit
.j_realblock
[i
-JOURNAL_TRANS_HALF
]),
255 desc_block
= (commit_block
+ 1) & (block_count
- 1);
258 printf ("Transaction %d/%d at %d isn't valid.\n",
259 __le32_to_cpu(desc
.j_trans_id
), __le32_to_cpu(desc
.j_mount_id
), desc_block
);
262 INFO
->journal_transactions
263 = next_trans_id
- __le32_to_cpu(header
.j_last_flush_trans_id
) - 1;
267 /* check filesystem types and read superblock into memory buffer */
269 reiserfs_mount (unsigned part_length
)
271 struct reiserfs_super_block super
;
272 int superblock
= REISERFS_DISK_OFFSET_IN_BYTES
>> SECTOR_BITS
;
275 if (part_length
< superblock
+ (sizeof (super
) >> SECTOR_BITS
)
276 || ! reiserfs_devread (superblock
, 0, sizeof (struct reiserfs_super_block
),
278 || (substring (REISER3FS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0
279 && substring (REISER2FS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0
280 && substring (REISERFS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0)
281 || (/* check that this is not a copy inside the journal log */
282 sb_journal_block(&super
) * sb_blocksize(&super
)
283 <= REISERFS_DISK_OFFSET_IN_BYTES
))
285 /* Try old super block position */
286 superblock
= REISERFS_OLD_DISK_OFFSET_IN_BYTES
>> SECTOR_BITS
;
287 if (part_length
< superblock
+ (sizeof (super
) >> SECTOR_BITS
)
288 || ! reiserfs_devread (superblock
, 0, sizeof (struct reiserfs_super_block
),
292 if (substring (REISER2FS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0
293 && substring (REISERFS_SUPER_MAGIC_STRING
, super
.s_magic
) > 0)
295 /* pre journaling super block ? */
296 if (substring (REISERFS_SUPER_MAGIC_STRING
,
297 (char*) ((int) &super
+ 20)) > 0)
300 set_sb_blocksize(&super
, REISERFS_OLD_BLOCKSIZE
);
301 set_sb_journal_block(&super
, 0);
302 set_sb_version(&super
, 0);
306 /* check the version number. */
307 if (sb_version(&super
) > REISERFS_MAX_SUPPORTED_VERSION
)
310 INFO
->version
= sb_version(&super
);
311 INFO
->blocksize
= sb_blocksize(&super
);
312 INFO
->fullblocksize_shift
= log2 (sb_blocksize(&super
));
313 INFO
->blocksize_shift
= INFO
->fullblocksize_shift
- SECTOR_BITS
;
315 (FSYSREISER_CACHE_SIZE
>> INFO
->fullblocksize_shift
) - 1;
318 printf ("reiserfs_mount: version=%d, blocksize=%d\n",
319 INFO
->version
, INFO
->blocksize
);
320 #endif /* REISERDEBUG */
322 /* Clear node cache. */
323 memset (INFO
->blocks
, 0, sizeof (INFO
->blocks
));
325 if (sb_blocksize(&super
) < FSYSREISER_MIN_BLOCKSIZE
326 || sb_blocksize(&super
) > FSYSREISER_MAX_BLOCKSIZE
327 || (SECTOR_SIZE
<< INFO
->blocksize_shift
) != sb_blocksize(&super
))
330 /* Initialize journal code. If something fails we end with zero
331 * journal_transactions, so we don't access the journal at all.
333 INFO
->journal_transactions
= 0;
334 if (sb_journal_block(&super
) != 0 && super
.s_journal_dev
== 0)
336 INFO
->journal_block
= sb_journal_block(&super
);
337 INFO
->journal_block_count
= sb_journal_size(&super
);
338 if (is_power_of_two (INFO
->journal_block_count
))
341 /* Read in super block again, maybe it is in the journal */
342 block_read (superblock
>> INFO
->blocksize_shift
,
343 0, sizeof (struct reiserfs_super_block
), (char *) &super
);
346 if (! block_read (sb_root_block(&super
), 0, INFO
->blocksize
, (char*) ROOT
))
350 INFO
->tree_depth
= __le16_to_cpu(BLOCKHEAD (cache
)->blk_level
);
353 printf ("root read_in: block=%d, depth=%d\n",
354 sb_root_block(&super
), INFO
->tree_depth
);
355 #endif /* REISERDEBUG */
357 if (INFO
->tree_depth
>= MAX_HEIGHT
)
359 if (INFO
->tree_depth
== DISK_LEAF_NODE_LEVEL
)
361 /* There is only one node in the whole filesystem,
362 * which is simultanously leaf and root */
363 memcpy (LEAF
, ROOT
, INFO
->blocksize
);
368 /***************** TREE ACCESSING METHODS *****************************/
370 /* I assume you are familiar with the ReiserFS tree, if not go to
371 * http://www.namesys.com/content_table.html
373 * My tree node cache is organized as following
375 * 1 LEAF node (if the ROOT is also a LEAF it is copied here
376 * 2-n other nodes on current path from bottom to top.
377 * if there is not enough space in the cache, the top most are
380 * I have only two methods to find a key in the tree:
381 * search_stat(dir_id, objectid) searches for the stat entry (always
382 * the first entry) of an object.
383 * next_key() gets the next key in tree order.
385 * This means, that I can only sequential reads of files are
386 * efficient, but this really doesn't hurt for grub.
389 /* Read in the node at the current path and depth into the node cache.
390 * You must set INFO->blocks[depth] before.
393 read_tree_node (unsigned int blockNr
, int depth
)
395 char* cache
= CACHE(depth
);
396 int num_cached
= INFO
->cached_slots
;
397 if (depth
< num_cached
)
399 /* This is the cached part of the path. Check if same block is
402 if (blockNr
== INFO
->blocks
[depth
])
406 cache
= CACHE(num_cached
);
409 printf (" next read_in: block=%d (depth=%d)\n",
411 #endif /* REISERDEBUG */
412 if (! block_read (blockNr
, 0, INFO
->blocksize
, cache
))
414 /* Make sure it has the right node level */
415 if (__le16_to_cpu(BLOCKHEAD (cache
)->blk_level
) != depth
)
417 errnum
= ERR_FSYS_CORRUPT
;
421 INFO
->blocks
[depth
] = blockNr
;
425 /* Get the next key, i.e. the key following the last retrieved key in
426 * tree order. INFO->current_ih and
427 * INFO->current_info are adapted accordingly. */
432 struct item_head
*ih
= INFO
->current_ih
+ 1;
436 printf ("next_key:\n old ih: key %d:%d:%d:%d version:%d\n",
437 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_dir_id
),
438 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
),
439 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_offset
),
440 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_uniqueness
),
441 __le16_to_cpu(INFO
->current_ih
->ih_version
));
442 #endif /* REISERDEBUG */
444 if (ih
== &ITEMHEAD
[__le16_to_cpu(BLOCKHEAD (LEAF
)->blk_nr_item
)])
446 depth
= DISK_LEAF_NODE_LEVEL
;
447 /* The last item, was the last in the leaf node.
448 * Read in the next block
452 if (depth
== INFO
->tree_depth
)
454 /* There are no more keys at all.
455 * Return a dummy item with MAX_KEY */
456 ih
= (struct item_head
*) &BLOCKHEAD (LEAF
)->blk_right_delim_key
;
461 printf (" depth=%d, i=%d\n", depth
, INFO
->next_key_nr
[depth
]);
462 #endif /* REISERDEBUG */
464 while (INFO
->next_key_nr
[depth
] == 0);
466 if (depth
== INFO
->tree_depth
)
468 else if (depth
<= INFO
->cached_slots
)
469 cache
= CACHE (depth
);
472 cache
= read_tree_node (INFO
->blocks
[depth
], depth
);
479 int nr_item
= __le16_to_cpu(BLOCKHEAD (cache
)->blk_nr_item
);
480 int key_nr
= INFO
->next_key_nr
[depth
]++;
482 printf (" depth=%d, i=%d/%d\n", depth
, key_nr
, nr_item
);
483 #endif /* REISERDEBUG */
484 if (key_nr
== nr_item
)
485 /* This is the last item in this block, set the next_key_nr to 0 */
486 INFO
->next_key_nr
[depth
] = 0;
488 cache
= read_tree_node (dc_block_number(&(DC (cache
)[key_nr
])), --depth
);
492 while (depth
> DISK_LEAF_NODE_LEVEL
);
497 INFO
->current_ih
= ih
;
498 INFO
->current_item
= &LEAF
[__le16_to_cpu(ih
->ih_item_location
)];
500 printf (" new ih: key %d:%d:%d:%d version:%d\n",
501 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_dir_id
),
502 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
),
503 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_offset
),
504 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_uniqueness
),
505 __le16_to_cpu(INFO
->current_ih
->ih_version
));
506 #endif /* REISERDEBUG */
510 /* preconditions: reiserfs_mount already executed, therefore
511 * INFO block is valid
512 * returns: 0 if error (errnum is set),
513 * nonzero iff we were able to find the key successfully.
514 * postconditions: on a nonzero return, the current_ih and
515 * current_item fields describe the key that equals the
516 * searched key. INFO->next_key contains the next key after
518 * side effects: messes around with the cache.
521 search_stat (__u32 dir_id
, __u32 objectid
)
527 struct item_head
*ih
;
529 printf ("search_stat:\n key %d:%d:0:0\n", dir_id
, objectid
);
530 #endif /* REISERDEBUG */
532 depth
= INFO
->tree_depth
;
535 while (depth
> DISK_LEAF_NODE_LEVEL
)
538 nr_item
= __le16_to_cpu(BLOCKHEAD (cache
)->blk_nr_item
);
542 for (i
= 0; i
< nr_item
; i
++)
544 if (__le32_to_cpu(key
->k_dir_id
) > dir_id
545 || (__le32_to_cpu(key
->k_dir_id
) == dir_id
546 && (__le32_to_cpu(key
->k_objectid
) > objectid
547 || (__le32_to_cpu(key
->k_objectid
) == objectid
548 && (__le32_to_cpu(key
->u
.v1
.k_offset
)
549 | __le32_to_cpu(key
->u
.v1
.k_uniqueness
)) > 0))))
555 printf (" depth=%d, i=%d/%d\n", depth
, i
, nr_item
);
556 #endif /* REISERDEBUG */
557 INFO
->next_key_nr
[depth
] = (i
== nr_item
) ? 0 : i
+1;
558 cache
= read_tree_node (dc_block_number(&(DC (cache
)[i
])), --depth
);
564 nr_item
= __le16_to_cpu(BLOCKHEAD (LEAF
)->blk_nr_item
);
566 for (i
= 0; i
< nr_item
; i
++)
568 if (__le32_to_cpu(ih
->ih_key
.k_dir_id
) == dir_id
569 && __le32_to_cpu(ih
->ih_key
.k_objectid
) == objectid
570 && __le32_to_cpu(ih
->ih_key
.u
.v1
.k_offset
) == 0
571 && __le32_to_cpu(ih
->ih_key
.u
.v1
.k_uniqueness
) == 0)
574 printf (" depth=%d, i=%d/%d\n", depth
, i
, nr_item
);
575 #endif /* REISERDEBUG */
576 INFO
->current_ih
= ih
;
577 INFO
->current_item
= &LEAF
[__le16_to_cpu(ih
->ih_item_location
)];
582 errnum
= ERR_FSYS_CORRUPT
;
587 reiserfs_read (char *buf
, unsigned len
)
589 unsigned int blocksize
;
591 unsigned int to_read
;
592 char *prev_buf
= buf
;
595 printf ("reiserfs_read: filepos=%d len=%d, offset=%Lx\n",
596 filepos
, len
, (__u64
) IH_KEY_OFFSET (INFO
->current_ih
) - 1);
597 #endif /* REISERDEBUG */
599 if (__le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
) != INFO
->fileinfo
.k_objectid
600 || IH_KEY_OFFSET (INFO
->current_ih
) > filepos
+ 1)
602 search_stat (INFO
->fileinfo
.k_dir_id
, INFO
->fileinfo
.k_objectid
);
608 if (__le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
) != INFO
->fileinfo
.k_objectid
) {
612 offset
= filepos
- IH_KEY_OFFSET (INFO
->current_ih
) + 1;
613 blocksize
= __le16_to_cpu(INFO
->current_ih
->ih_item_len
);
616 printf (" loop: filepos=%d len=%d, offset=%d blocksize=%d\n",
617 filepos
, len
, offset
, blocksize
);
618 #endif /* REISERDEBUG */
620 if (IH_KEY_ISTYPE(INFO
->current_ih
, TYPE_DIRECT
)
621 && offset
< blocksize
)
624 printf ("direct_read: offset=%d, blocksize=%d\n",
626 #endif /* REISERDEBUG */
627 to_read
= blocksize
- offset
;
631 memcpy (buf
, INFO
->current_item
+ offset
, to_read
);
634 else if (IH_KEY_ISTYPE(INFO
->current_ih
, TYPE_INDIRECT
))
636 blocksize
= (blocksize
>> 2) << INFO
->fullblocksize_shift
;
638 printf ("indirect_read: offset=%d, blocksize=%d\n",
640 #endif /* REISERDEBUG */
642 while (offset
< blocksize
)
644 __u32 blocknr
= __le32_to_cpu(((__u32
*) INFO
->current_item
)
645 [offset
>> INFO
->fullblocksize_shift
]);
646 int blk_offset
= offset
& (INFO
->blocksize
-1);
647 to_read
= INFO
->blocksize
- blk_offset
;
651 /* Journal is only for meta data. Data blocks can be read
652 * directly without using block_read
654 reiserfs_devread (blocknr
<< INFO
->blocksize_shift
,
655 blk_offset
, to_read
, buf
);
669 return errnum
? 0 : buf
- prev_buf
;
673 /* preconditions: reiserfs_mount already executed, therefore
674 * INFO block is valid
675 * returns: 0 if error, nonzero iff we were able to find the file successfully
676 * postconditions: on a nonzero return, INFO->fileinfo contains the info
677 * of the file we were trying to look up, filepos is 0 and filemax is
678 * the size of the file.
681 reiserfs_dir (char *dirname
)
683 struct reiserfs_de_head
*de_head
;
685 __u32 dir_id
, objectid
, parent_dir_id
= 0, parent_objectid
= 0;
687 int do_possibilities
= 0;
688 #endif /* ! STAGE1_5 */
689 char linkbuf
[PATH_MAX
]; /* buffer for following symbolic links */
693 dir_id
= REISERFS_ROOT_PARENT_OBJECTID
;
694 objectid
= REISERFS_ROOT_OBJECTID
;
699 printf ("dirname=%s\n", dirname
);
700 #endif /* REISERDEBUG */
702 /* Search for the stat info first. */
703 if (! search_stat (dir_id
, objectid
))
707 printf ("sd_mode=%x sd_size=%d\n",
708 stat_data_v1(INFO
->current_ih
) ? sd_v1_mode((struct stat_data_v1
*) INFO
->current_item
) :
709 sd_v2_mode((struct stat_data
*) (INFO
->current_item
)),
710 stat_data_v1(INFO
->current_ih
) ? sd_v1_size((struct stat_data_v1
*) INFO
->current_item
) :
711 sd_v2_size((struct stat_data
*) INFO
->current_item
)
714 #endif /* REISERDEBUG */
715 mode
= stat_data_v1(INFO
->current_ih
) ?
716 sd_v1_mode((struct stat_data_v1
*) INFO
->current_item
) :
717 sd_v2_mode((struct stat_data
*) INFO
->current_item
);
719 /* If we've got a symbolic link, then chase it. */
723 if (++link_count
> MAX_LINK_COUNT
)
725 errnum
= ERR_SYMLINK_LOOP
;
729 /* Get the symlink size. */
730 filemax
= stat_data_v1(INFO
->current_ih
) ?
731 sd_v1_size((struct stat_data_v1
*) INFO
->current_item
) :
732 sd_v2_size((struct stat_data
*) INFO
->current_item
);
734 /* Find out how long our remaining name is. */
736 while (dirname
[len
] && !isspace (dirname
[len
]))
739 if (filemax
+ len
> sizeof (linkbuf
) - 1)
741 errnum
= ERR_FILELENGTH
;
745 /* Copy the remaining name to the end of the symlink data.
746 Note that DIRNAME and LINKBUF may overlap! */
747 memmove (linkbuf
+ filemax
, dirname
, len
+1);
749 INFO
->fileinfo
.k_dir_id
= dir_id
;
750 INFO
->fileinfo
.k_objectid
= objectid
;
753 || reiserfs_read (linkbuf
, filemax
) != filemax
)
756 errnum
= ERR_FSYS_CORRUPT
;
761 printf ("symlink=%s\n", linkbuf
);
762 #endif /* REISERDEBUG */
767 /* It's an absolute link, so look it up in root. */
768 dir_id
= REISERFS_ROOT_PARENT_OBJECTID
;
769 objectid
= REISERFS_ROOT_OBJECTID
;
773 /* Relative, so look it up in our parent directory. */
774 dir_id
= parent_dir_id
;
775 objectid
= parent_objectid
;
778 /* Now lookup the new name. */
782 /* if we have a real file (and we're not just printing possibilities),
783 then this is where we want to exit */
785 if (! *dirname
|| isspace (*dirname
))
787 if (! S_ISREG (mode
))
789 errnum
= ERR_BAD_FILETYPE
;
794 filemax
= stat_data_v1(INFO
->current_ih
) ?
795 sd_v1_size((struct stat_data_v1
*) INFO
->current_item
) :
796 sd_v2_size((struct stat_data
*) INFO
->current_item
);
798 /* If this is a new stat data and size is > 4GB set filemax to
801 if (__le16_to_cpu(INFO
->current_ih
->ih_version
) == ITEM_VERSION_2
802 && sd_size_hi((struct stat_data
*) INFO
->current_item
) > 0)
803 filemax
= 0xffffffff;
805 INFO
->fileinfo
.k_dir_id
= dir_id
;
806 INFO
->fileinfo
.k_objectid
= objectid
;
810 /* continue with the file/directory name interpretation */
811 while (*dirname
== '/')
813 if (! S_ISDIR (mode
))
815 errnum
= ERR_BAD_FILETYPE
;
818 for (rest
= dirname
; (ch
= *rest
) && ! isspace (ch
) && ch
!= '/'; rest
++);
822 if (print_possibilities
&& ch
!= '/')
823 do_possibilities
= 1;
824 # endif /* ! STAGE1_5 */
834 printf ("ih: key %d:%d:%d:%d version:%d\n",
835 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_dir_id
),
836 __le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
),
837 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_offset
),
838 __le32_to_cpu(INFO
->current_ih
->ih_key
.u
.v1
.k_uniqueness
),
839 __le16_to_cpu(INFO
->current_ih
->ih_version
));
840 #endif /* REISERDEBUG */
842 if (__le32_to_cpu(INFO
->current_ih
->ih_key
.k_objectid
) != objectid
)
845 name_end
= INFO
->current_item
+ __le16_to_cpu(INFO
->current_ih
->ih_item_len
);
846 de_head
= (struct reiserfs_de_head
*) INFO
->current_item
;
847 num_entries
= __le16_to_cpu(INFO
->current_ih
->u
.ih_entry_count
);
848 while (num_entries
> 0)
850 char *filename
= INFO
->current_item
+ deh_location(de_head
);
851 char tmp
= *name_end
;
852 if ((deh_state(de_head
) & DEH_Visible
))
855 /* Directory names in ReiserFS are not null
856 * terminated. We write a temporary 0 behind it.
857 * NOTE: that this may overwrite the first block in
858 * the tree cache. That doesn't hurt as long as we
859 * don't call next_key () in between.
862 cmp
= substring (dirname
, filename
);
865 if (do_possibilities
)
870 struct fsys_reiser_info info_save
;
872 if (print_possibilities
> 0)
873 print_possibilities
= -print_possibilities
;
875 strcpy(fn
, filename
);
878 /* If NAME is "." or "..", do not count it. */
879 if (strcmp (fn
, ".") != 0 && strcmp (fn
, "..") != 0) {
880 memcpy(&info_save
, INFO
, sizeof(struct fsys_reiser_info
));
881 search_stat (deh_dir_id(de_head
), deh_objectid(de_head
));
882 sd_print_item(INFO
->current_ih
, INFO
->current_item
);
884 search_stat (dir_id
, objectid
);
885 memcpy(INFO
, &info_save
, sizeof(struct fsys_reiser_info
));
890 # endif /* ! STAGE1_5 */
894 /* The beginning of this name marks the end of the next name.
903 if (print_possibilities
< 0)
905 # endif /* ! STAGE1_5 */
907 errnum
= ERR_FILE_NOT_FOUND
;
915 parent_dir_id
= dir_id
;
916 parent_objectid
= objectid
;
917 dir_id
= deh_dir_id(de_head
);
918 objectid
= deh_objectid(de_head
);
923 * U-Boot interface functions
927 * List given directory
929 * RETURN: 0 - OK, else grub_error_t errnum
932 reiserfs_ls (char *dirname
)
938 dir_slash
= malloc(strlen(dirname
) + 1);
939 if (dir_slash
== NULL
) {
940 return ERR_NUMBER_OVERFLOW
;
942 strcpy(dir_slash
, dirname
);
943 /* add "/" to the directory name */
944 strcat(dir_slash
, "/");
946 print_possibilities
= 1;
947 res
= reiserfs_dir (dir_slash
);
949 if (!res
|| errnum
) {
957 * Open file for reading
959 * RETURN: >0 - OK, size of opened file
960 * <0 - ERROR -grub_error_t errnum
963 reiserfs_open (char *filename
)
967 print_possibilities
= 0;
968 if (!reiserfs_dir (filename
) || errnum
) {