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
, reiser4_key
* key
);
13 void check_light_weight(struct inode
*inode
, struct inode
*parent
);
15 /* this is common implementation of get_parent method of dir plugin
16 this is used by NFS kernel server to "climb" up directory tree to
19 struct dentry
*get_parent_common(struct inode
*child
)
21 struct super_block
*s
;
24 struct dentry
*dentry
;
29 * lookup dotdot entry.
33 memset(&dotdot
, 0, sizeof(dotdot
));
34 dotdot
.d_name
.name
= "..";
35 dotdot
.d_name
.len
= 2;
36 dotdot
.d_op
= &get_super_private(s
)->ops
.dentry
;
38 result
= reiser4_lookup_name(child
, &dotdot
, &key
);
40 return ERR_PTR(result
);
42 parent
= reiser4_iget(s
, &key
, 1);
43 if (!IS_ERR(parent
)) {
45 * FIXME-NIKITA dubious: attributes are inherited from @child
48 * (*) this is the only this we can do
50 * (*) attributes of light-weight object are inherited
51 * from a parent through which object was looked up first,
52 * so it is ambiguous anyway.
55 check_light_weight(parent
, child
);
56 reiser4_iget_complete(parent
);
57 dentry
= d_alloc_anon(parent
);
60 dentry
= ERR_PTR(RETERR(-ENOMEM
));
62 dentry
->d_op
= &get_super_private(s
)->ops
.dentry
;
63 } else if (PTR_ERR(parent
) == -ENOENT
)
64 dentry
= ERR_PTR(RETERR(-ESTALE
));
66 dentry
= (void *)parent
;
70 /* this is common implementation of is_name_acceptable method of dir
73 int is_name_acceptable_common(const struct inode
*inode
, /* directory to check */
74 const char *name UNUSED_ARG
, /* name to check */
75 int len
/* @name's length */ )
77 assert("nikita-733", inode
!= NULL
);
78 assert("nikita-734", name
!= NULL
);
79 assert("nikita-735", len
> 0);
81 return len
<= reiser4_max_filename_len(inode
);
84 /* there is no common implementation of build_entry_key method of dir
85 plugin. See plugin/dir/hashed_dir.c:build_entry_key_hashed() or
86 plugin/dir/seekable.c:build_entry_key_seekable() for example
89 /* this is common implementation of build_readdir_key method of dir
91 see reiser4_readdir_common for more details
93 int build_readdir_key_common(struct file
*dir
/* directory being read */ ,
94 reiser4_key
* result
/* where to store key */ )
96 reiser4_file_fsdata
*fdata
;
99 assert("nikita-1361", dir
!= NULL
);
100 assert("nikita-1362", result
!= NULL
);
101 assert("nikita-1363", dir
->f_dentry
!= NULL
);
102 inode
= dir
->f_dentry
->d_inode
;
103 assert("nikita-1373", inode
!= NULL
);
105 fdata
= reiser4_get_file_fsdata(dir
);
107 return PTR_ERR(fdata
);
108 assert("nikita-1364", fdata
!= NULL
);
109 return extract_key_from_de_id(get_inode_oid(inode
),
110 &fdata
->dir
.readdir
.position
.
111 dir_entry_key
, result
);
115 void reiser4_adjust_dir_file(struct inode
*, const struct dentry
*, int offset
,
118 /* this is common implementation of add_entry method of dir plugin
120 int reiser4_add_entry_common(struct inode
*object
, /* directory to add new name
122 struct dentry
*where
, /* new name */
123 reiser4_object_create_data
* data
, /* parameters of
125 reiser4_dir_entry_desc
* entry
/* parameters of
132 struct reiser4_dentry_fsdata
*fsdata
;
133 reiser4_block_nr reserve
;
135 assert("nikita-1114", object
!= NULL
);
136 assert("nikita-1250", where
!= NULL
);
138 fsdata
= reiser4_get_dentry_fsdata(where
);
139 if (unlikely(IS_ERR(fsdata
)))
140 return PTR_ERR(fsdata
);
142 reserve
= inode_dir_plugin(object
)->estimate
.add_entry(object
);
143 if (reiser4_grab_space(reserve
, BA_CAN_COMMIT
))
144 return RETERR(-ENOSPC
);
147 coord
= &fsdata
->dec
.entry_coord
;
148 coord_clear_iplug(coord
);
150 /* check for this entry in a directory. This is plugin method. */
151 result
= reiser4_find_entry(object
, where
, &lh
, ZNODE_WRITE_LOCK
,
153 if (likely(result
== -ENOENT
)) {
154 /* add new entry. Just pass control to the directory
156 assert("nikita-1709", inode_dir_item_plugin(object
));
157 assert("nikita-2230", coord
->node
== lh
.node
);
158 reiser4_seal_done(&fsdata
->dec
.entry_seal
);
160 inode_dir_item_plugin(object
)->s
.dir
.add_entry(object
,
165 reiser4_adjust_dir_file(object
, where
,
166 fsdata
->dec
.pos
+ 1, +1);
167 INODE_INC_FIELD(object
, i_size
);
169 } else if (result
== 0) {
170 assert("nikita-2232", coord
->node
== lh
.node
);
171 result
= RETERR(-EEXIST
);
179 * rem_entry - remove entry from directory item
186 * Checks that coordinate @coord is set properly and calls item plugin
187 * method to cut entry.
190 rem_entry(struct inode
*dir
, struct dentry
*dentry
,
191 reiser4_dir_entry_desc
* entry
, coord_t
* coord
, lock_handle
* lh
)
196 iplug
= inode_dir_item_plugin(dir
);
197 child
= dentry
->d_inode
;
198 assert("nikita-3399", child
!= NULL
);
200 /* check that we are really destroying an entry for @child */
205 result
= iplug
->s
.dir
.extract_key(coord
, &key
);
208 if (get_key_objectid(&key
) != get_inode_oid(child
)) {
209 warning("nikita-3397",
210 "rem_entry: %#llx != %#llx\n",
211 get_key_objectid(&key
),
212 (unsigned long long)get_inode_oid(child
));
216 return iplug
->s
.dir
.rem_entry(dir
, &dentry
->d_name
, coord
, lh
, entry
);
220 * reiser4_rem_entry_common - remove entry from a directory
221 * @dir: directory to remove entry from
222 * @where: name that is being removed
223 * @entry: description of entry being removed
225 * This is common implementation of rem_entry method of dir plugin.
227 int reiser4_rem_entry_common(struct inode
*dir
,
228 struct dentry
*dentry
,
229 reiser4_dir_entry_desc
*entry
)
234 struct reiser4_dentry_fsdata
*fsdata
;
237 assert("nikita-1124", dir
!= NULL
);
238 assert("nikita-1125", dentry
!= NULL
);
240 tograb
= inode_dir_plugin(dir
)->estimate
.rem_entry(dir
);
241 result
= reiser4_grab_space(tograb
, BA_CAN_COMMIT
| BA_RESERVED
);
243 return RETERR(-ENOSPC
);
247 /* check for this entry in a directory. This is plugin method. */
248 result
= reiser4_find_entry(dir
, dentry
, &lh
, ZNODE_WRITE_LOCK
, entry
);
249 fsdata
= reiser4_get_dentry_fsdata(dentry
);
250 if (IS_ERR(fsdata
)) {
252 return PTR_ERR(fsdata
);
255 coord
= &fsdata
->dec
.entry_coord
;
257 assert("nikita-3404",
258 get_inode_oid(dentry
->d_inode
) != get_inode_oid(dir
) ||
261 coord_clear_iplug(coord
);
263 /* remove entry. Just pass control to the directory item
265 assert("vs-542", inode_dir_item_plugin(dir
));
266 reiser4_seal_done(&fsdata
->dec
.entry_seal
);
267 reiser4_adjust_dir_file(dir
, dentry
, fsdata
->dec
.pos
, -1);
270 rem_entry(dir
, dentry
, entry
, coord
, &lh
));
272 if (dir
->i_size
>= 1)
273 INODE_DEC_FIELD(dir
, i_size
);
275 warning("nikita-2509", "Dir %llu is runt",
278 result
= RETERR(-EIO
);
281 assert("nikita-3405", dentry
->d_inode
->i_nlink
!= 1 ||
282 dentry
->d_inode
->i_size
!= 2 ||
283 inode_dir_plugin(dentry
->d_inode
) == NULL
);
291 static reiser4_block_nr
estimate_init(struct inode
*parent
,
292 struct inode
*object
);
293 static int create_dot_dotdot(struct inode
*object
, struct inode
*parent
);
295 /* this is common implementation of init method of dir plugin
296 create "." and ".." entries
298 int reiser4_dir_init_common(struct inode
*object
, /* new directory */
299 struct inode
*parent
, /* parent directory */
300 reiser4_object_create_data
* data
/* info passed
307 reiser4_block_nr reserve
;
309 assert("nikita-680", object
!= NULL
);
310 assert("nikita-681", S_ISDIR(object
->i_mode
));
311 assert("nikita-682", parent
!= NULL
);
312 assert("nikita-684", data
!= NULL
);
313 assert("nikita-686", data
->id
== DIRECTORY_FILE_PLUGIN_ID
);
314 assert("nikita-687", object
->i_mode
& S_IFDIR
);
316 reserve
= estimate_init(parent
, object
);
317 if (reiser4_grab_space(reserve
, BA_CAN_COMMIT
))
318 return RETERR(-ENOSPC
);
320 return create_dot_dotdot(object
, parent
);
323 /* this is common implementation of done method of dir plugin
326 int reiser4_dir_done_common(struct inode
*object
/* object being deleted */ )
329 reiser4_block_nr reserve
;
330 struct dentry goodby_dots
;
331 reiser4_dir_entry_desc entry
;
333 assert("nikita-1449", object
!= NULL
);
335 if (reiser4_inode_get_flag(object
, REISER4_NO_SD
))
338 /* of course, this can be rewritten to sweep everything in one
339 reiser4_cut_tree(). */
340 memset(&entry
, 0, sizeof entry
);
342 /* FIXME: this done method is called from reiser4_delete_dir_common which
343 * reserved space already */
344 reserve
= inode_dir_plugin(object
)->estimate
.rem_entry(object
);
345 if (reiser4_grab_space(reserve
, BA_CAN_COMMIT
| BA_RESERVED
))
346 return RETERR(-ENOSPC
);
348 memset(&goodby_dots
, 0, sizeof goodby_dots
);
349 entry
.obj
= goodby_dots
.d_inode
= object
;
350 goodby_dots
.d_name
.name
= ".";
351 goodby_dots
.d_name
.len
= 1;
352 result
= reiser4_rem_entry_common(object
, &goodby_dots
, &entry
);
353 reiser4_free_dentry_fsdata(&goodby_dots
);
354 if (unlikely(result
!= 0 && result
!= -ENOMEM
&& result
!= -ENOENT
))
355 /* only worth a warning
357 "values of \x0eB\x0f will give rise to dom!\n"
360 warning("nikita-2252", "Cannot remove dot of %lli: %i",
361 (unsigned long long)get_inode_oid(object
), result
);
365 /* this is common implementation of attach method of dir plugin
367 int reiser4_attach_common(struct inode
*child UNUSED_ARG
,
368 struct inode
*parent UNUSED_ARG
)
370 assert("nikita-2647", child
!= NULL
);
371 assert("nikita-2648", parent
!= NULL
);
376 /* this is common implementation of detach method of dir plugin
377 remove "..", decrease nlink on parent
379 int reiser4_detach_common(struct inode
*object
, struct inode
*parent
)
382 struct dentry goodby_dots
;
383 reiser4_dir_entry_desc entry
;
385 assert("nikita-2885", object
!= NULL
);
386 assert("nikita-2886", !reiser4_inode_get_flag(object
, REISER4_NO_SD
));
388 memset(&entry
, 0, sizeof entry
);
390 /* NOTE-NIKITA this only works if @parent is -the- parent of
391 @object, viz. object whose key is stored in dotdot
392 entry. Wouldn't work with hard-links on directories. */
393 memset(&goodby_dots
, 0, sizeof goodby_dots
);
394 entry
.obj
= goodby_dots
.d_inode
= parent
;
395 goodby_dots
.d_name
.name
= "..";
396 goodby_dots
.d_name
.len
= 2;
397 result
= reiser4_rem_entry_common(object
, &goodby_dots
, &entry
);
398 reiser4_free_dentry_fsdata(&goodby_dots
);
400 /* the dot should be the only entry remaining at this time... */
401 assert("nikita-3400",
402 object
->i_size
== 1 && object
->i_nlink
<= 2);
404 /* and, together with the only name directory can have, they
405 * provides for the last 2 remaining references. If we get
406 * here as part of error handling during mkdir, @object
407 * possibly has no name yet, so its nlink == 1. If we get here
408 * from rename (targeting empty directory), it has no name
409 * already, so its nlink == 1. */
410 assert("nikita-3401",
411 object
->i_nlink
== 2 || object
->i_nlink
== 1);
414 /* decrement nlink of directory removed ".." pointed
416 reiser4_del_nlink(parent
, NULL
, 0);
421 /* this is common implementation of estimate.add_entry method of
423 estimation of adding entry which supposes that entry is inserting a
426 reiser4_block_nr
estimate_add_entry_common(const struct inode
* inode
)
428 return estimate_one_insert_into_item(reiser4_tree_by_inode(inode
));
431 /* this is common implementation of estimate.rem_entry method of dir
434 reiser4_block_nr
estimate_rem_entry_common(const struct inode
* inode
)
436 return estimate_one_item_removal(reiser4_tree_by_inode(inode
));
439 /* this is common implementation of estimate.unlink method of dir
443 dir_estimate_unlink_common(const struct inode
* parent
,
444 const struct inode
* object
)
446 reiser4_block_nr res
;
448 /* hashed_rem_entry(object) */
449 res
= inode_dir_plugin(object
)->estimate
.rem_entry(object
);
450 /* del_nlink(parent) */
451 res
+= 2 * inode_file_plugin(parent
)->estimate
.update(parent
);
457 * helper for inode_ops ->lookup() and dir plugin's ->get_parent()
458 * methods: if @inode is a light-weight file, setup its credentials
459 * that are not stored in the stat-data in this case
461 void check_light_weight(struct inode
*inode
, struct inode
*parent
)
463 if (reiser4_inode_get_flag(inode
, REISER4_LIGHT_WEIGHT
)) {
464 inode
->i_uid
= parent
->i_uid
;
465 inode
->i_gid
= parent
->i_gid
;
466 /* clear light-weight flag. If inode would be read by any
467 other name, [ug]id wouldn't change. */
468 reiser4_inode_clr_flag(inode
, REISER4_LIGHT_WEIGHT
);
472 /* looks for name specified in @dentry in directory @parent and if name is
473 found - key of object found entry points to is stored in @entry->key */
474 int reiser4_lookup_name(struct inode
*parent
, /* inode of directory to lookup for
476 struct dentry
*dentry
, /* name to look for */
477 reiser4_key
* key
/* place to store key */ )
484 reiser4_dir_entry_desc entry
;
485 struct reiser4_dentry_fsdata
*fsdata
;
487 assert("nikita-1247", parent
!= NULL
);
488 assert("nikita-1248", dentry
!= NULL
);
489 assert("nikita-1123", dentry
->d_name
.name
!= NULL
);
491 dentry
->d_op
== &get_super_private(parent
->i_sb
)->ops
.dentry
);
493 name
= dentry
->d_name
.name
;
494 len
= dentry
->d_name
.len
;
496 if (!inode_dir_plugin(parent
)->is_name_acceptable(parent
, name
, len
))
497 /* some arbitrary error code to return */
498 return RETERR(-ENAMETOOLONG
);
500 fsdata
= reiser4_get_dentry_fsdata(dentry
);
502 return PTR_ERR(fsdata
);
504 coord
= &fsdata
->dec
.entry_coord
;
505 coord_clear_iplug(coord
);
508 /* find entry in a directory. This is plugin method. */
509 result
= reiser4_find_entry(parent
, dentry
, &lh
, ZNODE_READ_LOCK
,
512 /* entry was found, extract object key from it. */
515 item_plugin_by_coord(coord
)->s
.dir
.
516 extract_key(coord
, key
));
523 /* helper for reiser4_dir_init_common(): estimate number of blocks to reserve */
524 static reiser4_block_nr
525 estimate_init(struct inode
*parent
, struct inode
*object
)
527 reiser4_block_nr res
= 0;
529 assert("vpf-321", parent
!= NULL
);
530 assert("vpf-322", object
!= NULL
);
532 /* hashed_add_entry(object) */
533 res
+= inode_dir_plugin(object
)->estimate
.add_entry(object
);
534 /* reiser4_add_nlink(object) */
535 res
+= inode_file_plugin(object
)->estimate
.update(object
);
536 /* hashed_add_entry(object) */
537 res
+= inode_dir_plugin(object
)->estimate
.add_entry(object
);
538 /* reiser4_add_nlink(parent) */
539 res
+= inode_file_plugin(parent
)->estimate
.update(parent
);
544 /* helper function for reiser4_dir_init_common(). Create "." and ".." */
545 static int create_dot_dotdot(struct inode
*object
/* object to create dot and
547 struct inode
*parent
/* parent of @object */)
550 struct dentry dots_entry
;
551 reiser4_dir_entry_desc entry
;
553 assert("nikita-688", object
!= NULL
);
554 assert("nikita-689", S_ISDIR(object
->i_mode
));
555 assert("nikita-691", parent
!= NULL
);
557 /* We store dot and dotdot as normal directory entries. This is
558 not necessary, because almost all information stored in them
559 is already in the stat-data of directory, the only thing
560 being missed is objectid of grand-parent directory that can
561 easily be added there as extension.
563 But it is done the way it is done, because not storing dot
564 and dotdot will lead to the following complications:
566 . special case handling in ->lookup().
567 . addition of another extension to the sd.
568 . dependency on key allocation policy for stat data.
572 memset(&entry
, 0, sizeof entry
);
573 memset(&dots_entry
, 0, sizeof dots_entry
);
574 entry
.obj
= dots_entry
.d_inode
= object
;
575 dots_entry
.d_name
.name
= ".";
576 dots_entry
.d_name
.len
= 1;
577 result
= reiser4_add_entry_common(object
, &dots_entry
, NULL
, &entry
);
578 reiser4_free_dentry_fsdata(&dots_entry
);
581 result
= reiser4_add_nlink(object
, object
, 0);
583 entry
.obj
= dots_entry
.d_inode
= parent
;
584 dots_entry
.d_name
.name
= "..";
585 dots_entry
.d_name
.len
= 2;
586 result
= reiser4_add_entry_common(object
,
587 &dots_entry
, NULL
, &entry
);
588 reiser4_free_dentry_fsdata(&dots_entry
);
589 /* if creation of ".." failed, iput() will delete
592 result
= reiser4_add_nlink(parent
, object
, 0);
595 * if we failed to bump i_nlink, try
598 reiser4_detach_common(object
, parent
);
605 * in the case of error, at least update stat-data so that,
606 * ->i_nlink updates are not lingering.
608 reiser4_update_sd(object
);
609 reiser4_update_sd(parent
);
616 * return 0 iff @coord contains a directory entry for the file with the name
620 check_item(const struct inode
*dir
, const coord_t
* coord
, const char *name
)
623 char buf
[DE_NAME_BUF_LEN
];
625 iplug
= item_plugin_by_coord(coord
);
627 warning("nikita-1135", "Cannot get item plugin");
628 print_coord("coord", coord
, 1);
630 } else if (item_id_by_coord(coord
) !=
631 item_id_by_plugin(inode_dir_item_plugin(dir
))) {
632 /* item id of current item does not match to id of items a
633 directory is built of */
634 warning("nikita-1136", "Wrong item plugin");
635 print_coord("coord", coord
, 1);
638 assert("nikita-1137", iplug
->s
.dir
.extract_name
);
640 /* Compare name stored in this entry with name we are looking for.
642 NOTE-NIKITA Here should go code for support of something like
643 unicode, code tables, etc.
645 return !!strcmp(name
, iplug
->s
.dir
.extract_name(coord
, buf
));
649 check_entry(const struct inode
*dir
, coord_t
* coord
, const struct qstr
*name
)
651 return WITH_COORD(coord
, check_item(dir
, coord
, name
->name
));
655 * argument package used by entry_actor to scan entries with identical keys.
657 struct entry_actor_args
{
658 /* name we are looking for */
660 /* key of directory entry. entry_actor() scans through sequence of
661 * items/units having the same key */
663 /* how many entries with duplicate key was scanned so far. */
665 #if REISER4_USE_COLLISION_LIMIT
669 /* return parameter: set to true, if ->name wasn't found */
671 /* what type of lock to take when moving to the next node during
673 znode_lock_mode mode
;
675 /* last coord that was visited during scan */
677 /* last node locked during scan */
679 /* inode of directory */
680 const struct inode
*inode
;
683 /* Function called by reiser4_find_entry() to look for given name
685 static int entry_actor(reiser4_tree
* tree UNUSED_ARG
/* tree being scanned */ ,
686 coord_t
* coord
/* current coord */ ,
687 lock_handle
* lh
/* current lock handle */ ,
688 void *entry_actor_arg
/* argument to scan */ )
690 reiser4_key unit_key
;
691 struct entry_actor_args
*args
;
693 assert("nikita-1131", tree
!= NULL
);
694 assert("nikita-1132", coord
!= NULL
);
695 assert("nikita-1133", entry_actor_arg
!= NULL
);
697 args
= entry_actor_arg
;
699 #if REISER4_USE_COLLISION_LIMIT
700 if (args
->non_uniq
> args
->max_non_uniq
) {
702 /* hash collision overflow. */
703 return RETERR(-EBUSY
);
708 * did we just reach the end of the sequence of items/units with
711 if (!keyeq(args
->key
, unit_key_by_coord(coord
, &unit_key
))) {
712 assert("nikita-1791",
713 keylt(args
->key
, unit_key_by_coord(coord
, &unit_key
)));
715 args
->last_coord
.between
= AFTER_UNIT
;
719 coord_dup(&args
->last_coord
, coord
);
721 * did scan just moved to the next node?
723 if (args
->last_lh
.node
!= lh
->node
) {
727 * if so, lock new node with the mode requested by the caller
729 done_lh(&args
->last_lh
);
730 assert("nikita-1896", znode_is_any_locked(lh
->node
));
731 lock_result
= longterm_lock_znode(&args
->last_lh
, lh
->node
,
732 args
->mode
, ZNODE_LOCK_HIPRI
);
733 if (lock_result
!= 0)
736 return check_item(args
->inode
, coord
, args
->name
);
739 /* Look for given @name within directory @dir.
741 This is called during lookup, creation and removal of directory
742 entries and on reiser4_rename_common
744 First calculate key that directory entry for @name would have. Search
745 for this key in the tree. If such key is found, scan all items with
746 the same key, checking name in each directory entry along the way.
748 int reiser4_find_entry(struct inode
*dir
, /* directory to scan */
749 struct dentry
*de
, /* name to search for */
750 lock_handle
* lh
, /* resulting lock handle */
751 znode_lock_mode mode
, /* required lock mode */
752 reiser4_dir_entry_desc
* entry
/* parameters of found
755 const struct qstr
*name
;
760 struct de_location
*dec
;
761 struct reiser4_dentry_fsdata
*fsdata
;
763 assert("nikita-1130", lh
!= NULL
);
764 assert("nikita-1128", dir
!= NULL
);
767 assert("nikita-1129", name
!= NULL
);
769 /* dentry private data don't require lock, because dentry
770 manipulations are protected by i_mutex on parent.
772 This is not so for inodes, because there is no -the- parent in
775 fsdata
= reiser4_get_dentry_fsdata(de
);
777 return PTR_ERR(fsdata
);
780 coord
= &dec
->entry_coord
;
781 coord_clear_iplug(coord
);
782 seal
= &dec
->entry_seal
;
783 /* compose key of directory entry for @name */
784 inode_dir_plugin(dir
)->build_entry_key(dir
, name
, &entry
->key
);
786 if (reiser4_seal_is_set(seal
)) {
788 result
= reiser4_seal_validate(seal
, coord
, &entry
->key
,
789 lh
, mode
, ZNODE_LOCK_LOPRI
);
791 /* key was found. Check that it is really item we are
793 result
= check_entry(dir
, coord
, name
);
798 flags
= (mode
== ZNODE_WRITE_LOCK
) ? CBK_FOR_INSERT
: 0;
800 * find place in the tree where directory item should be located.
802 result
= reiser4_object_lookup(dir
, &entry
->key
, coord
, lh
, mode
,
803 FIND_EXACT
, LEAF_LEVEL
, LEAF_LEVEL
,
804 flags
, NULL
/*ra_info */ );
805 if (result
== CBK_COORD_FOUND
) {
806 struct entry_actor_args arg
;
808 /* fast path: no hash collisions */
809 result
= check_entry(dir
, coord
, name
);
811 reiser4_seal_init(seal
, coord
, &entry
->key
);
813 } else if (result
> 0) {
814 /* Iterate through all units with the same keys. */
815 arg
.name
= name
->name
;
816 arg
.key
= &entry
->key
;
819 #if REISER4_USE_COLLISION_LIMIT
820 arg
.max_non_uniq
= max_hash_collisions(dir
);
821 assert("nikita-2851", arg
.max_non_uniq
> 1);
825 coord_init_zero(&arg
.last_coord
);
826 init_lh(&arg
.last_lh
);
828 result
= reiser4_iterate_tree
829 (reiser4_tree_by_inode(dir
),
831 entry_actor
, &arg
, mode
, 1);
832 /* if end of the tree or extent was reached during
834 if (arg
.not_found
|| (result
== -E_NO_NEIGHBOR
)) {
838 result
= zload(arg
.last_coord
.node
);
840 coord_clear_iplug(&arg
.last_coord
);
841 coord_dup(coord
, &arg
.last_coord
);
842 move_lh(lh
, &arg
.last_lh
);
843 result
= RETERR(-ENOENT
);
844 zrelse(arg
.last_coord
.node
);
849 done_lh(&arg
.last_lh
);
851 reiser4_seal_init(seal
, coord
, &entry
->key
);
853 if (result
== 0 || result
== -ENOENT
) {
854 assert("nikita-2580", arg
.non_uniq
> 0);
855 dec
->pos
= arg
.non_uniq
- 1;
865 c-indentation-style: "K&R"