2 * fs_reiserfs.c - an implementation for the Reiser filesystem
4 * Copyright (C) 2001 Jeffrey Mahoney (jeffm@suse.com)
8 * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include "reiserfs/reiserfs.h"
35 /* Exported in struct fs_t */
36 static int reiserfs_open( struct boot_file_t *file, struct partition_t *part,
37 struct boot_fspec_t *fspec);
38 static int reiserfs_read( struct boot_file_t *file, unsigned int size,
41 static int reiserfs_seek( struct boot_file_t *file, unsigned int newpos );
42 static int reiserfs_close( struct boot_file_t *file );
44 struct fs_t reiserfs_filesystem = {
52 static int reiserfs_read_super( void );
53 static int reiserfs_open_file( char *dirname );
54 static int reiserfs_read_data( char *buf, __u32 len );
57 static struct reiserfs_state reiserfs;
58 static struct reiserfs_state *INFO = &reiserfs;
60 /* Adapted from GRUB: */
61 static char FSYS_BUF[FSYSREISER_CACHE_SIZE];
66 reiserfs_open( struct boot_file_t *file, struct partition_t *part,
67 struct boot_fspec_t *fspec)
69 static char buffer[1024];
70 char *dev_name = fspec->dev;
71 char *file_name = fspec->file;
76 memset( INFO, 0, sizeof(struct reiserfs_state) );
81 DEBUG_F( "Determining offset for partition %d\n", part->part_number );
82 INFO->partition_offset = ((uint64_t)part->part_start) * part->blocksize;
83 DEBUG_F( "%Lu = %lu * %hu\n", INFO->partition_offset,
88 INFO->partition_offset = 0;
90 strncpy(buffer, dev_name, 1020);
91 if (_machine != _MACH_bplan)
92 strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */
94 file->of_device = prom_open( buffer );
95 DEBUG_F( "Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
96 buffer, file_name, INFO->partition_offset );
98 if ( file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL )
100 DEBUG_F( "Can't open device %p\n", file->of_device );
101 DEBUG_LEAVE(FILE_ERR_BADDEV);
102 return FILE_ERR_BADDEV;
105 DEBUG_F("%p was successfully opened\n", file->of_device);
107 if ( reiserfs_read_super() != 1 )
109 DEBUG_F( "Couldn't open ReiserFS @ %s/%Lu\n", buffer, INFO->partition_offset );
110 prom_close( file->of_device );
111 DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
112 return FILE_ERR_BAD_FSYS;
115 DEBUG_F( "Attempting to open %s\n", file_name );
116 strcpy(buffer, file_name); /* reiserfs_open_file modifies argument */
117 if (reiserfs_open_file(buffer) == 0)
119 DEBUG_F( "reiserfs_open_file failed. errnum = %d\n", errnum );
120 prom_close( file->of_device );
121 DEBUG_LEAVE_F(errnum);
125 DEBUG_F( "Successfully opened %s\n", file_name );
127 DEBUG_LEAVE(FILE_ERR_OK);
133 reiserfs_read( struct boot_file_t *file, unsigned int size, void *buffer )
135 return reiserfs_read_data( buffer, size );
139 reiserfs_seek( struct boot_file_t *file, unsigned int newpos )
146 reiserfs_close( struct boot_file_t *file )
148 if( file->of_device )
150 prom_close(file->of_device);
152 DEBUG_F("reiserfs_close called\n");
158 static __inline__ __u32
159 reiserfs_log2( __u32 word )
162 while( word && (word & (1 << ++i)) == 0 );
166 static __inline__ int
167 is_power_of_two( unsigned long word )
169 return ( word & -word ) == word;
173 read_disk_block( struct boot_file_t *file, __u32 block, __u32 start,
174 __u32 length, void *buf )
176 __u16 fs_blocksize = INFO->blocksize == 0 ? REISERFS_OLD_BLOCKSIZE
178 unsigned long long pos = (unsigned long long)block * (unsigned long long)fs_blocksize;
179 pos += (unsigned long long)INFO->partition_offset + (unsigned long long)start;
180 DEBUG_F( "Reading %u bytes, starting at block %u, disk offset %Lu\n",
181 length, block, pos );
182 if (!prom_lseek( file->of_device, pos )) {
183 DEBUG_F("prom_lseek failed\n");
186 return prom_read( file->of_device, buf, length );
191 journal_read( __u32 block, __u32 len, char *buffer )
193 return read_disk_block( INFO->file,
194 (INFO->journal_block + block), 0,
198 /* Read a block from ReiserFS file system, taking the journal into
199 * account. If the block nr is in the journal, the block from the
203 block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
205 __u32 transactions = INFO->journal_transactions;
206 __u32 desc_block = INFO->journal_first_desc;
207 __u32 journal_mask = INFO->journal_block_count - 1;
208 __u32 translatedNr = blockNr;
209 __u32 *journal_table = JOURNAL_START;
211 // DEBUG_F( "block_read( %u, %u, %u, ..)\n", blockNr, start, len );
213 while ( transactions-- > 0 )
218 if ( *journal_table != 0xffffffff )
220 /* Search for the blockNr in cached journal */
221 j_len = le32_to_cpu((*journal_table)++);
222 while ( i++ < j_len )
224 if ( le32_to_cpu(*journal_table++) == blockNr )
226 journal_table += j_len - i;
233 /* This is the end of cached journal marker. The remaining
234 * transactions are still on disk. */
235 struct reiserfs_journal_desc desc;
236 struct reiserfs_journal_commit commit;
238 if ( !journal_read( desc_block, sizeof(desc), (char *) &desc ) )
241 j_len = le32_to_cpu(desc.j_len);
242 while ( i < j_len && i < JOURNAL_TRANS_HALF )
243 if ( le32_to_cpu(desc.j_realblock[i++]) == blockNr )
246 if ( j_len >= JOURNAL_TRANS_HALF )
248 int commit_block = ( desc_block + 1 + j_len ) & journal_mask;
250 if ( !journal_read( commit_block,
251 sizeof(commit), (char *) &commit ) )
255 if ( le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr )
263 INFO->journal_block + ( ( desc_block + i ) & journal_mask );
265 DEBUG_F( "block_read: block %u is mapped to journal block %u.\n",
266 blockNr, translatedNr - INFO->journal_block );
268 /* We must continue the search, as this block may be overwritten in
269 * later transactions. */
271 desc_block = (desc_block + 2 + j_len) & journal_mask;
274 return read_disk_block( INFO->file, translatedNr, start, len, buffer );
277 /* Init the journal data structure. We try to cache as much as
278 * possible in the JOURNAL_START-JOURNAL_END space, but if it is full
279 * we can still read the rest from the disk on demand.
281 * The first number of valid transactions and the descriptor block of the
282 * first valid transaction are held in INFO. The transactions are all
283 * adjacent, but we must take care of the journal wrap around.
288 struct reiserfs_journal_header header;
289 struct reiserfs_journal_desc desc;
290 struct reiserfs_journal_commit commit;
291 __u32 block_count = INFO->journal_block_count;
295 __u32 *journal_table = JOURNAL_START;
297 journal_read( block_count, sizeof ( header ), ( char * ) &header );
298 desc_block = le32_to_cpu(header.j_first_unflushed_offset);
299 if ( desc_block >= block_count )
302 INFO->journal_transactions = 0;
303 INFO->journal_first_desc = desc_block;
304 next_trans_id = le32_to_cpu(header.j_last_flush_trans_id) + 1;
306 DEBUG_F( "journal_init: last flushed %u\n", le32_to_cpu(header.j_last_flush_trans_id) );
310 journal_read( desc_block, sizeof(desc), (char *) &desc );
311 if ( strcmp( JOURNAL_DESC_MAGIC, desc.j_magic ) != 0
312 || desc.j_trans_id != next_trans_id
313 || desc.j_mount_id != header.j_mount_id )
314 /* no more valid transactions */
317 commit_block = ( desc_block + le32_to_cpu(desc.j_len) + 1 ) & ( block_count - 1 );
318 journal_read( commit_block, sizeof(commit), (char *) &commit );
319 if ( desc.j_trans_id != commit.j_trans_id
320 || desc.j_len != commit.j_len )
321 /* no more valid transactions */
325 DEBUG_F( "Found valid transaction %u/%u at %u.\n",
326 le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
331 if ( journal_table < JOURNAL_END )
333 if ( ( journal_table + 1 + le32_to_cpu(desc.j_len) ) >= JOURNAL_END )
335 /* The table is almost full; mark the end of the cached * *
337 *journal_table = 0xffffffff;
338 journal_table = JOURNAL_END;
344 /* Cache the length and the realblock numbers in the table. *
345 * The block number of descriptor can easily be computed. *
346 * and need not to be stored here. */
347 *journal_table++ = desc.j_len;
348 for ( i = 0; i < le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++ )
350 *journal_table++ = desc.j_realblock[i];
352 DEBUG_F( "block %u is in journal %u.\n",
353 le32_to_cpu(desc.j_realblock[i]), desc_block );
356 for ( ; i < le32_to_cpu(desc.j_len); i++ )
359 commit.j_realblock[i - JOURNAL_TRANS_HALF];
361 DEBUG_F( "block %u is in journal %u.\n",
362 le32_to_cpu(commit.j_realblock[i - JOURNAL_TRANS_HALF]),
368 desc_block = (commit_block + 1) & (block_count - 1);
371 DEBUG_F( "Transaction %u/%u at %u isn't valid.\n",
372 le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
376 INFO->journal_transactions
377 = next_trans_id - le32_to_cpu(header.j_last_flush_trans_id) - 1;
378 return (errnum == 0);
381 /* check filesystem types and read superblock into memory buffer */
383 reiserfs_read_super( void )
385 struct reiserfs_super_block super;
386 __u64 superblock = REISERFS_SUPERBLOCK_BLOCK;
388 if (read_disk_block(INFO->file, superblock, 0, sizeof(super), &super) != sizeof(super)) {
389 DEBUG_F("read_disk_block failed!\n");
393 DEBUG_F( "Found super->magic: \"%s\"\n", super.s_magic );
395 if( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
396 strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
398 /* Try old super block position */
399 superblock = REISERFS_OLD_SUPERBLOCK_BLOCK;
401 if (read_disk_block( INFO->file, superblock, 0, sizeof (super), &super ) != sizeof(super)) {
402 DEBUG_F("read_disk_block failed!\n");
406 if ( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
407 strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
409 /* pre journaling super block - untested */
410 if ( strcmp( REISERFS_SUPER_MAGIC_STRING,
411 (char *) ((__u32) &super + 20 ) ) != 0 )
414 super.s_blocksize = cpu_to_le16(REISERFS_OLD_BLOCKSIZE);
415 super.s_journal_block = 0;
420 DEBUG_F( "ReiserFS superblock data:\n" );
421 DEBUG_F( "Block count: %u\n", le32_to_cpu(super.s_block_count) )
422 DEBUG_F( "Free blocks: %u\n", le32_to_cpu(super.s_free_blocks) );
423 DEBUG_F( "Journal block: %u\n", le32_to_cpu(super.s_journal_block) );
424 DEBUG_F( "Journal size (in blocks): %u\n",
425 le32_to_cpu(super.s_orig_journal_size) );
426 DEBUG_F( "Root block: %u\n\n", le32_to_cpu(super.s_root_block) );
429 INFO->version = le16_to_cpu(super.s_version);
430 INFO->blocksize = le16_to_cpu(super.s_blocksize);
431 INFO->blocksize_shift = reiserfs_log2( INFO->blocksize );
433 INFO->journal_block = le32_to_cpu(super.s_journal_block);
434 INFO->journal_block_count = le32_to_cpu(super.s_orig_journal_size);
436 INFO->cached_slots = (FSYSREISER_CACHE_SIZE >> INFO->blocksize_shift) - 1;
438 /* At this point, we've found a valid superblock. If we run into problems
439 * mounting the FS, the user should probably know. */
441 /* A few sanity checks ... */
442 if ( INFO->version > REISERFS_MAX_SUPPORTED_VERSION )
444 prom_printf( "ReiserFS: Unsupported version field: %u\n",
449 if ( INFO->blocksize < FSYSREISER_MIN_BLOCKSIZE
450 || INFO->blocksize > FSYSREISER_MAX_BLOCKSIZE )
452 prom_printf( "ReiserFS: Unsupported block size: %u\n",
457 /* Setup the journal.. */
458 if ( INFO->journal_block != 0 )
460 if ( !is_power_of_two( INFO->journal_block_count ) )
462 prom_printf( "ReiserFS: Unsupported journal size, "
463 "not a power of 2: %u\n",
464 INFO->journal_block_count );
469 /* Read in super block again, maybe it is in the journal */
470 block_read( superblock, 0, sizeof (struct reiserfs_super_block),
474 /* Read in the root block */
475 if ( !block_read( le32_to_cpu(super.s_root_block), 0,
476 INFO->blocksize, ROOT ) )
478 prom_printf( "ReiserFS: Failed to read in root block\n" );
482 /* The root node is always the "deepest", so we can
483 determine the hieght of the tree using it. */
484 INFO->tree_depth = blkh_level(BLOCKHEAD(ROOT));
487 DEBUG_F( "root read_in: block=%u, depth=%u\n",
488 le32_to_cpu(super.s_root_block), INFO->tree_depth );
490 if ( INFO->tree_depth >= REISERFS_MAX_TREE_HEIGHT )
492 prom_printf( "ReiserFS: Unsupported tree depth (too deep): %u\n",
497 if ( INFO->tree_depth == BLKH_LEVEL_LEAF )
499 /* There is only one node in the whole filesystem, which is
500 simultanously leaf and root */
501 memcpy( LEAF, ROOT, INFO->blocksize );
506 /***************** TREE ACCESSING METHODS *****************************/
508 /* I assume you are familiar with the ReiserFS tree, if not go to
509 * http://devlinux.com/projects/reiserfs/
511 * My tree node cache is organized as following
513 * 1 LEAF node (if the ROOT is also a LEAF it is copied here
514 * 2-n other nodes on current path from bottom to top.
515 * if there is not enough space in the cache, the top most are
518 * I have only two methods to find a key in the tree:
519 * search_stat(dir_id, objectid) searches for the stat entry (always
520 * the first entry) of an object.
521 * next_key() gets the next key in tree order.
523 * This means, that I can only sequential reads of files are
524 * efficient, but this really doesn't hurt for grub.
527 /* Read in the node at the current path and depth into the node cache.
528 * You must set INFO->blocks[depth] before.
531 read_tree_node( __u32 blockNr, __u16 depth )
533 char *cache = CACHE(depth);
534 int num_cached = INFO->cached_slots;
537 if ( depth < num_cached )
539 /* This is the cached part of the path.
540 Check if same block is needed. */
541 if ( blockNr == INFO->blocks[depth] )
545 cache = CACHE(num_cached);
547 DEBUG_F( " next read_in: block=%u (depth=%u)\n", blockNr, depth );
549 if ( !block_read( blockNr, 0, INFO->blocksize, cache ) )
551 DEBUG_F( "block_read failed\n" );
555 DEBUG_F( "FOUND: blk_level=%u, blk_nr_item=%u, blk_free_space=%u\n",
556 blkh_level(BLOCKHEAD(cache)),
557 blkh_nr_item(BLOCKHEAD(cache)),
558 le16_to_cpu(BLOCKHEAD(cache)->blk_free_space) );
560 /* Make sure it has the right node level */
561 if ( blkh_level(BLOCKHEAD(cache)) != depth )
563 DEBUG_F( "depth = %u != %u\n", blkh_level(BLOCKHEAD(cache)), depth );
564 DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
565 errnum = FILE_ERR_BAD_FSYS;
569 INFO->blocks[depth] = blockNr;
573 /* Get the next key, i.e. the key following the last retrieved key in
574 * tree order. INFO->current_ih and
575 * INFO->current_info are adapted accordingly. */
580 struct item_head *ih = INFO->current_ih + 1;
584 DEBUG_F( "next_key:\n old ih: key %u:%u:%u:%u version:%u\n",
585 le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
586 le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
587 le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
588 le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
589 ih_version(INFO->current_ih) );
592 if ( ih == &ITEMHEAD[blkh_nr_item(BLOCKHEAD( LEAF ))] )
594 depth = BLKH_LEVEL_LEAF;
595 /* The last item, was the last in the leaf node. * Read in the next
599 if ( depth == INFO->tree_depth )
601 /* There are no more keys at all. * Return a dummy item with
604 ( struct item_head * )
605 &BLOCKHEAD( LEAF )->blk_right_delim_key;
610 DEBUG_F( " depth=%u, i=%u\n", depth, INFO->next_key_nr[depth] );
613 while ( INFO->next_key_nr[depth] == 0 );
615 if ( depth == INFO->tree_depth )
617 else if ( depth <= INFO->cached_slots )
618 cache = CACHE( depth );
621 /* Save depth as using it twice as args to read_tree_node()
622 * has undefined behaviour */
624 cache = read_tree_node( INFO->blocks[d], --depth );
631 __u16 nr_item = blkh_nr_item(BLOCKHEAD( cache ));
632 int key_nr = INFO->next_key_nr[depth]++;
635 DEBUG_F( " depth=%u, i=%u/%u\n", depth, key_nr, nr_item );
637 if ( key_nr == nr_item )
638 /* This is the last item in this block, set the next_key_nr *
640 INFO->next_key_nr[depth] = 0;
643 read_tree_node( dc_block_number( &(DC( cache )[key_nr])),
648 while ( depth > BLKH_LEVEL_LEAF );
653 INFO->current_ih = ih;
654 INFO->current_item = &LEAF[ih_location(ih)];
656 DEBUG_F( " new ih: key %u:%u:%u:%u version:%u\n",
657 le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
658 le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
659 le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
660 le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
661 ih_version(INFO->current_ih) );
666 /* preconditions: reiserfs_read_super already executed, therefore
667 * INFO block is valid
668 * returns: 0 if error (errnum is set),
669 * nonzero iff we were able to find the key successfully.
670 * postconditions: on a nonzero return, the current_ih and
671 * current_item fields describe the key that equals the
672 * searched key. INFO->next_key contains the next key after
674 * side effects: messes around with the cache.
677 search_stat( __u32 dir_id, __u32 objectid )
683 struct item_head *ih;
686 DEBUG_F( "search_stat:\n key %u:%u:0:0\n", le32_to_cpu(dir_id),
687 le32_to_cpu(objectid) );
690 depth = INFO->tree_depth;
693 DEBUG_F( "depth = %d\n", depth );
694 while ( depth > BLKH_LEVEL_LEAF )
698 nr_item = blkh_nr_item(BLOCKHEAD( cache ));
702 for ( i = 0; i < nr_item; i++ )
704 if (le32_to_cpu(key->k_dir_id) > le32_to_cpu(dir_id)
705 || (key->k_dir_id == dir_id
706 && (le32_to_cpu(key->k_objectid) > le32_to_cpu(objectid)
707 || (key->k_objectid == objectid
708 && (key->u.k_offset_v1.k_offset
709 | key->u.k_offset_v1.k_uniqueness) > 0))))
715 DEBUG_F( " depth=%d, i=%d/%d\n", depth, i, nr_item );
717 INFO->next_key_nr[depth] = ( i == nr_item ) ? 0 : i + 1;
718 cache = read_tree_node( dc_block_number(&(DC(cache)[i])), --depth );
724 nr_item = blkh_nr_item(BLOCKHEAD(LEAF));
726 DEBUG_F( "nr_item = %d\n", nr_item );
727 for ( i = 0; i < nr_item; i++ )
729 if ( ih->ih_key.k_dir_id == dir_id
730 && ih->ih_key.k_objectid == objectid
731 && ih->ih_key.u.k_offset_v1.k_offset == 0
732 && ih->ih_key.u.k_offset_v1.k_uniqueness == 0 )
735 DEBUG_F( " depth=%d, i=%d/%d\n", depth, i, nr_item );
737 INFO->current_ih = ih;
738 INFO->current_item = &LEAF[ih_location(ih)];
746 DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
747 errnum = FILE_ERR_BAD_FSYS;
752 reiserfs_read_data( char *buf, __u32 len )
757 char *prev_buf = buf;
760 DEBUG_F( "reiserfs_read_data: INFO->file->pos=%Lu len=%u, offset=%Lu\n",
761 INFO->file->pos, len, (__u64) IH_KEY_OFFSET(INFO->current_ih) - 1 );
764 if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
765 || IH_KEY_OFFSET( INFO->current_ih ) > INFO->file->pos + 1 )
767 search_stat( INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid );
771 while ( errnum == 0 )
773 if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid )
776 offset = INFO->file->pos - IH_KEY_OFFSET( INFO->current_ih ) + 1;
777 blocksize = ih_item_len(INFO->current_ih);
780 DEBUG_F( " loop: INFO->file->pos=%Lu len=%u, offset=%u blocksize=%u\n",
781 INFO->file->pos, len, offset, blocksize );
784 if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_DIRECT )
785 && offset < blocksize )
787 to_read = blocksize - offset;
791 memcpy( buf, INFO->current_item + offset, to_read );
794 else if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_INDIRECT ) )
796 blocksize = ( blocksize >> 2 ) << INFO->blocksize_shift;
798 while ( offset < blocksize )
800 __u32 blocknr = le32_to_cpu(((__u32 *)
801 INFO->current_item)[offset >> INFO->blocksize_shift]);
803 int blk_offset = offset & (INFO->blocksize - 1);
805 to_read = INFO->blocksize - blk_offset;
809 /* Journal is only for meta data.
810 Data blocks can be read directly without using block_read */
811 read_disk_block( INFO->file, blocknr, blk_offset, to_read,
818 INFO->file->pos += to_read;
827 return (errnum != 0) ? 0 : buf - prev_buf;
831 /* preconditions: reiserfs_read_super already executed, therefore
832 * INFO block is valid
833 * returns: 0 if error, nonzero iff we were able to find the file successfully
834 * postconditions: on a nonzero return, INFO->fileinfo contains the info
835 * of the file we were trying to look up, filepos is 0 and filemax is
836 * the size of the file.
839 reiserfs_open_file( char *dirname )
841 struct reiserfs_de_head *de_head;
843 __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
845 char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
850 dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
851 objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
856 DEBUG_F( "dirname=%s\n", dirname );
858 /* Search for the stat info first. */
859 if ( !search_stat( dir_id, objectid ) )
863 DEBUG_F( "sd_mode=0%o sd_size=%Lu\n",
864 sd_mode((struct stat_data *) INFO->current_item ),
865 sd_size(INFO->current_ih, INFO->current_item ));
868 mode = sd_mode((struct stat_data *)INFO->current_item);
870 /* If we've got a symbolic link, then chase it. */
871 if ( S_ISLNK( mode ) )
875 DEBUG_F("link count = %d\n", link_count);
877 if ( ++link_count > MAX_LINK_COUNT )
879 DEBUG_F("Symlink loop\n");
880 errnum = FILE_ERR_SYMLINK_LOOP;
884 /* Get the symlink size. */
885 INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
887 /* Find out how long our remaining name is. */
888 while ( dirname[len] && !isspace( dirname[len] ) )
891 if ( INFO->file->len + len > sizeof ( linkbuf ) - 1 )
893 errnum = FILE_ERR_LENGTH;
897 /* Copy the remaining name to the end of the symlink data. Note *
898 * that DIRNAME and LINKBUF may overlap! */
899 memmove( linkbuf + INFO->file->len, dirname, len + 1 );
901 INFO->fileinfo.k_dir_id = dir_id;
902 INFO->fileinfo.k_objectid = objectid;
905 || reiserfs_read_data( linkbuf, INFO->file->len ) != INFO->file->len ) {
906 DEBUG_F("reiserfs_open_file - if !next_key || reiserfs_read_data\n");
913 DEBUG_F( "symlink=%s\n", linkbuf );
917 if ( *dirname == '/' )
919 /* It's an absolute link, so look it up in root. */
920 dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
921 objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
925 /* Relative, so look it up in our parent directory. */
926 dir_id = parent_dir_id;
927 objectid = parent_objectid;
930 /* Now lookup the new name. */
934 /* if we have a real file (and we're not just printing *
935 * possibilities), then this is where we want to exit */
937 if ( !*dirname || isspace( *dirname ) )
939 if ( !S_ISREG( mode ) )
941 errnum = FILE_ERR_BAD_TYPE;
946 INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
948 INFO->fileinfo.k_dir_id = dir_id;
949 INFO->fileinfo.k_objectid = objectid;
953 /* continue with the file/directory name interpretation */
954 while ( *dirname == '/' )
956 if ( !S_ISDIR( mode ) )
958 errnum = FILE_ERR_NOTDIR;
961 for ( rest = dirname; ( ch = *rest ) && !isspace( ch ) && ch != '/';
973 if ( INFO->current_ih->ih_key.k_objectid != objectid )
976 name_end = INFO->current_item + ih_item_len(INFO->current_ih);
977 de_head = ( struct reiserfs_de_head * ) INFO->current_item;
978 num_entries = ih_entry_count(INFO->current_ih);
979 while ( num_entries > 0 )
981 char *filename = INFO->current_item + deh_location(de_head);
982 char tmp = *name_end;
984 if( deh_state(de_head) & (1 << DEH_Visible))
988 /* Directory names in ReiserFS are not null * terminated.
989 * We write a temporary 0 behind it. * NOTE: that this
990 * may overwrite the first block in * the tree cache.
991 * That doesn't hurt as long as we * don't call next_key
994 cmp = strcmp( dirname, filename );
999 /* The beginning of this name marks the end of the next name.
1001 name_end = filename;
1007 errnum = FILE_ERR_NOTFOUND;
1015 parent_dir_id = dir_id;
1016 parent_objectid = objectid;
1017 dir_id = de_head->deh_dir_id; /* LE */
1018 objectid = de_head->deh_objectid; /* LE */
1024 #ifndef __LITTLE_ENDIAN
1026 struct offset_v2 offset_v2;
1028 } offset_v2_esafe_overlay;
1031 offset_v2_k_type( struct offset_v2 *v2 )
1033 offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
1034 tmp.linear = le64_to_cpu( tmp.linear );
1035 return tmp.offset_v2.k_type;
1039 offset_v2_k_offset( struct offset_v2 *v2 )
1041 offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
1042 tmp.linear = le64_to_cpu( tmp.linear );
1043 return tmp.offset_v2.k_offset;
1048 uniqueness2type (__u32 uniqueness)
1050 switch (uniqueness) {
1051 case V1_SD_UNIQUENESS: return TYPE_STAT_DATA;
1052 case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT;
1053 case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
1054 case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
1061 * c-file-style: "k&r"