20
#include <framework/mod/options.h>
21
#include <mem/misc/pool.h>
25
#define DIR_POOL_SIZE OPTION_GET(NUMBER, dir_pool_size)
31
struct timespec mtime;
35
POOL_DEF(dir_pool, DIR, DIR_POOL_SIZE);
37
static int __readdir(DIR *dir) {
41
if (vfs_inode_is_bad(&dir->pos)) {
42
vfs_inode_get_mtime(&dir->inode, &dir->mtime);
44
else if (vfs_inode_is_modified(&dir->inode, &dir->mtime)) {
48
err = dir->inode.sb->drv->ops.readdir(&dir->inode, &dir->pos,
52
dir->pos.ino = VFS_BAD_INO;
53
dir->pos.sb = dir->inode.sb;
56
} while (err && vfs_mount_point_get_prev_bind(&dir->inode, &dir->inode));
61
DIR *opendir(const char *path) {
65
dir = pool_alloc(&dir_pool);
73
err = vfs_path_lookup(path, &dir->inode);
75
vfs_mount_point_get_last(&dir->inode, &dir->inode);
76
vfs_inode_lock(&dir->inode);
79
vfs_inode_ops_unlock();
82
pool_free(&dir_pool, dir);
87
dir->pos.ino = VFS_BAD_INO;
88
dir->pos.sb = dir->inode.sb;
89
dir->end_of_dir = false;
94
int closedir(DIR *dir) {
95
if (!dir->end_of_dir) {
96
vfs_inode_unlock(&dir->inode);
98
pool_free(&dir_pool, dir);
103
struct dirent *readdir(DIR *dir) {
107
if (dir->end_of_dir) {
112
memcpy(&old, &dir->inode, sizeof(struct inode));
114
vfs_inode_ops_lock();
115
err = __readdir(dir);
116
vfs_inode_ops_unlock();
119
dir->end_of_dir = true;
120
vfs_inode_unlock(&dir->inode);
125
if ((dir->inode.ino != old.ino) || (dir->inode.sb != old.sb)) {
126
vfs_inode_lock(&dir->inode);
127
vfs_inode_unlock(&old);