@@ -525,6 +525,7 @@ int dfs_elm_close(struct dfs_file *file)
525525 dir = (DIR * )(file -> vnode -> data );
526526 RT_ASSERT (dir != RT_NULL );
527527
528+ f_closedir (dir );
528529 /* release memory */
529530 rt_free (dir );
530531 }
@@ -1017,10 +1018,27 @@ static struct dfs_vnode *dfs_elm_create_vnode(struct dfs_dentry *dentry, int typ
10171018
10181019static int dfs_elm_free_vnode (struct dfs_vnode * vnode )
10191020{
1020- /* nothing to be freed */
1021- if (vnode && vnode -> ref_count <= 1 )
1021+ /* free_vnode is the backstop destruction point: called from
1022+ dfs_vnode_unref when ref_count drops to 0, and from dfs_vnode_destroy on
1023+ a create/lookup failure (ref_count == 1). Normally dfs_elm_close has
1024+ already released the resource and set data = NULL, so this is a no-op.
1025+ It only tears down the resource when close bailed out early due to
1026+ ref_count > 1 (a transient lookup had raised it), which is exactly the
1027+ leak this guards against. data != NULL means the resource is still
1028+ live and the lock is still initialized, so both are released here. */
1029+ if (vnode && vnode -> ref_count <= 1 && vnode -> data != RT_NULL )
10221030 {
1023- vnode -> data = NULL ;
1031+ if (vnode -> type == FT_DIRECTORY )
1032+ {
1033+ f_closedir ((DIR * )vnode -> data );
1034+ }
1035+ else if (vnode -> type == FT_REGULAR )
1036+ {
1037+ f_close ((FIL * )vnode -> data );
1038+ }
1039+ rt_free (vnode -> data );
1040+ vnode -> data = RT_NULL ;
1041+ rt_mutex_detach (& vnode -> lock );
10241042 }
10251043
10261044 return 0 ;
0 commit comments