diff options
author | gleb <gleb@FreeBSD.org> | 2013-01-06 22:15:44 +0000 |
---|---|---|
committer | gleb <gleb@FreeBSD.org> | 2013-01-06 22:15:44 +0000 |
commit | 97e76936ec964af173aff961044216c92d94a32a (patch) | |
tree | 4e0ee484516d2c8b1675a7e1d18d741bc663bfb9 /sys/fs/tmpfs/tmpfs_vfsops.c | |
parent | 580a3aadfb3f2d64b5a4b1b464d338e3c211b1ea (diff) | |
download | FreeBSD-src-97e76936ec964af173aff961044216c92d94a32a.zip FreeBSD-src-97e76936ec964af173aff961044216c92d94a32a.tar.gz |
tmpfs: Replace directory entry linked list with RB-Tree.
Use file name hash as a tree key, handle duplicate keys. Both VOP_LOOKUP
and VOP_READDIR operations utilize same tree for search. Directory
entry offset (cookie) is either file name hash or incremental id in case
of hash collisions (duplicate-cookies). Keep sorted per directory list
of duplicate-cookie entries to facilitate cookie number allocation.
Don't fail if previous VOP_READDIR() offset is no longer valid, start
with next dirent instead. Other file system handle it similarly.
Workaround race prone tn_readdir_last[pn] fields update.
Add tmpfs_dir_destroy() to free all dirents.
Set NFS cookies in tmpfs_dir_getdents(). Return EJUSTRETURN from
tmpfs_dir_getdents() instead of hard coded -1.
Mark directory traversal routines static as they are no longer
used outside of tmpfs_subr.c
Diffstat (limited to 'sys/fs/tmpfs/tmpfs_vfsops.c')
-rw-r--r-- | sys/fs/tmpfs/tmpfs_vfsops.c | 15 |
1 files changed, 2 insertions, 13 deletions
diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index b2aa786..8cf8693 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -294,19 +294,8 @@ tmpfs_unmount(struct mount *mp, int mntflags) while (node != NULL) { struct tmpfs_node *next; - if (node->tn_type == VDIR) { - struct tmpfs_dirent *de; - - de = TAILQ_FIRST(&node->tn_dir.tn_dirhead); - while (de != NULL) { - struct tmpfs_dirent *nde; - - nde = TAILQ_NEXT(de, td_entries); - tmpfs_free_dirent(tmp, de, FALSE); - de = nde; - node->tn_size -= sizeof(struct tmpfs_dirent); - } - } + if (node->tn_type == VDIR) + tmpfs_dir_destroy(tmp, node); next = LIST_NEXT(node, tn_entries); tmpfs_free_node(tmp, node); |