コード例 #1
0
ファイル: super.c プロジェクト: niubl/camera_project
// if root directory is empty - we set default - Yura's - hash and
// warn about it
// FIXME: we look for only one name in a directory. If tea and yura
// bith have the same value - we ask user to send report to the
// mailing list
__u32 find_hash_out (struct super_block * s)
{
    int retval;
    struct inode * inode;
    struct cpu_key key;
    INITIALIZE_PATH (path);
    struct reiserfs_dir_entry de;
    __u32 hash = DEFAULT_HASH;

    inode = s->s_root->d_inode;

    do { // Some serious "goto"-hater was there ;)
	u32 teahash, r5hash, yurahash;

	make_cpu_key (&key, inode, ~0, TYPE_DIRENTRY, 3);
	retval = search_by_entry_key (s, &key, &path, &de);
	if (retval == IO_ERROR) {
	    pathrelse (&path);
	    return UNSET_HASH ;
	}
	if (retval == NAME_NOT_FOUND)
	    de.de_entry_num --;
	set_de_name_and_namelen (&de);
	if (deh_offset( &(de.de_deh[de.de_entry_num]) ) == DOT_DOT_OFFSET) {
	    /* allow override in this case */
	    if (reiserfs_rupasov_hash(s)) {
		hash = YURA_HASH ;
	    }
	    reiserfs_warning("reiserfs: FS seems to be empty, autodetect "
	                     "is using the default hash\n");
	    break;
	}
	r5hash=GET_HASH_VALUE (r5_hash (de.de_name, de.de_namelen));
	teahash=GET_HASH_VALUE (keyed_hash (de.de_name, de.de_namelen));
	yurahash=GET_HASH_VALUE (yura_hash (de.de_name, de.de_namelen));
	if ( ( (teahash == r5hash) && (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash) ) ||
	     ( (teahash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ||
	     ( (r5hash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ) {
	    reiserfs_warning("reiserfs: Unable to automatically detect hash"
		"function for device %s\n"
		"please mount with -o hash={tea,rupasov,r5}\n", kdevname (s->s_dev));
	    hash = UNSET_HASH;
	    break;
	}
	if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == yurahash)
	    hash = YURA_HASH;
	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == teahash)
	    hash = TEA_HASH;
	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == r5hash)
	    hash = R5_HASH;
	else {
	    reiserfs_warning("reiserfs: Unrecognised hash function for "
			     "device %s\n", kdevname (s->s_dev));
	    hash = UNSET_HASH;
	}
    } while (0);

    pathrelse (&path);
    return hash;
}
コード例 #2
0
ファイル: namei.c プロジェクト: AlexShiLucky/linux
/* The function is NOT SCHEDULE-SAFE! */
int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
			struct treepath *path, struct reiserfs_dir_entry *de)
{
	int retval;

	retval = search_item(sb, key, path);
	switch (retval) {
	case ITEM_NOT_FOUND:
		if (!PATH_LAST_POSITION(path)) {
			reiserfs_error(sb, "vs-7000", "search_by_key "
				       "returned item position == 0");
			pathrelse(path);
			return IO_ERROR;
		}
		PATH_LAST_POSITION(path)--;

	case ITEM_FOUND:
		break;

	case IO_ERROR:
		return retval;

	default:
		pathrelse(path);
		reiserfs_error(sb, "vs-7002", "no path to here");
		return IO_ERROR;
	}

	set_de_item_location(de, path);

#ifdef CONFIG_REISERFS_CHECK
	if (!is_direntry_le_ih(de->de_ih) ||
	    COMP_SHORT_KEYS(&de->de_ih->ih_key, key)) {
		print_block(de->de_bh, 0, -1, -1);
		reiserfs_panic(sb, "vs-7005", "found item %h is not directory "
			       "item or does not belong to the same directory "
			       "as key %K", de->de_ih, key);
	}
#endif				/* CONFIG_REISERFS_CHECK */

	/*
	 * binary search in directory item by third component of the
	 * key. sets de->de_entry_num of de
	 */
	retval = bin_search_in_dir_item(de, cpu_key_k_offset(key));
	path->pos_in_item = de->de_entry_num;
	if (retval != NAME_NOT_FOUND) {
		/*
		 * ugly, but rename needs de_bh, de_deh, de_name,
		 * de_namelen, de_objectid set
		 */
		set_de_name_and_namelen(de);
		set_de_object_key(de);
	}
	return retval;
}
コード例 #3
0
/*
 * We assign a key to each directory item, and place multiple entries in
 * a single directory item. A directory item has a key equal to the key
 * of the first directory entry in it.
 *
 * This function first calls search_by_key, then, if item whose first
 * entry matches is not found it looks for the entry inside directory
 * item found by search_by_key. Fills the path to the entry, and to the
 * entry position in the item
 */
int
search_by_entry_key(struct reiserfs_sb_info *sbi,
    const struct cpu_key *key, struct path *path,
    struct reiserfs_dir_entry *de)
{
	int retval;

	reiserfs_log(LOG_DEBUG, "searching in (objectid=%d,dirid=%d)\n",
	    key->on_disk_key.k_objectid, key->on_disk_key.k_dir_id);
	retval = search_item(sbi, key, path);
	switch (retval) {
	case ITEM_NOT_FOUND:
		if (!PATH_LAST_POSITION(path)) {
			reiserfs_log(LOG_DEBUG,
			    "search_by_key returned item position == 0");
			pathrelse(path);
			return (IO_ERROR);
		}
		PATH_LAST_POSITION(path)--;
		reiserfs_log(LOG_DEBUG, "search_by_key did not found it\n");
		break;
	case ITEM_FOUND:
		reiserfs_log(LOG_DEBUG, "search_by_key found it\n");
		break;
	case IO_ERROR:
		return (retval);
	default:
		pathrelse(path);
		reiserfs_log(LOG_DEBUG, "no path to here");
		return (IO_ERROR);
	}

	reiserfs_log(LOG_DEBUG, "set item location\n");
	set_de_item_location(de, path);

	/*
	 * Binary search in directory item by third component of the
	 * key. Sets de->de_entry_num of de
	 */
	reiserfs_log(LOG_DEBUG, "bin_search_in_dir_item\n");
	retval = bin_search_in_dir_item(de, cpu_key_k_offset(key));
	path->pos_in_item = de->de_entry_num;
	if (retval != NAME_NOT_FOUND) {
		/*
		 * Ugly, but rename needs de_bp, de_deh, de_name, de_namelen,
		 * de_objectid set
		 */
		set_de_name_and_namelen(de);
		set_de_object_key(de);
		reiserfs_log(LOG_DEBUG, "set (objectid=%d,dirid=%d)\n",
		    de->de_objectid, de->de_dir_id);
	}

	return (retval);
}
コード例 #4
0
ファイル: namei.c プロジェクト: OpenHMR/Open-HMR600
// de contains information pointing to an entry which 
static int de_still_valid (const char * name, int len, struct reiserfs_dir_entry * de)
{
    struct reiserfs_dir_entry tmp = *de;
    
    // recalculate pointer to name and name length
    set_de_name_and_namelen (&tmp);
    // FIXME: could check more
    if (tmp.de_namelen != len || memcmp (name, de->de_name, len))
	return 0;
    return 1;
}
コード例 #5
0
// if root directory is empty - we set default - Yura's - hash and
// warn about it
// FIXME: we look for only one name in a directory. If tea and yura
// bith have the same value - we ask user to send report to the
// mailing list
__u32 find_hash_out (struct super_block * s)
{
    int retval;
    struct inode * inode;
    struct cpu_key key;
    INITIALIZE_PATH (path);
    struct reiserfs_dir_entry de;
    __u32 hash = DEFAULT_HASH;

    inode = s->s_root->d_inode;

    while (1) {
	make_cpu_key (&key, inode, ~0, TYPE_DIRENTRY, 3);
	retval = search_by_entry_key (s, &key, &path, &de);
	if (retval == IO_ERROR) {
	    pathrelse (&path);
	    return UNSET_HASH ;
	}
	if (retval == NAME_NOT_FOUND)
	    de.de_entry_num --;
	set_de_name_and_namelen (&de);
	if (deh_offset( &(de.de_deh[de.de_entry_num]) ) == DOT_DOT_OFFSET) {
	    /* allow override in this case */
	    if (reiserfs_rupasov_hash(s)) {
		hash = YURA_HASH ;
	    }
	    reiserfs_warning("reiserfs: FS seems to be empty, autodetect "
	                     "is using the default hash\n");
	    break;
	}
	if (GET_HASH_VALUE(yura_hash (de.de_name, de.de_namelen)) == 
	    GET_HASH_VALUE(keyed_hash (de.de_name, de.de_namelen))) {
	    reiserfs_warning ("reiserfs: Could not detect hash function "
			      "please mount with -o hash={tea,rupasov,r5}\n") ;
	    hash = UNSET_HASH ;
	    break;
	}
	if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) ==
	    GET_HASH_VALUE (yura_hash (de.de_name, de.de_namelen)))
	    hash = YURA_HASH;
	else
	    hash = TEA_HASH;
	break;
    }

    pathrelse (&path);
    return hash;
}
コード例 #6
0
static int linear_search_in_dir_item(struct cpu_key *key,
				     struct reiserfs_dir_entry *de,
				     const char *name, int namelen)
{
	struct reiserfs_de_head *deh = de->de_deh;
	int retval;
	int i;

	i = de->de_entry_num;

	if (i == I_ENTRY_COUNT(de->de_ih) ||
	    GET_HASH_VALUE(deh_offset(deh + i)) !=
	    GET_HASH_VALUE(cpu_key_k_offset(key))) {
		i--;
	}

	RFALSE(de->de_deh != B_I_DEH(de->de_bh, de->de_ih),
	       "vs-7010: array of entry headers not found");

	deh += i;

	for (; i >= 0; i--, deh--) {
		if (GET_HASH_VALUE(deh_offset(deh)) !=
		    GET_HASH_VALUE(cpu_key_k_offset(key))) {
			// hash value does not match, no need to check whole name
			return NAME_NOT_FOUND;
		}

		/* mark, that this generation number is used */
		if (de->de_gen_number_bit_string)
			set_bit(GET_GENERATION_NUMBER(deh_offset(deh)),
				de->de_gen_number_bit_string);

		// calculate pointer to name and namelen
		de->de_entry_num = i;
		set_de_name_and_namelen(de);

		if ((retval =
		     reiserfs_match(de, name, namelen)) != NAME_NOT_FOUND) {
			// de's de_name, de_namelen, de_recordlen are set. Fill the rest:

			// key of pointed object
			set_de_object_key(de);

			store_de_entry_key(de);

			// retval can be NAME_FOUND or NAME_FOUND_INVISIBLE
			return retval;
		}
	}

	if (GET_GENERATION_NUMBER(le_ih_k_offset(de->de_ih)) == 0)
		/* we have reached left most entry in the node. In common we
		   have to go to the left neighbor, but if generation counter
		   is 0 already, we know for sure, that there is no name with
		   the same hash value */
		// FIXME: this work correctly only because hash value can not
		// be 0. Btw, in case of Yura's hash it is probably possible,
		// so, this is a bug
		return NAME_NOT_FOUND;

	RFALSE(de->de_item_num,
	       "vs-7015: two diritems of the same directory in one node?");

	return GOTO_PREVIOUS_ITEM;
}
コード例 #7
0
/*
 * de's de_bh, de_ih, de_deh, de_item_num, de_entry_num are set already
 * Used when hash collisions exist
 */
static int
linear_search_in_dir_item(struct cpu_key *key, struct reiserfs_dir_entry *de,
    const char *name, int namelen)
{
	int i;
	int retval;
	struct reiserfs_de_head * deh = de->de_deh;

	i = de->de_entry_num;

	if (i == I_ENTRY_COUNT(de->de_ih) ||
	    GET_HASH_VALUE(deh_offset(deh + i)) !=
	    GET_HASH_VALUE(cpu_key_k_offset(key))) {
		i--;
	}

	/*RFALSE( de->de_deh != B_I_DEH (de->de_bh, de->de_ih),
	  "vs-7010: array of entry headers not found");*/

	deh += i;

	for (; i >= 0; i--, deh--) {
		if (GET_HASH_VALUE(deh_offset(deh)) !=
		    GET_HASH_VALUE(cpu_key_k_offset(key))) {
			/*
			 * Hash value does not match, no need to check
			 * whole name
			 */
			reiserfs_log(LOG_DEBUG, "name `%s' not found\n", name);
			return (NAME_NOT_FOUND);
		}

		/* Mark that this generation number is used */
		if (de->de_gen_number_bit_string)
			set_bit(GET_GENERATION_NUMBER(deh_offset(deh)),
			    (unsigned long *)de->de_gen_number_bit_string);

		/* Calculate pointer to name and namelen */
		de->de_entry_num = i;
		set_de_name_and_namelen(de);

		if ((retval = reiserfs_match(de, name, namelen)) !=
		    NAME_NOT_FOUND) {
			/*
			 * de's de_name, de_namelen, de_recordlen are set.
			 * Fill the rest:
			 */
			/* key of pointed object */
			set_de_object_key(de);
			store_de_entry_key(de);

			/* retval can be NAME_FOUND or NAME_FOUND_INVISIBLE */
			reiserfs_log(LOG_DEBUG,
			    "reiserfs_match answered `%d'\n",
			    retval);
			return (retval);
		}
	}

	if (GET_GENERATION_NUMBER(le_ih_k_offset(de->de_ih)) == 0)
		/*
		 * We have reached left most entry in the node. In common
		 * we have to go to the left neighbor, but if generation
		 * counter is 0 already, we know for sure, that there is
		 * no name with the same hash value
		 */
		/* FIXME: this work correctly only because hash value can
		 * not be 0. Btw, in case of Yura's hash it is probably
		 * possible, so, this is a bug
		 */
		return (NAME_NOT_FOUND);

	/*RFALSE(de->de_item_num,
	    "vs-7015: two diritems of the same directory in one node?");*/

	return (GOTO_PREVIOUS_ITEM);
}
コード例 #8
0
/*
 * If root directory is empty - we set default - Yura's - hash and warn
 * about it.
 * FIXME: we look for only one name in a directory. If tea and yura both
 * have the same value - we ask user to send report to the mailing list
 */
uint32_t find_hash_out(struct reiserfs_mount *rmp)
{
	int retval;
	struct cpu_key key;
	INITIALIZE_PATH(path);
	struct reiserfs_node *ip;
	struct reiserfs_sb_info *sbi;
	struct reiserfs_dir_entry de;
	uint32_t hash = DEFAULT_HASH;

	get_root_node(rmp, &ip);
	if (!ip)
		return (UNSET_HASH);

	sbi = rmp->rm_reiserfs;

	do {
		uint32_t teahash, r5hash, yurahash;

		reiserfs_log(LOG_DEBUG, "make_cpu_key\n");
		make_cpu_key(&key, ip, ~0, TYPE_DIRENTRY, 3);
		reiserfs_log(LOG_DEBUG, "search_by_entry_key for "
		    "key(objectid=%d,dirid=%d)\n",
		    key.on_disk_key.k_objectid, key.on_disk_key.k_dir_id);
		retval = search_by_entry_key(sbi, &key, &path, &de);
		if (retval == IO_ERROR) {
			pathrelse(&path);
			return (UNSET_HASH);
		}
		if (retval == NAME_NOT_FOUND)
			de.de_entry_num--;

		reiserfs_log(LOG_DEBUG, "name found\n");

		set_de_name_and_namelen(&de);

		if (deh_offset(&(de.de_deh[de.de_entry_num])) == DOT_DOT_OFFSET) {
			/* Allow override in this case */
			if (reiserfs_rupasov_hash(sbi)) {
				hash = YURA_HASH;
			}
			reiserfs_log(LOG_DEBUG,
			    "FS seems to be empty, autodetect "
			    "is using the default hash");
			break;
		}

		r5hash   = GET_HASH_VALUE(r5_hash(de.de_name, de.de_namelen));
		teahash  = GET_HASH_VALUE(keyed_hash(de.de_name,
		    de.de_namelen));
		yurahash = GET_HASH_VALUE(yura_hash(de.de_name, de.de_namelen));
		if (((teahash == r5hash) &&
		    (GET_HASH_VALUE(
		     deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash)) ||
		    ((teahash == yurahash) &&
		     (yurahash ==
		      GET_HASH_VALUE(
		      deh_offset(&(de.de_deh[de.de_entry_num]))))) ||
		    ((r5hash == yurahash) &&
		     (yurahash ==
		      GET_HASH_VALUE(
		      deh_offset(&(de.de_deh[de.de_entry_num])))))) {
			reiserfs_log(LOG_ERR,
			    "unable to automatically detect hash "
			    "function. Please mount with -o "
			    "hash={tea,rupasov,r5}");
			hash = UNSET_HASH;
			break;
		}

		if (GET_HASH_VALUE(
		    deh_offset(&(de.de_deh[de.de_entry_num]))) == yurahash) {
			reiserfs_log(LOG_DEBUG, "detected YURA hash\n");
			hash = YURA_HASH;
		} else if (GET_HASH_VALUE(
		    deh_offset(&(de.de_deh[de.de_entry_num]))) == teahash) {
			reiserfs_log(LOG_DEBUG, "detected TEA hash\n");
			hash = TEA_HASH;
		} else if (GET_HASH_VALUE(
		    deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash) {
			reiserfs_log(LOG_DEBUG, "detected R5 hash\n");
			hash = R5_HASH;
		} else {
			reiserfs_log(LOG_WARNING, "unrecognised hash function");
			hash = UNSET_HASH;
		}
	} while (0);

	pathrelse(&path);
	return (hash);
}