xref: /NextBSD/sys/gnu/fs/reiserfs/reiserfs_namei.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /*-
2  * Copyright 2000 Hans Reiser
3  * See README for licensing and copyright details
4  *
5  * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron@club-internet.fr>
6  *
7  * $FreeBSD$
8  */
9 
10 #include <gnu/fs/reiserfs/reiserfs_fs.h>
11 
12 static int	reiserfs_find_entry(struct reiserfs_node *dp,
13     const char *name, int namelen,
14     struct path * path_to_entry, struct reiserfs_dir_entry *de);
15 
16 MALLOC_DEFINE(M_REISERFSCOOKIES, "reiserfs_cookies",
17     "ReiserFS VOP_READDIR cookies");
18 
19 /* -------------------------------------------------------------------
20  * Lookup functions
21  * -------------------------------------------------------------------*/
22 
23 int
reiserfs_lookup(struct vop_cachedlookup_args * ap)24 reiserfs_lookup(struct vop_cachedlookup_args *ap)
25 {
26 	int error, retval;
27 	struct vnode *vdp         = ap->a_dvp;
28 	struct vnode **vpp        = ap->a_vpp;
29 	struct componentname *cnp = ap->a_cnp;
30 
31 	int flags         = cnp->cn_flags;
32 	struct thread *td = cnp->cn_thread;
33 	struct cpu_key *saved_ino;
34 
35 	struct vnode *vp;
36 	struct vnode *pdp;  /* Saved dp during symlink work */
37 	struct reiserfs_node *dp;
38 	struct reiserfs_dir_entry de;
39 	INITIALIZE_PATH(path_to_entry);
40 
41 	char c = cnp->cn_nameptr[cnp->cn_namelen];
42 	cnp->cn_nameptr[cnp->cn_namelen] = '\0';
43 	reiserfs_log(LOG_DEBUG, "looking for `%s', %ld (%s)\n",
44 	    cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_pnbuf);
45 	cnp->cn_nameptr[cnp->cn_namelen] = c;
46 
47 	vp = NULL;
48 	dp = VTOI(vdp);
49 
50 	if (REISERFS_MAX_NAME(dp->i_reiserfs->s_blocksize) < cnp->cn_namelen)
51 		return (ENAMETOOLONG);
52 
53 	reiserfs_log(LOG_DEBUG, "searching entry\n");
54 	de.de_gen_number_bit_string = 0;
55 	retval = reiserfs_find_entry(dp, cnp->cn_nameptr, cnp->cn_namelen,
56 	    &path_to_entry, &de);
57 	pathrelse(&path_to_entry);
58 
59 	if (retval == NAME_FOUND) {
60 		reiserfs_log(LOG_DEBUG, "found\n");
61 	} else {
62 		reiserfs_log(LOG_DEBUG, "not found\n");
63 	}
64 
65 	if (retval == NAME_FOUND) {
66 #if 0
67 		/* Hide the .reiserfs_priv directory */
68 		if (reiserfs_xattrs(dp->i_reiserfs) &&
69 		    !old_format_only(dp->i_reiserfs) &&
70 		    REISERFS_SB(dp->i_reiserfs)->priv_root &&
71 		    REISERFS_SB(dp->i_reiserfs)->priv_root->d_inode &&
72 		    de.de_objectid == le32toh(INODE_PKEY(REISERFS_SB(
73 		    dp->i_reiserfs)->priv_root->d_inode)->k_objectid)) {
74 			return (EACCES);
75 		}
76 #endif
77 
78 		reiserfs_log(LOG_DEBUG, "reading vnode\n");
79 		pdp = vdp;
80 		if (flags & ISDOTDOT) {
81 			saved_ino = (struct cpu_key *)&(de.de_dir_id);
82 			VOP_UNLOCK(pdp, 0);
83 			error = reiserfs_iget(vdp->v_mount,
84 			    saved_ino, &vp, td);
85 			vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
86 			if (error != 0)
87 				return (error);
88 			*vpp = vp;
89 		} else if (de.de_objectid == dp->i_number &&
90 		    de.de_dir_id == dp->i_ino) {
91 			VREF(vdp); /* We want ourself, ie "." */
92 			*vpp = vdp;
93 		} else {
94 			if ((error = reiserfs_iget(vdp->v_mount,
95 			    (struct cpu_key *)&(de.de_dir_id), &vp, td)) != 0)
96 				return (error);
97 			*vpp = vp;
98 		}
99 
100 		/*
101 		 * Propogate the priv_object flag so we know we're in the
102 		 * priv tree
103 		 */
104 		/*if (is_reiserfs_priv_object(dir))
105 			REISERFS_I(inode)->i_flags |= i_priv_object;*/
106 	} else {
107 		if (retval == IO_ERROR) {
108 			reiserfs_log(LOG_DEBUG, "IO error\n");
109 			return (EIO);
110 		}
111 
112 		return (ENOENT);
113 	}
114 
115 	/* Insert name into cache if appropriate. */
116 	if (cnp->cn_flags & MAKEENTRY)
117 		cache_enter(vdp, *vpp, cnp);
118 
119 	reiserfs_log(LOG_DEBUG, "done\n");
120 	return (0);
121 }
122 
123 extern struct key MIN_KEY;
124 
125 int
reiserfs_readdir(struct vop_readdir_args * ap)126 reiserfs_readdir(struct vop_readdir_args  /* {
127 		struct vnode *a_vp;
128 		struct uio *a_uio;
129 		struct ucred *a_cred;
130 		int *a_eofflag;
131 		int *a_ncookies;
132 		u_long **a_cookies;
133 	} */*ap)
134 {
135 	int error = 0;
136 	struct dirent dstdp;
137 	struct uio *uio = ap->a_uio;
138 
139 	off_t next_pos;
140 	struct buf *bp;
141 	struct item_head *ih;
142 	struct cpu_key pos_key;
143 	const struct key *rkey;
144 	struct reiserfs_node *ip;
145 	struct reiserfs_dir_entry de;
146 	INITIALIZE_PATH(path_to_entry);
147 	int entry_num, item_num, search_res;
148 
149 	/* The NFS part */
150 	int ncookies = 0;
151 	u_long *cookies = NULL;
152 
153 	/*
154 	 * Form key for search the next directory entry using f_pos field of
155 	 * file structure
156 	 */
157 	ip = VTOI(ap->a_vp);
158 	make_cpu_key(&pos_key,
159 	    ip, uio->uio_offset ? uio->uio_offset : DOT_OFFSET,
160 	    TYPE_DIRENTRY, 3);
161 	next_pos = cpu_key_k_offset(&pos_key);
162 
163 	reiserfs_log(LOG_DEBUG, "listing entries for "
164 	    "(objectid=%d, dirid=%d)\n",
165 	    pos_key.on_disk_key.k_objectid, pos_key.on_disk_key.k_dir_id);
166 	reiserfs_log(LOG_DEBUG, "uio_offset = %jd, uio_resid = %d\n",
167 	    (intmax_t)uio->uio_offset, uio->uio_resid);
168 
169 	if (ap->a_ncookies && ap->a_cookies) {
170 		cookies = (u_long *)malloc(
171 		    uio->uio_resid / 16 * sizeof(u_long),
172 		    M_REISERFSCOOKIES, M_WAITOK);
173 	}
174 
175 	while (1) {
176 		//research:
177 		/*
178 		 * Search the directory item, containing entry with
179 		 * specified key
180 		 */
181 		reiserfs_log(LOG_DEBUG, "search directory to read\n");
182 		search_res = search_by_entry_key(ip->i_reiserfs, &pos_key,
183 		    &path_to_entry, &de);
184 		if (search_res == IO_ERROR) {
185 			error = EIO;
186 			goto out;
187 		}
188 
189 		entry_num = de.de_entry_num;
190 		item_num  = de.de_item_num;
191 		bp = de.de_bp;
192 		ih = de.de_ih;
193 
194 		if (search_res == POSITION_FOUND ||
195 		    entry_num < I_ENTRY_COUNT(ih)) {
196 			/*
197 			 * Go through all entries in the directory item
198 			 * beginning from the entry, that has been found.
199 			 */
200 			struct reiserfs_de_head *deh = B_I_DEH(bp, ih) +
201 			    entry_num;
202 
203 			if (ap->a_ncookies == NULL) {
204 				cookies = NULL;
205 			} else {
206 				//ncookies =
207 			}
208 
209 			reiserfs_log(LOG_DEBUG,
210 			    "walking through directory entries\n");
211 			for (; entry_num < I_ENTRY_COUNT(ih);
212 			    entry_num++, deh++) {
213 				int d_namlen;
214 				char *d_name;
215 				off_t d_off;
216 				ino_t d_ino;
217 
218 				if (!de_visible(deh)) {
219 					/* It is hidden entry */
220 					continue;
221 				}
222 
223 				d_namlen = entry_length(bp, ih, entry_num);
224 				d_name   = B_I_DEH_ENTRY_FILE_NAME(bp, ih, deh);
225 				if (!d_name[d_namlen - 1])
226 					d_namlen = strlen(d_name);
227 				reiserfs_log(LOG_DEBUG, "  - `%s' (len=%d)\n",
228 				    d_name, d_namlen);
229 
230 				if (d_namlen > REISERFS_MAX_NAME(
231 				    ip->i_reiserfs->s_blocksize)) {
232 					/* Too big to send back to VFS */
233 					continue;
234 				}
235 
236 #if 0
237 				/* Ignore the .reiserfs_priv entry */
238 				if (reiserfs_xattrs(ip->i_reiserfs) &&
239 				    !old_format_only(ip->i_reiserfs) &&
240 				    filp->f_dentry == ip->i_reiserfs->s_root &&
241 				    REISERFS_SB(ip->i_reiserfs)->priv_root &&
242 				    REISERFS_SB(ip->i_reiserfs)->priv_root->d_inode &&
243 				    deh_objectid(deh) ==
244 				    le32toh(INODE_PKEY(REISERFS_SB(
245 				    ip->i_reiserfs)->priv_root->d_inode)->k_objectid)) {
246 					continue;
247 				}
248 #endif
249 
250 				d_off = deh_offset(deh);
251 				d_ino = deh_objectid(deh);
252 				uio->uio_offset = d_off;
253 
254 				/* Copy to user land */
255 				dstdp.d_fileno = d_ino;
256 				dstdp.d_type   = DT_UNKNOWN;
257 				dstdp.d_namlen = d_namlen;
258 				dstdp.d_reclen = GENERIC_DIRSIZ(&dstdp);
259 				bcopy(d_name, dstdp.d_name, dstdp.d_namlen);
260 				bzero(dstdp.d_name + dstdp.d_namlen,
261 				    dstdp.d_reclen -
262 				    offsetof(struct dirent, d_name) -
263 				    dstdp.d_namlen);
264 
265 				if (d_namlen > 0) {
266 					if (dstdp.d_reclen <= uio->uio_resid) {
267 						reiserfs_log(LOG_DEBUG, "     copying to user land\n");
268 						error = uiomove(&dstdp,
269 						    dstdp.d_reclen, uio);
270 						if (error)
271 							goto end;
272 						if (cookies != NULL) {
273 							cookies[ncookies] =
274 							    d_off;
275 							ncookies++;
276 						}
277 					} else
278 						break;
279 				} else {
280 					error = EIO;
281 					break;
282 				}
283 
284 				next_pos = deh_offset(deh) + 1;
285 			}
286 			reiserfs_log(LOG_DEBUG, "...done\n");
287 		}
288 
289 		reiserfs_log(LOG_DEBUG, "checking item num (%d == %d ?)\n",
290 		    item_num, B_NR_ITEMS(bp) - 1);
291 		if (item_num != B_NR_ITEMS(bp) - 1) {
292 			/* End of directory has been reached */
293 			reiserfs_log(LOG_DEBUG, "end reached\n");
294 			if (ap->a_eofflag)
295 				*ap->a_eofflag = 1;
296 			goto end;
297 		}
298 
299 		/*
300 		 * Item we went through is last item of node. Using right
301 		 * delimiting key check is it directory end
302 		 */
303 		reiserfs_log(LOG_DEBUG, "get right key\n");
304 		rkey = get_rkey(&path_to_entry, ip->i_reiserfs);
305 		reiserfs_log(LOG_DEBUG, "right key = (objectid=%d, dirid=%d)\n",
306 		    rkey->k_objectid, rkey->k_dir_id);
307 
308 		reiserfs_log(LOG_DEBUG, "compare it to MIN_KEY\n");
309 		reiserfs_log(LOG_DEBUG, "MIN KEY = (objectid=%d, dirid=%d)\n",
310 		    MIN_KEY.k_objectid, MIN_KEY.k_dir_id);
311 		if (comp_le_keys(rkey, &MIN_KEY) == 0) {
312 			/* Set pos_key to key, that is the smallest and greater
313 			 * that key of the last entry in the item */
314 			reiserfs_log(LOG_DEBUG, "continuing on the right\n");
315 			set_cpu_key_k_offset(&pos_key, next_pos);
316 			continue;
317 		}
318 
319 		reiserfs_log(LOG_DEBUG, "compare it to pos_key\n");
320 		reiserfs_log(LOG_DEBUG, "pos key = (objectid=%d, dirid=%d)\n",
321 		    pos_key.on_disk_key.k_objectid,
322 		    pos_key.on_disk_key.k_dir_id);
323 		if (COMP_SHORT_KEYS(rkey, &pos_key)) {
324 			/* End of directory has been reached */
325 			reiserfs_log(LOG_DEBUG, "end reached (right)\n");
326 			if (ap->a_eofflag)
327 				*ap->a_eofflag = 1;
328 			goto end;
329 		}
330 
331 		/* Directory continues in the right neighboring block */
332 		reiserfs_log(LOG_DEBUG, "continuing with a new offset\n");
333 		set_cpu_key_k_offset(&pos_key,
334 		    le_key_k_offset(KEY_FORMAT_3_5, rkey));
335 		reiserfs_log(LOG_DEBUG,
336 		    "new pos key = (objectid=%d, dirid=%d)\n",
337 		    pos_key.on_disk_key.k_objectid,
338 		    pos_key.on_disk_key.k_dir_id);
339 	}
340 
341 end:
342 	uio->uio_offset = next_pos;
343 	pathrelse(&path_to_entry);
344 	reiserfs_check_path(&path_to_entry);
345 out:
346 	if (error && cookies != NULL) {
347 		free(cookies, M_REISERFSCOOKIES);
348 	} else if (ap->a_ncookies != NULL && ap->a_cookies != NULL) {
349 		*ap->a_ncookies = ncookies;
350 		*ap->a_cookies  = cookies;
351 	}
352 	return (error);
353 }
354 
355 /* -------------------------------------------------------------------
356  * Functions from linux/fs/reiserfs/namei.c
357  * -------------------------------------------------------------------*/
358 
359 
360 /*
361  * Directory item contains array of entry headers. This performs binary
362  * search through that array.
363  */
364 static int
bin_search_in_dir_item(struct reiserfs_dir_entry * de,off_t off)365 bin_search_in_dir_item(struct reiserfs_dir_entry *de, off_t off)
366 {
367 	struct item_head *ih = de->de_ih;
368 	struct reiserfs_de_head *deh = de->de_deh;
369 	int rbound, lbound, j;
370 
371 	lbound = 0;
372 	rbound = I_ENTRY_COUNT(ih) - 1;
373 
374 	for (j = (rbound + lbound) / 2; lbound <= rbound;
375 	    j = (rbound + lbound) / 2) {
376 		if (off < deh_offset(deh + j)) {
377 			rbound = j - 1;
378 			continue;
379 		}
380 		if (off > deh_offset(deh + j)) {
381 			lbound = j + 1;
382 			continue;
383 		}
384 
385 		/* This is not name found, but matched third key component */
386 		de->de_entry_num = j;
387 		return (NAME_FOUND);
388 	}
389 
390 	de->de_entry_num = lbound;
391 	return (NAME_NOT_FOUND);
392 }
393 
394 /*
395  * Comment?  Maybe something like set de to point to what the path
396  * points to?
397  */
398 static inline void
set_de_item_location(struct reiserfs_dir_entry * de,struct path * path)399 set_de_item_location(struct reiserfs_dir_entry *de, struct path *path)
400 {
401 
402 	de->de_bp       = get_last_bp(path);
403 	de->de_ih       = get_ih(path);
404 	de->de_deh      = B_I_DEH(de->de_bp, de->de_ih);
405 	de->de_item_num = PATH_LAST_POSITION(path);
406 }
407 
408 /*
409  * de_bh, de_ih, de_deh (points to first element of array), de_item_num
410  * is set
411  */
412 void
set_de_name_and_namelen(struct reiserfs_dir_entry * de)413 set_de_name_and_namelen(struct reiserfs_dir_entry *de)
414 {
415 	struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
416 
417 	if (de->de_entry_num >= ih_entry_count(de->de_ih)) {
418 		reiserfs_log(LOG_DEBUG, "BUG\n");
419 		return;
420 	}
421 
422 	de->de_entrylen = entry_length(de->de_bp, de->de_ih, de->de_entry_num);
423 	de->de_namelen  = de->de_entrylen - (de_with_sd(deh) ? SD_SIZE : 0);
424 	de->de_name     = B_I_PITEM(de->de_bp, de->de_ih) + deh_location(deh);
425 	if (de->de_name[de->de_namelen - 1] == 0)
426 		de->de_namelen = strlen(de->de_name);
427 }
428 
429 /* What entry points to */
430 static inline void
set_de_object_key(struct reiserfs_dir_entry * de)431 set_de_object_key(struct reiserfs_dir_entry *de)
432 {
433 
434 	if (de->de_entry_num >= ih_entry_count(de->de_ih)) {
435 		reiserfs_log(LOG_DEBUG, "BUG\n");
436 		return;
437 	}
438 	de->de_dir_id   = deh_dir_id(&(de->de_deh[de->de_entry_num]));
439 	de->de_objectid = deh_objectid(&(de->de_deh[de->de_entry_num]));
440 }
441 
442 static inline void
store_de_entry_key(struct reiserfs_dir_entry * de)443 store_de_entry_key(struct reiserfs_dir_entry *de)
444 {
445 	struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
446 
447 	if (de->de_entry_num >= ih_entry_count(de->de_ih)) {
448 		reiserfs_log(LOG_DEBUG, "BUG\n");
449 		return;
450 	}
451 
452 	/* Store key of the found entry */
453 	de->de_entry_key.version = KEY_FORMAT_3_5;
454 	de->de_entry_key.on_disk_key.k_dir_id =
455 	    le32toh(de->de_ih->ih_key.k_dir_id);
456 	de->de_entry_key.on_disk_key.k_objectid =
457 	    le32toh(de->de_ih->ih_key.k_objectid);
458 	set_cpu_key_k_offset(&(de->de_entry_key), deh_offset(deh));
459 	set_cpu_key_k_type(&(de->de_entry_key), TYPE_DIRENTRY);
460 }
461 
462 /*
463  * We assign a key to each directory item, and place multiple entries in
464  * a single directory item. A directory item has a key equal to the key
465  * of the first directory entry in it.
466  *
467  * This function first calls search_by_key, then, if item whose first
468  * entry matches is not found it looks for the entry inside directory
469  * item found by search_by_key. Fills the path to the entry, and to the
470  * entry position in the item
471  */
472 int
search_by_entry_key(struct reiserfs_sb_info * sbi,const struct cpu_key * key,struct path * path,struct reiserfs_dir_entry * de)473 search_by_entry_key(struct reiserfs_sb_info *sbi,
474     const struct cpu_key *key, struct path *path,
475     struct reiserfs_dir_entry *de)
476 {
477 	int retval;
478 
479 	reiserfs_log(LOG_DEBUG, "searching in (objectid=%d,dirid=%d)\n",
480 	    key->on_disk_key.k_objectid, key->on_disk_key.k_dir_id);
481 	retval = search_item(sbi, key, path);
482 	switch (retval) {
483 	case ITEM_NOT_FOUND:
484 		if (!PATH_LAST_POSITION(path)) {
485 			reiserfs_log(LOG_DEBUG,
486 			    "search_by_key returned item position == 0");
487 			pathrelse(path);
488 			return (IO_ERROR);
489 		}
490 		PATH_LAST_POSITION(path)--;
491 		reiserfs_log(LOG_DEBUG, "search_by_key did not found it\n");
492 		break;
493 	case ITEM_FOUND:
494 		reiserfs_log(LOG_DEBUG, "search_by_key found it\n");
495 		break;
496 	case IO_ERROR:
497 		return (retval);
498 	default:
499 		pathrelse(path);
500 		reiserfs_log(LOG_DEBUG, "no path to here");
501 		return (IO_ERROR);
502 	}
503 
504 	reiserfs_log(LOG_DEBUG, "set item location\n");
505 	set_de_item_location(de, path);
506 
507 	/*
508 	 * Binary search in directory item by third component of the
509 	 * key. Sets de->de_entry_num of de
510 	 */
511 	reiserfs_log(LOG_DEBUG, "bin_search_in_dir_item\n");
512 	retval = bin_search_in_dir_item(de, cpu_key_k_offset(key));
513 	path->pos_in_item = de->de_entry_num;
514 	if (retval != NAME_NOT_FOUND) {
515 		/*
516 		 * Ugly, but rename needs de_bp, de_deh, de_name, de_namelen,
517 		 * de_objectid set
518 		 */
519 		set_de_name_and_namelen(de);
520 		set_de_object_key(de);
521 		reiserfs_log(LOG_DEBUG, "set (objectid=%d,dirid=%d)\n",
522 		    de->de_objectid, de->de_dir_id);
523 	}
524 
525 	return (retval);
526 }
527 
528 static uint32_t
get_third_component(struct reiserfs_sb_info * sbi,const char * name,int len)529 get_third_component(struct reiserfs_sb_info *sbi, const char *name, int len)
530 {
531 	uint32_t res;
532 
533 	if (!len || (len == 1 && name[0] == '.'))
534 		return (DOT_OFFSET);
535 
536 	if (len == 2 && name[0] == '.' && name[1] == '.')
537 		return (DOT_DOT_OFFSET);
538 
539 	res = REISERFS_SB(sbi)->s_hash_function(name, len);
540 
541 	/* Take bits from 7-th to 30-th including both bounds */
542 	res = GET_HASH_VALUE(res);
543 	if (res == 0)
544 		/*
545 		 * Needed to have no names before "." and ".." those have hash
546 		 * value == 0 and generation counters 1 and 2 accordingly
547 		 */
548 		res = 128;
549 
550 	return (res + MAX_GENERATION_NUMBER);
551 }
552 
553 static int
reiserfs_match(struct reiserfs_dir_entry * de,const char * name,int namelen)554 reiserfs_match(struct reiserfs_dir_entry *de, const char *name, int namelen)
555 {
556 	int retval = NAME_NOT_FOUND;
557 
558 	if ((namelen == de->de_namelen) &&
559 	    !memcmp(de->de_name, name, de->de_namelen))
560 		retval = (de_visible(de->de_deh + de->de_entry_num) ?
561 		    NAME_FOUND : NAME_FOUND_INVISIBLE);
562 
563 	return (retval);
564 }
565 
566 /*
567  * de's de_bh, de_ih, de_deh, de_item_num, de_entry_num are set already
568  * Used when hash collisions exist
569  */
570 static int
linear_search_in_dir_item(struct cpu_key * key,struct reiserfs_dir_entry * de,const char * name,int namelen)571 linear_search_in_dir_item(struct cpu_key *key, struct reiserfs_dir_entry *de,
572     const char *name, int namelen)
573 {
574 	int i;
575 	int retval;
576 	struct reiserfs_de_head * deh = de->de_deh;
577 
578 	i = de->de_entry_num;
579 
580 	if (i == I_ENTRY_COUNT(de->de_ih) ||
581 	    GET_HASH_VALUE(deh_offset(deh + i)) !=
582 	    GET_HASH_VALUE(cpu_key_k_offset(key))) {
583 		i--;
584 	}
585 
586 	/*RFALSE( de->de_deh != B_I_DEH (de->de_bh, de->de_ih),
587 	  "vs-7010: array of entry headers not found");*/
588 
589 	deh += i;
590 
591 	for (; i >= 0; i--, deh--) {
592 		if (GET_HASH_VALUE(deh_offset(deh)) !=
593 		    GET_HASH_VALUE(cpu_key_k_offset(key))) {
594 			/*
595 			 * Hash value does not match, no need to check
596 			 * whole name
597 			 */
598 			reiserfs_log(LOG_DEBUG, "name `%s' not found\n", name);
599 			return (NAME_NOT_FOUND);
600 		}
601 
602 		/* Mark that this generation number is used */
603 		if (de->de_gen_number_bit_string)
604 			set_bit(GET_GENERATION_NUMBER(deh_offset(deh)),
605 			    (unsigned long *)de->de_gen_number_bit_string);
606 
607 		/* Calculate pointer to name and namelen */
608 		de->de_entry_num = i;
609 		set_de_name_and_namelen(de);
610 
611 		if ((retval = reiserfs_match(de, name, namelen)) !=
612 		    NAME_NOT_FOUND) {
613 			/*
614 			 * de's de_name, de_namelen, de_recordlen are set.
615 			 * Fill the rest:
616 			 */
617 			/* key of pointed object */
618 			set_de_object_key(de);
619 			store_de_entry_key(de);
620 
621 			/* retval can be NAME_FOUND or NAME_FOUND_INVISIBLE */
622 			reiserfs_log(LOG_DEBUG,
623 			    "reiserfs_match answered `%d'\n",
624 			    retval);
625 			return (retval);
626 		}
627 	}
628 
629 	if (GET_GENERATION_NUMBER(le_ih_k_offset(de->de_ih)) == 0)
630 		/*
631 		 * We have reached left most entry in the node. In common
632 		 * we have to go to the left neighbor, but if generation
633 		 * counter is 0 already, we know for sure, that there is
634 		 * no name with the same hash value
635 		 */
636 		/* FIXME: this work correctly only because hash value can
637 		 * not be 0. Btw, in case of Yura's hash it is probably
638 		 * possible, so, this is a bug
639 		 */
640 		return (NAME_NOT_FOUND);
641 
642 	/*RFALSE(de->de_item_num,
643 	    "vs-7015: two diritems of the same directory in one node?");*/
644 
645 	return (GOTO_PREVIOUS_ITEM);
646 }
647 
648 /*
649  * May return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND
650  * FIXME: should add something like IOERROR
651  */
652 static int
reiserfs_find_entry(struct reiserfs_node * dp,const char * name,int namelen,struct path * path_to_entry,struct reiserfs_dir_entry * de)653 reiserfs_find_entry(struct reiserfs_node *dp, const char *name, int namelen,
654     struct path * path_to_entry, struct reiserfs_dir_entry *de)
655 {
656 	struct cpu_key key_to_search;
657 	int retval;
658 
659 	if (namelen > REISERFS_MAX_NAME(dp->i_reiserfs->s_blocksize))
660 		return NAME_NOT_FOUND;
661 
662 	/* We will search for this key in the tree */
663 	make_cpu_key(&key_to_search, dp,
664 	    get_third_component(dp->i_reiserfs, name, namelen),
665 	    TYPE_DIRENTRY, 3);
666 
667 	while (1) {
668 		reiserfs_log(LOG_DEBUG, "search by entry key\n");
669 		retval = search_by_entry_key(dp->i_reiserfs, &key_to_search,
670 		    path_to_entry, de);
671 		if (retval == IO_ERROR) {
672 			reiserfs_log(LOG_DEBUG, "IO error in %s\n",
673 			    __FUNCTION__);
674 			return IO_ERROR;
675 		}
676 
677 		/* Compare names for all entries having given hash value */
678 		reiserfs_log(LOG_DEBUG, "linear search for `%s'\n", name);
679 		retval = linear_search_in_dir_item(&key_to_search, de,
680 		    name, namelen);
681 		if (retval != GOTO_PREVIOUS_ITEM) {
682 			/*
683 			 * There is no need to scan directory anymore.
684 			 * Given entry found or does not exist
685 			 */
686 			reiserfs_log(LOG_DEBUG, "linear search returned "
687 			    "(objectid=%d,dirid=%d)\n",
688 			    de->de_objectid, de->de_dir_id);
689 			path_to_entry->pos_in_item = de->de_entry_num;
690 			return retval;
691 		}
692 
693 		/*
694 		 * There is left neighboring item of this directory and
695 		 * given entry can be there
696 		 */
697 		set_cpu_key_k_offset(&key_to_search,
698 		    le_ih_k_offset(de->de_ih) - 1);
699 		pathrelse(path_to_entry);
700 	} /* while (1) */
701 }
702