static int reiserfs_find_entry (struct inode * dir, const char * name, int namelen, struct path * path_to_entry, struct reiserfs_dir_entry * de) { struct key key_to_search; int repeat; int retval; if (!dir || !dir->i_sb) return POSITION_NOT_FOUND; if ((unsigned int)namelen > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize)) return POSITION_NOT_FOUND; /* there are no entries having the same third component of key, so fourth key component is not used */ copy_key (&key_to_search, INODE_PKEY (dir)); key_to_search.k_offset = get_third_component (name, namelen); key_to_search.k_uniqueness = DIRENTRY_UNIQUENESS; while (1) { /* search for a directory item using the formed key */ if (search_by_key (dir->i_sb, &key_to_search, path_to_entry, &repeat, DISK_LEAF_NODE_LEVEL, READ_BLOCKS) == ITEM_NOT_FOUND) { /* take previous item */ #ifdef REISERFS_CHECK if (!PATH_LAST_POSITION (path_to_entry)) reiserfs_panic (dir->i_sb, "vs-7010: reiserfs_find_entry: search_by_key returned bad position == 0"); #endif /* REISERFS_CHECK */ PATH_LAST_POSITION (path_to_entry) --; } de->de_bh = PATH_PLAST_BUFFER (path_to_entry); de->de_item_num = PATH_LAST_POSITION (path_to_entry); de->de_ih = B_N_PITEM_HEAD (de->de_bh, de->de_item_num); de->de_deh = B_I_DEH (de->de_bh, de->de_ih); #ifdef REISERFS_CHECK if (!I_IS_DIRECTORY_ITEM (de->de_ih) || COMP_SHORT_KEYS (&(de->de_ih->ih_key), INODE_PKEY (dir))) reiserfs_panic (dir->i_sb, "vs-7020: reiserfs_find_entry: item must be an item of the same directory item as inode"); #endif /* REISERFS_CHECK */ /* we do not check whether bin_search_in_dir_item found the given key, even if so, we still have to compare names */ bin_search_in_dir_item (de->de_ih, de->de_deh, &key_to_search, &(de->de_entry_num)); /* compare names for all entries having given hash value */ retval = linear_search_in_dir_item (&key_to_search, de, name, namelen); if (retval != GOTO_PREVIOUS_ITEM) /* there is no need to scan directory anymore. Given entry found or does not exist */ return retval; /* there is left neighboring item of this directory and given entry can be there */ key_to_search.k_offset = de->de_ih->ih_key.k_offset - 1; pathrelse (path_to_entry); } /* while (1) */ }
/* * May return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND * FIXME: should add something like IOERROR */ static int reiserfs_find_entry(struct reiserfs_node *dp, const char *name, int namelen, struct path * path_to_entry, struct reiserfs_dir_entry *de) { struct cpu_key key_to_search; int retval; if (namelen > REISERFS_MAX_NAME(dp->i_reiserfs->s_blocksize)) return NAME_NOT_FOUND; /* We will search for this key in the tree */ make_cpu_key(&key_to_search, dp, get_third_component(dp->i_reiserfs, name, namelen), TYPE_DIRENTRY, 3); while (1) { reiserfs_log(LOG_DEBUG, "search by entry key\n"); retval = search_by_entry_key(dp->i_reiserfs, &key_to_search, path_to_entry, de); if (retval == IO_ERROR) { reiserfs_log(LOG_DEBUG, "IO error in %s\n", __FUNCTION__); return IO_ERROR; } /* Compare names for all entries having given hash value */ reiserfs_log(LOG_DEBUG, "linear search for `%s'\n", name); retval = linear_search_in_dir_item(&key_to_search, de, name, namelen); if (retval != GOTO_PREVIOUS_ITEM) { /* * There is no need to scan directory anymore. * Given entry found or does not exist */ reiserfs_log(LOG_DEBUG, "linear search returned " "(objectid=%d,dirid=%d)\n", de->de_objectid, de->de_dir_id); path_to_entry->pos_in_item = de->de_entry_num; return retval; } /* * There is left neighboring item of this directory and * given entry can be there */ set_cpu_key_k_offset(&key_to_search, le_ih_k_offset(de->de_ih) - 1); pathrelse(path_to_entry); } /* while (1) */ }
/* * may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND * FIXME: should add something like IOERROR */ static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen, struct treepath *path_to_entry, struct reiserfs_dir_entry *de) { struct cpu_key key_to_search; int retval; if (namelen > REISERFS_MAX_NAME(dir->i_sb->s_blocksize)) return NAME_NOT_FOUND; /* we will search for this key in the tree */ make_cpu_key(&key_to_search, dir, get_third_component(dir->i_sb, name, namelen), TYPE_DIRENTRY, 3); while (1) { retval = search_by_entry_key(dir->i_sb, &key_to_search, path_to_entry, de); if (retval == IO_ERROR) { reiserfs_error(dir->i_sb, "zam-7001", "io error"); return IO_ERROR; } /* compare names for all entries having given hash value */ retval = linear_search_in_dir_item(&key_to_search, de, name, namelen); /* * there is no need to scan directory anymore. * Given entry found or does not exist */ if (retval != GOTO_PREVIOUS_ITEM) { path_to_entry->pos_in_item = de->de_entry_num; return retval; } /* * there is left neighboring item of this directory * and given entry can be there */ set_cpu_key_k_offset(&key_to_search, le_ih_k_offset(de->de_ih) - 1); pathrelse(path_to_entry); } /* while (1) */ }