@@ -91,8 +91,9 @@ struct {
9191 { \
9292 int khret; \
9393 khiter_t khiter = kh_put(_name, _h, _k, &khret); \
94- ucs_assert((khret == UCS_KH_PUT_BUCKET_EMPTY) || \
95- (khret == UCS_KH_PUT_BUCKET_CLEAR)); \
94+ ucs_assertv((khret == UCS_KH_PUT_BUCKET_EMPTY) || \
95+ (khret == UCS_KH_PUT_BUCKET_CLEAR), \
96+ "khret=%d path=%s", khret, (_node)->path); \
9697 kh_val(_h, khiter) = _node; \
9798 }
9899
@@ -169,31 +170,43 @@ static ucs_vfs_node_t *ucs_vfs_node_create(ucs_vfs_node_t *parent_node,
169170 const char * path ,
170171 ucs_vfs_node_type_t type , void * obj )
171172{
172- ucs_vfs_node_t * node ;
173+ ucs_vfs_node_t * node , * existing_node ;
173174
174175 node = ucs_malloc (sizeof (* node ) + strlen (path ) + 1 , "vfs_node" );
175176 if (node == NULL ) {
176- ucs_error ("Failed to allocate vfs_node" );
177- return NULL ;
177+ ucs_error ("failed to allocate vfs_node" );
178+ goto err ;
178179 }
179180
180- /* initialize node */
181+ /* Initialize node */
181182 ucs_vfs_node_init (node , type , obj , parent_node );
182183 strcpy (node -> path , path );
183184
184- /* add to parent */
185- ucs_list_add_head (& parent_node -> children , & node -> list );
186-
187- /* add to obj hash */
185+ /* Add to object hash */
188186 if (node -> obj != NULL ) {
187+ existing_node = ucs_vfs_node_find_by_obj (node -> obj );
188+ if (existing_node != NULL ) {
189+ ucs_error ("cannot add vfs node '%s', object %p (%s) already exists" ,
190+ node -> path , node -> obj , existing_node -> path );
191+ goto err_free ;
192+ }
193+
189194 ucs_vfs_kh_put (vfs_obj , & ucs_vfs_obj_context .obj_hash ,
190195 (uintptr_t )node -> obj , node );
191196 }
192197
193198 /* add to path hash */
194199 ucs_vfs_kh_put (vfs_path , & ucs_vfs_obj_context .path_hash , node -> path , node );
195200
201+ /* add to parent */
202+ ucs_list_add_head (& parent_node -> children , & node -> list );
203+
196204 return node ;
205+
206+ err_free :
207+ ucs_free (node );
208+ err :
209+ return NULL ;
197210}
198211
199212/* must be called with lock held */
@@ -512,18 +525,22 @@ static void ucs_vfs_path_list_dir_cb(ucs_vfs_node_t *node,
512525static void
513526ucs_vfs_get_link_path (ucs_vfs_node_t * node , ucs_string_buffer_t * strb )
514527{
515- size_t i , n ;
528+ size_t i , n , common_length ;
516529
517530 ucs_assert (ucs_vfs_check_node (node , UCS_VFS_NODE_TYPE_SYM_LINK ));
531+ ucs_assertv (node -> target != NULL , "node=%p node->path=%s" , node ,
532+ node -> path );
518533
519- n = ucs_string_count_char (node -> path , '/' );
534+ common_length = ucs_path_common_parent_length (node -> path ,
535+ node -> target -> path );
536+
537+ n = ucs_string_count_char (& node -> path [common_length ], '/' );
520538 for (i = 1 ; i < n ; ++ i ) {
521539 ucs_string_buffer_appendf (strb , "../" );
522540 }
523541
524- if (node -> target != NULL ) {
525- ucs_string_buffer_appendf (strb , "%s" , & node -> target -> path [1 ]);
526- }
542+ ucs_string_buffer_appendf (strb , "%s" ,
543+ & node -> target -> path [common_length + 1 ]);
527544}
528545
529546ucs_status_t
@@ -635,7 +652,6 @@ ucs_vfs_obj_add_sym_link(void *obj, void *target_obj, const char *rel_path, ...)
635652
636653out :
637654 ucs_spin_unlock (& ucs_vfs_obj_context .lock );
638-
639655 return status ;
640656}
641657
0 commit comments