1 /* Copyright 2005 by Hans Reiser, licensing governed by
4 /* this file contains typical implementations for most of methods of
10 int reiser4_find_entry(struct inode
*dir
, struct dentry
*name
,
11 lock_handle
* , znode_lock_mode
, reiser4_dir_entry_desc
*);
12 int reiser4_lookup_name(struct inode
*parent
, struct dentry
*dentry
,
14 void check_light_weight(struct inode
*inode
, struct inode
*parent
);
16 /* this is common implementation of get_parent method of dir plugin
17 this is used by NFS kernel server to "climb" up directory tree to
20 struct dentry
*get_parent_common(struct inode
*child
)
22 struct super_block
*s
;
25 struct dentry
*dentry
;
30 * lookup dotdot entry.
34 memset(&dotdot
, 0, sizeof(dotdot
));
35 dotdot
.d_name
.name
= "..";
36 dotdot
.d_name
.len
= 2;
37 dotdot
.d_op
= &get_super_private(s
)->ops
.dentry
;
39 result
= reiser4_lookup_name(child
, &dotdot
, &key
);
41 return ERR_PTR(result
);
43 parent
= reiser4_iget(s
, &key
, 1);
44 if (!IS_ERR(parent
)) {
46 * FIXME-NIKITA dubious: attributes are inherited from @child
49 * (*) this is the only this we can do
51 * (*) attributes of light-weight object are inherited
52 * from a parent through which object was looked up first,
53 * so it is ambiguous anyway.
56 check_light_weight(parent
, child
);
57 reiser4_iget_complete(parent
);
58 dentry
= d_obtain_alias(parent
);
60 dentry
->d_op
= &get_super_private(s
)->ops
.dentry
;
61 } else if (PTR_ERR(parent
) == -ENOENT
)
62 dentry
= ERR_PTR(RETERR(-ESTALE
));
64 dentry
= (void *)parent
;
68 /* this is common implementation of is_name_acceptable method of dir
71 int is_name_acceptable_common(const struct inode
*inode
, /* directory to check*/
72 const char *name UNUSED_ARG
, /* name to check */
73 int len
/* @name's length */)
75 assert("nikita-733", inode
!= NULL
);
76 assert("nikita-734", name
!= NULL
);
77 assert("nikita-735", len
> 0);
79 return len
<= reiser4_max_filename_len(inode
);
82 /* there is no common implementation of build_entry_key method of dir
83 plugin. See plugin/dir/hashed_dir.c:build_entry_key_hashed() or
84 plugin/dir/seekable.c:build_entry_key_seekable() for example
87 /* this is common implementation of build_readdir_key method of dir
89 see reiser4_readdir_common for more details
91 int build_readdir_key_common(struct file
*dir
/* directory being read */ ,
92 reiser4_key
* result
/* where to store key */)
94 reiser4_file_fsdata
*fdata
;
97 assert("nikita-1361", dir
!= NULL
);
98 assert("nikita-1362", result
!= NULL
);
99 assert("nikita-1363", dir
->f_dentry
!= NULL
);
100 inode
= dir
->f_dentry
->d_inode
;
101 assert("nikita-1373", inode
!= NULL
);
103 fdata
= reiser4_get_file_fsdata(dir
);
105 return PTR_ERR(fdata
);
106 assert("nikita-1364", fdata
!= NULL
);
107 return extract_key_from_de_id(get_inode_oid(inode
),
108 &fdata
->dir
.readdir
.position
.
109 dir_entry_key
, result
);
113 void reiser4_adjust_dir_file(struct inode
*, const struct dentry
*, int offset
,
116 /* this is common implementation of add_entry method of dir plugin
118 int reiser4_add_entry_common(struct inode
*object
, /* directory to add new name
120 struct dentry
*where
, /* new name */
121 reiser4_object_create_data
* data
, /* parameters of
123 reiser4_dir_entry_desc
* entry
/* parameters of
130 struct reiser4_dentry_fsdata
*fsdata
;
131 reiser4_block_nr reserve
;
133 assert("nikita-1114", object
!= NULL
);
134 assert("nikita-1250", where
!= NULL
);
136 fsdata
= reiser4_get_dentry_fsdata(where
);
137 if (unlikely(IS_ERR(fsdata
)))
138 return PTR_ERR(fsdata
);
140 reserve
= inode_dir_plugin(object
)->estimate
.add_entry(object
);
141 if (reiser4_grab_space(reserve
, BA_CAN_COMMIT
))
142 return RETERR(-ENOSPC
);
145 coord
= &fsdata
->dec
.entry_coord
;
146 coord_clear_iplug(coord
);
148 /* check for this entry in a directory. This is plugin method. */
149 result
= reiser4_find_entry(object
, where
, &lh
, ZNODE_WRITE_LOCK
,
151 if (likely(result
== -ENOENT
)) {
152 /* add new entry. Just pass control to the directory
154 assert("nikita-1709", inode_dir_item_plugin(object
));
155 assert("nikita-2230", coord
->node
== lh
.node
);
156 reiser4_seal_done(&fsdata
->dec
.entry_seal
);
158 inode_dir_item_plugin(object
)->s
.dir
.add_entry(object
,
163 reiser4_adjust_dir_file(object
, where
,
164 fsdata
->dec
.pos
+ 1, +1);
165 INODE_INC_FIELD(object
, i_size
);
167 } else if (result
== 0) {
168 assert("nikita-2232", coord
->node
== lh
.node
);
169 result
= RETERR(-EEXIST
);
177 * rem_entry - remove entry from directory item
184 * Checks that coordinate @coord is set properly and calls item plugin
185 * method to cut entry.
188 rem_entry(struct inode
*dir
, struct dentry
*dentry
,
189 reiser4_dir_entry_desc
* entry
, coord_t
*coord
, lock_handle
* lh
)
194 iplug
= inode_dir_item_plugin(dir
);
195 child
= dentry
->d_inode
;
196 assert("nikita-3399", child
!= NULL
);
198 /* check that we are really destroying an entry for @child */
203 result
= iplug
->s
.dir
.extract_key(coord
, &key
);
206 if (get_key_objectid(&key
) != get_inode_oid(child
)) {
207 warning("nikita-3397",
208 "rem_entry: %#llx != %#llx\n",
209 get_key_objectid(&key
),
210 (unsigned long long)get_inode_oid(child
));
214 return iplug
->s
.dir
.rem_entry(dir
, &dentry
->d_name
, coord
, lh
, entry
);
218 * reiser4_rem_entry_common - remove entry from a directory
219 * @dir: directory to remove entry from
220 * @where: name that is being removed
221 * @entry: description of entry being removed
223 * This is common implementation of rem_entry method of dir plugin.
225 int reiser4_rem_entry_common(struct inode
*dir
,
226 struct dentry
*dentry
,
227 reiser4_dir_entry_desc
* entry
)
232 struct reiser4_dentry_fsdata
*fsdata
;
235 assert("nikita-1124", dir
!= NULL
);
236 assert("nikita-1125", dentry
!= NULL
);
238 tograb
= inode_dir_plugin(dir
)->estimate
.rem_entry(dir
);
239 result
= reiser4_grab_space(tograb
, BA_CAN_COMMIT
| BA_RESERVED
);
241 return RETERR(-ENOSPC
);
245 /* check for this entry in a directory. This is plugin method. */
246 result
= reiser4_find_entry(dir
, dentry
, &lh
, ZNODE_WRITE_LOCK
, entry
);
247 fsdata
= reiser4_get_dentry_fsdata(dentry
);
248 if (IS_ERR(fsdata
)) {
250 return PTR_ERR(fsdata
);
253 coord
= &fsdata
->dec
.entry_coord
;
255 assert("nikita-3404",
256 get_inode_oid(dentry
->d_inode
) != get_inode_oid(dir
) ||
259 coord_clear_iplug(coord
);
261 /* remove entry. Just pass control to the directory item
263 assert("vs-542", inode_dir_item_plugin(dir
));
264 reiser4_seal_done(&fsdata
->dec
.entry_seal
);
265 reiser4_adjust_dir_file(dir
, dentry
, fsdata
->dec
.pos
, -1);
268 rem_entry(dir
, dentry
, entry
, coord
, &lh
));
270 if (dir
->i_size
>= 1)
271 INODE_DEC_FIELD(dir
, i_size
);
273 warning("nikita-2509", "Dir %llu is runt",
276 result
= RETERR(-EIO
);
279 assert("nikita-3405", dentry
->d_inode
->i_nlink
!= 1 ||
280 dentry
->d_inode
->i_size
!= 2 ||
281 inode_dir_plugin(dentry
->d_inode
) == NULL
);
289 static reiser4_block_nr
estimate_init(struct inode
*parent
,
290 struct inode
*object
);
291 static int create_dot_dotdot(struct inode
*object
, struct inode
*parent
);
293 /* this is common implementation of init method of dir plugin
294 create "." and ".." entries
296 int reiser4_dir_init_common(struct inode
*object
, /* new directory */
297 struct inode
*parent
, /* parent directory */
298 reiser4_object_create_data
* data
/* info passed
305 reiser4_block_nr reserve
;
307 assert("nikita-680", object
!= NULL
);
308 assert("nikita-681", S_ISDIR(object
->i_mode
));
309 assert("nikita-682", parent
!= NULL
);
310 assert("nikita-684", data
!= NULL
);
311 assert("nikita-686", data
->id
== DIRECTORY_FILE_PLUGIN_ID
);
312 assert("nikita-687", object
->i_mode
& S_IFDIR
);
314 reserve
= estimate_init(parent
, object
);
315 if (reiser4_grab_space(reserve
, BA_CAN_COMMIT
))
316 return RETERR(-ENOSPC
);
318 return create_dot_dotdot(object
, parent
);
321 /* this is common implementation of done method of dir plugin
324 int reiser4_dir_done_common(struct inode
*object
/* object being deleted */)
327 reiser4_block_nr reserve
;
328 struct dentry goodby_dots
;
329 reiser4_dir_entry_desc entry
;
331 assert("nikita-1449", object
!= NULL
);
333 if (reiser4_inode_get_flag(object
, REISER4_NO_SD
))
336 /* of course, this can be rewritten to sweep everything in one
337 reiser4_cut_tree(). */
338 memset(&entry
, 0, sizeof entry
);
340 /* FIXME: this done method is called from reiser4_delete_dir_common
341 * which reserved space already */
342 reserve
= inode_dir_plugin(object
)->estimate
.rem_entry(object
);
343 if (reiser4_grab_space(reserve
, BA_CAN_COMMIT
| BA_RESERVED
))
344 return RETERR(-ENOSPC
);
346 memset(&goodby_dots
, 0, sizeof goodby_dots
);
347 entry
.obj
= goodby_dots
.d_inode
= object
;
348 goodby_dots
.d_name
.name
= ".";
349 goodby_dots
.d_name
.len
= 1;
350 result
= reiser4_rem_entry_common(object
, &goodby_dots
, &entry
);
351 reiser4_free_dentry_fsdata(&goodby_dots
);
352 if (unlikely(result
!= 0 && result
!= -ENOMEM
&& result
!= -ENOENT
))
353 warning("nikita-2252", "Cannot remove dot of %lli: %i",
354 (unsigned long long)get_inode_oid(object
), result
);
358 /* this is common implementation of attach method of dir plugin
360 int reiser4_attach_common(struct inode
*child UNUSED_ARG
,
361 struct inode
*parent UNUSED_ARG
)
363 assert("nikita-2647", child
!= NULL
);
364 assert("nikita-2648", parent
!= NULL
);
369 /* this is common implementation of detach method of dir plugin
370 remove "..", decrease nlink on parent
372 int reiser4_detach_common(struct inode
*object
, struct inode
*parent
)
375 struct dentry goodby_dots
;
376 reiser4_dir_entry_desc entry
;
378 assert("nikita-2885", object
!= NULL
);
379 assert("nikita-2886", !reiser4_inode_get_flag(object
, REISER4_NO_SD
));
381 memset(&entry
, 0, sizeof entry
);
383 /* NOTE-NIKITA this only works if @parent is -the- parent of
384 @object, viz. object whose key is stored in dotdot
385 entry. Wouldn't work with hard-links on directories. */
386 memset(&goodby_dots
, 0, sizeof goodby_dots
);
387 entry
.obj
= goodby_dots
.d_inode
= parent
;
388 goodby_dots
.d_name
.name
= "..";
389 goodby_dots
.d_name
.len
= 2;
390 result
= reiser4_rem_entry_common(object
, &goodby_dots
, &entry
);
391 reiser4_free_dentry_fsdata(&goodby_dots
);
393 /* the dot should be the only entry remaining at this time... */
394 assert("nikita-3400",
395 object
->i_size
== 1 && object
->i_nlink
<= 2);
397 /* and, together with the only name directory can have, they
398 * provides for the last 2 remaining references. If we get
399 * here as part of error handling during mkdir, @object
400 * possibly has no name yet, so its nlink == 1. If we get here
401 * from rename (targeting empty directory), it has no name
402 * already, so its nlink == 1. */
403 assert("nikita-3401",
404 object
->i_nlink
== 2 || object
->i_nlink
== 1);
407 /* decrement nlink of directory removed ".." pointed
409 reiser4_del_nlink(parent
, NULL
, 0);
414 /* this is common implementation of estimate.add_entry method of
416 estimation of adding entry which supposes that entry is inserting a
419 reiser4_block_nr
estimate_add_entry_common(const struct inode
*inode
)
421 return estimate_one_insert_into_item(reiser4_tree_by_inode(inode
));
424 /* this is common implementation of estimate.rem_entry method of dir
427 reiser4_block_nr
estimate_rem_entry_common(const struct inode
*inode
)
429 return estimate_one_item_removal(reiser4_tree_by_inode(inode
));
432 /* this is common implementation of estimate.unlink method of dir
436 dir_estimate_unlink_common(const struct inode
*parent
,
437 const struct inode
*object
)
439 reiser4_block_nr res
;
441 /* hashed_rem_entry(object) */
442 res
= inode_dir_plugin(object
)->estimate
.rem_entry(object
);
443 /* del_nlink(parent) */
444 res
+= 2 * inode_file_plugin(parent
)->estimate
.update(parent
);
450 * helper for inode_ops ->lookup() and dir plugin's ->get_parent()
451 * methods: if @inode is a light-weight file, setup its credentials
452 * that are not stored in the stat-data in this case
454 void check_light_weight(struct inode
*inode
, struct inode
*parent
)
456 if (reiser4_inode_get_flag(inode
, REISER4_LIGHT_WEIGHT
)) {
457 inode
->i_uid
= parent
->i_uid
;
458 inode
->i_gid
= parent
->i_gid
;
459 /* clear light-weight flag. If inode would be read by any
460 other name, [ug]id wouldn't change. */
461 reiser4_inode_clr_flag(inode
, REISER4_LIGHT_WEIGHT
);
465 /* looks for name specified in @dentry in directory @parent and if name is
466 found - key of object found entry points to is stored in @entry->key */
467 int reiser4_lookup_name(struct inode
*parent
, /* inode of directory to lookup
469 struct dentry
*dentry
, /* name to look for */
470 reiser4_key
* key
/* place to store key */)
477 reiser4_dir_entry_desc entry
;
478 struct reiser4_dentry_fsdata
*fsdata
;
480 assert("nikita-1247", parent
!= NULL
);
481 assert("nikita-1248", dentry
!= NULL
);
482 assert("nikita-1123", dentry
->d_name
.name
!= NULL
);
484 dentry
->d_op
== &get_super_private(parent
->i_sb
)->ops
.dentry
);
486 name
= dentry
->d_name
.name
;
487 len
= dentry
->d_name
.len
;
489 if (!inode_dir_plugin(parent
)->is_name_acceptable(parent
, name
, len
))
490 /* some arbitrary error code to return */
491 return RETERR(-ENAMETOOLONG
);
493 fsdata
= reiser4_get_dentry_fsdata(dentry
);
495 return PTR_ERR(fsdata
);
497 coord
= &fsdata
->dec
.entry_coord
;
498 coord_clear_iplug(coord
);
501 /* find entry in a directory. This is plugin method. */
502 result
= reiser4_find_entry(parent
, dentry
, &lh
, ZNODE_READ_LOCK
,
505 /* entry was found, extract object key from it. */
508 item_plugin_by_coord(coord
)->s
.dir
.
509 extract_key(coord
, key
));
516 /* helper for reiser4_dir_init_common(): estimate number of blocks to reserve */
517 static reiser4_block_nr
518 estimate_init(struct inode
*parent
, struct inode
*object
)
520 reiser4_block_nr res
= 0;
522 assert("vpf-321", parent
!= NULL
);
523 assert("vpf-322", object
!= NULL
);
525 /* hashed_add_entry(object) */
526 res
+= inode_dir_plugin(object
)->estimate
.add_entry(object
);
527 /* reiser4_add_nlink(object) */
528 res
+= inode_file_plugin(object
)->estimate
.update(object
);
529 /* hashed_add_entry(object) */
530 res
+= inode_dir_plugin(object
)->estimate
.add_entry(object
);
531 /* reiser4_add_nlink(parent) */
532 res
+= inode_file_plugin(parent
)->estimate
.update(parent
);
537 /* helper function for reiser4_dir_init_common(). Create "." and ".." */
538 static int create_dot_dotdot(struct inode
*object
/* object to create dot and
540 struct inode
*parent
/* parent of @object */)
543 struct dentry dots_entry
;
544 reiser4_dir_entry_desc entry
;
546 assert("nikita-688", object
!= NULL
);
547 assert("nikita-689", S_ISDIR(object
->i_mode
));
548 assert("nikita-691", parent
!= NULL
);
550 /* We store dot and dotdot as normal directory entries. This is
551 not necessary, because almost all information stored in them
552 is already in the stat-data of directory, the only thing
553 being missed is objectid of grand-parent directory that can
554 easily be added there as extension.
556 But it is done the way it is done, because not storing dot
557 and dotdot will lead to the following complications:
559 . special case handling in ->lookup().
560 . addition of another extension to the sd.
561 . dependency on key allocation policy for stat data.
565 memset(&entry
, 0, sizeof entry
);
566 memset(&dots_entry
, 0, sizeof dots_entry
);
567 entry
.obj
= dots_entry
.d_inode
= object
;
568 dots_entry
.d_name
.name
= ".";
569 dots_entry
.d_name
.len
= 1;
570 result
= reiser4_add_entry_common(object
, &dots_entry
, NULL
, &entry
);
571 reiser4_free_dentry_fsdata(&dots_entry
);
574 result
= reiser4_add_nlink(object
, object
, 0);
576 entry
.obj
= dots_entry
.d_inode
= parent
;
577 dots_entry
.d_name
.name
= "..";
578 dots_entry
.d_name
.len
= 2;
579 result
= reiser4_add_entry_common(object
,
580 &dots_entry
, NULL
, &entry
);
581 reiser4_free_dentry_fsdata(&dots_entry
);
582 /* if creation of ".." failed, iput() will delete
585 result
= reiser4_add_nlink(parent
, object
, 0);
588 * if we failed to bump i_nlink, try
591 reiser4_detach_common(object
, parent
);
598 * in the case of error, at least update stat-data so that,
599 * ->i_nlink updates are not lingering.
601 reiser4_update_sd(object
);
602 reiser4_update_sd(parent
);
609 * return 0 iff @coord contains a directory entry for the file with the name
613 check_item(const struct inode
*dir
, const coord_t
*coord
, const char *name
)
616 char buf
[DE_NAME_BUF_LEN
];
618 iplug
= item_plugin_by_coord(coord
);
620 warning("nikita-1135", "Cannot get item plugin");
621 print_coord("coord", coord
, 1);
623 } else if (item_id_by_coord(coord
) !=
624 item_id_by_plugin(inode_dir_item_plugin(dir
))) {
625 /* item id of current item does not match to id of items a
626 directory is built of */
627 warning("nikita-1136", "Wrong item plugin");
628 print_coord("coord", coord
, 1);
631 assert("nikita-1137", iplug
->s
.dir
.extract_name
);
633 /* Compare name stored in this entry with name we are looking for.
635 NOTE-NIKITA Here should go code for support of something like
636 unicode, code tables, etc.
638 return !!strcmp(name
, iplug
->s
.dir
.extract_name(coord
, buf
));
642 check_entry(const struct inode
*dir
, coord_t
*coord
, const struct qstr
*name
)
644 return WITH_COORD(coord
, check_item(dir
, coord
, name
->name
));
648 * argument package used by entry_actor to scan entries with identical keys.
650 struct entry_actor_args
{
651 /* name we are looking for */
653 /* key of directory entry. entry_actor() scans through sequence of
654 * items/units having the same key */
656 /* how many entries with duplicate key was scanned so far. */
658 #if REISER4_USE_COLLISION_LIMIT
662 /* return parameter: set to true, if ->name wasn't found */
664 /* what type of lock to take when moving to the next node during
666 znode_lock_mode mode
;
668 /* last coord that was visited during scan */
670 /* last node locked during scan */
672 /* inode of directory */
673 const struct inode
*inode
;
676 /* Function called by reiser4_find_entry() to look for given name
678 static int entry_actor(reiser4_tree
* tree UNUSED_ARG
/* tree being scanned */ ,
679 coord_t
*coord
/* current coord */ ,
680 lock_handle
* lh
/* current lock handle */ ,
681 void *entry_actor_arg
/* argument to scan */)
683 reiser4_key unit_key
;
684 struct entry_actor_args
*args
;
686 assert("nikita-1131", tree
!= NULL
);
687 assert("nikita-1132", coord
!= NULL
);
688 assert("nikita-1133", entry_actor_arg
!= NULL
);
690 args
= entry_actor_arg
;
692 #if REISER4_USE_COLLISION_LIMIT
693 if (args
->non_uniq
> args
->max_non_uniq
) {
695 /* hash collision overflow. */
696 return RETERR(-EBUSY
);
701 * did we just reach the end of the sequence of items/units with
704 if (!keyeq(args
->key
, unit_key_by_coord(coord
, &unit_key
))) {
705 assert("nikita-1791",
706 keylt(args
->key
, unit_key_by_coord(coord
, &unit_key
)));
708 args
->last_coord
.between
= AFTER_UNIT
;
712 coord_dup(&args
->last_coord
, coord
);
714 * did scan just moved to the next node?
716 if (args
->last_lh
.node
!= lh
->node
) {
720 * if so, lock new node with the mode requested by the caller
722 done_lh(&args
->last_lh
);
723 assert("nikita-1896", znode_is_any_locked(lh
->node
));
724 lock_result
= longterm_lock_znode(&args
->last_lh
, lh
->node
,
725 args
->mode
, ZNODE_LOCK_HIPRI
);
726 if (lock_result
!= 0)
729 return check_item(args
->inode
, coord
, args
->name
);
732 /* Look for given @name within directory @dir.
734 This is called during lookup, creation and removal of directory
735 entries and on reiser4_rename_common
737 First calculate key that directory entry for @name would have. Search
738 for this key in the tree. If such key is found, scan all items with
739 the same key, checking name in each directory entry along the way.
741 int reiser4_find_entry(struct inode
*dir
, /* directory to scan */
742 struct dentry
*de
, /* name to search for */
743 lock_handle
* lh
, /* resulting lock handle */
744 znode_lock_mode mode
, /* required lock mode */
745 reiser4_dir_entry_desc
* entry
/* parameters of found
748 const struct qstr
*name
;
753 struct de_location
*dec
;
754 struct reiser4_dentry_fsdata
*fsdata
;
756 assert("nikita-1130", lh
!= NULL
);
757 assert("nikita-1128", dir
!= NULL
);
760 assert("nikita-1129", name
!= NULL
);
762 /* dentry private data don't require lock, because dentry
763 manipulations are protected by i_mutex on parent.
765 This is not so for inodes, because there is no -the- parent in
768 fsdata
= reiser4_get_dentry_fsdata(de
);
770 return PTR_ERR(fsdata
);
773 coord
= &dec
->entry_coord
;
774 coord_clear_iplug(coord
);
775 seal
= &dec
->entry_seal
;
776 /* compose key of directory entry for @name */
777 inode_dir_plugin(dir
)->build_entry_key(dir
, name
, &entry
->key
);
779 if (reiser4_seal_is_set(seal
)) {
781 result
= reiser4_seal_validate(seal
, coord
, &entry
->key
,
782 lh
, mode
, ZNODE_LOCK_LOPRI
);
784 /* key was found. Check that it is really item we are
786 result
= check_entry(dir
, coord
, name
);
791 flags
= (mode
== ZNODE_WRITE_LOCK
) ? CBK_FOR_INSERT
: 0;
793 * find place in the tree where directory item should be located.
795 result
= reiser4_object_lookup(dir
, &entry
->key
, coord
, lh
, mode
,
796 FIND_EXACT
, LEAF_LEVEL
, LEAF_LEVEL
,
797 flags
, NULL
/*ra_info */);
798 if (result
== CBK_COORD_FOUND
) {
799 struct entry_actor_args arg
;
801 /* fast path: no hash collisions */
802 result
= check_entry(dir
, coord
, name
);
804 reiser4_seal_init(seal
, coord
, &entry
->key
);
806 } else if (result
> 0) {
807 /* Iterate through all units with the same keys. */
808 arg
.name
= name
->name
;
809 arg
.key
= &entry
->key
;
812 #if REISER4_USE_COLLISION_LIMIT
813 arg
.max_non_uniq
= max_hash_collisions(dir
);
814 assert("nikita-2851", arg
.max_non_uniq
> 1);
818 coord_init_zero(&arg
.last_coord
);
819 init_lh(&arg
.last_lh
);
821 result
= reiser4_iterate_tree
822 (reiser4_tree_by_inode(dir
),
824 entry_actor
, &arg
, mode
, 1);
825 /* if end of the tree or extent was reached during
827 if (arg
.not_found
|| (result
== -E_NO_NEIGHBOR
)) {
831 result
= zload(arg
.last_coord
.node
);
833 coord_clear_iplug(&arg
.last_coord
);
834 coord_dup(coord
, &arg
.last_coord
);
835 move_lh(lh
, &arg
.last_lh
);
836 result
= RETERR(-ENOENT
);
837 zrelse(arg
.last_coord
.node
);
842 done_lh(&arg
.last_lh
);
844 reiser4_seal_init(seal
, coord
, &entry
->key
);
846 if (result
== 0 || result
== -ENOENT
) {
847 assert("nikita-2580", arg
.non_uniq
> 0);
848 dec
->pos
= arg
.non_uniq
- 1;
858 c-indentation-style: "K&R"