aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/user/nullfs.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-19 18:53:15 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-19 18:53:15 +0100
commit62e5a35940198f0f8fbabdf31c80455647420c4e (patch)
treed73846d90d0611125eb99b53e473f8bc76c7fa15 /src/kernel/user/nullfs.c
parent277b329c5609b8172ad0c142117edfa9a08279da (diff)
downloadkogata-62e5a35940198f0f8fbabdf31c80455647420c4e.tar.gz
kogata-62e5a35940198f0f8fbabdf31c80455647420c4e.zip
Several things :
- disambiguate syscall.h : kernel syscall.h moved to sct.h - fix btree_remove_v !! (munmap fucked up stuff before) - make nullfs's directory listing non-exclusive (it actually copies the listing on open() and readdir()'s from that copy)
Diffstat (limited to 'src/kernel/user/nullfs.c')
-rw-r--r--src/kernel/user/nullfs.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c
index 3065192..50baeff 100644
--- a/src/kernel/user/nullfs.c
+++ b/src/kernel/user/nullfs.c
@@ -102,14 +102,15 @@ typedef struct {
nullfs_item_t *items_list;
hashtbl_t *items_idx;
- mutex_t lock; // always locked when open (cannot create/delete/move)
+ mutex_t lock;
nullfs_t *fs;
} nullfs_dir_t;
typedef struct {
- nullfs_item_t *it;
nullfs_dir_t *d;
+ int nitems, i;
+ dirent_t *items;
} nullfs_dh_t;
typedef struct {
@@ -118,7 +119,7 @@ typedef struct {
bool own_data;
int ok_modes;
- mutex_t lock;
+ mutex_t lock; // locked on open
} nullfs_file_t;
// No nullfs_file_handle_t struct, we don't need it. The handle's data
@@ -241,19 +242,45 @@ bool nullfs_d_open(fs_node_ptr n, int mode, fs_handle_t *s) {
if (!got_lock) return false;
nullfs_dh_t *h = (nullfs_dh_t*)malloc(sizeof(nullfs_dh_t));
- if (h == 0) {
- mutex_unlock(&d->lock);
- return false;
+ if (h == 0) goto fail;
+
+ h->nitems = hashtbl_count(d->items_idx);
+ if (h->nitems > 0) {
+ h->items = (dirent_t*)malloc(h->nitems * sizeof(dirent_t));
+ if (h->nitems == 0) goto fail;
+
+ int i = 0;
+ for (nullfs_item_t *it = d->items_list; it != 0; it = it->next) {
+ strncpy(h->items[i].name, it->name, DIR_MAX);
+ h->items[i].name[DIR_MAX-1] = 0; // make sur it's null-terminated
+ if (it->ops->stat) {
+ it->ops->stat(it->data, &h->items[i].st);
+ } else {
+ // no stat operation : should we do something else ?
+ memset(&h->items[i].st, 0, sizeof(stat_t));
+ }
+
+ i++;
+ }
+ ASSERT(i == h->nitems);
}
- h->it = d->items_list;
h->d = d;
+ h->i = 0;
s->data = h;
s->ops = &nullfs_dh_ops;
s->mode = FM_READDIR;
+ mutex_unlock(&d->lock);
+
return true;
+
+fail:
+ mutex_unlock(&d->lock);
+ if (h && h->items) free(h->items);
+ if (h) free(h);
+ return false;
}
bool nullfs_d_stat(fs_node_ptr n, stat_t *st) {
@@ -445,19 +472,11 @@ void nullfs_d_dispose(fs_node_ptr n) {
bool nullfs_dh_readdir(fs_handle_ptr f, dirent_t *d) {
nullfs_dh_t *h = (nullfs_dh_t*)f;
- if (h->it == 0) {
+ if (h->i >= h->nitems) {
return false;
} else {
- strncpy(d->name, h->it->name, DIR_MAX);
- d->name[DIR_MAX-1] = 0; // make sur it's null-terminated
- if (h->it->ops->stat) {
- h->it->ops->stat(h->it->data, &d->st);
- } else {
- // no stat operation : should we do something else ?
- memset(&d->st, 0, sizeof(stat_t));
- }
- h->it = h->it->next;
-
+ memcpy(d, &h->items[h->i], sizeof(dirent_t));
+ h->i++;
return true;
}
}
@@ -465,8 +484,7 @@ bool nullfs_dh_readdir(fs_handle_ptr f, dirent_t *d) {
void nullfs_dh_close(fs_handle_ptr f) {
nullfs_dh_t *h = (nullfs_dh_t*)f;
- mutex_unlock(&h->d->lock);
-
+ if (h->items) free(h->items);
free(h);
}