diff --git a/src/tests/add-ons/kernel/file_systems/fs_shell/fsh.c b/src/tests/add-ons/kernel/file_systems/fs_shell/fsh.c index 8416d857b6..9cb27d39e0 100644 --- a/src/tests/add-ons/kernel/file_systems/fs_shell/fsh.c +++ b/src/tests/add-ons/kernel/file_systems/fs_shell/fsh.c @@ -24,6 +24,7 @@ #include "argv.h" #include +#include static void do_lat_fs(int argc, char **argv); static void do_fsh(void); @@ -1060,6 +1061,50 @@ do_sync(int argc, char **argv) } +void *gQueryCookie = NULL; + + +static void +do_stopquery(int argc, char **argv) +{ + int err; + + if (gQueryCookie == NULL) { + printf("no query running (use the 'startquery' command to start a query).\n"); + return; + } + + err = sys_close_query(true, -1, "/myfs/.", gQueryCookie); + if (err < 0) { + printf("could not close query: %s\n", strerror(err)); + return; + } + + gQueryCookie = NULL; +} + + +static void +do_startquery(int argc, char **argv) +{ + char *query; + int err; + + if (argc != 2) { + printf("query string expected"); + return; + } + query = argv[1]; + + err = sys_open_query(true, -1, "/myfs/.", query, B_LIVE_QUERY, &gQueryCookie); + if (err < 0) { + printf("could not open query: %s\n", strerror(err)); + return; + } else + printf("query started - use the 'stopquery' command to stop it."); +} + + static void do_query(int argc, char **argv) { @@ -1076,14 +1121,14 @@ do_query(int argc, char **argv) } query = argv[1]; - err = sys_open_query(true,-1,"/myfs/.",query,&cookie); + err = sys_open_query(true, -1, "/myfs/.", query, 0, &cookie); if (err < 0) { - printf("could not open query: %s\n",strerror(err)); + printf("could not open query: %s\n", strerror(err)); return; } while (true) { - err = sys_read_query(true,-1,"/myfs/.",cookie, dent, sizeof(buffer), 1); + err = sys_read_query(true, -1, "/myfs/.", cookie, dent, sizeof(buffer), 1); if (err < 0) { printf("readdir failed for: %s\n", dent->d_name); if (max_err-- <= 0) @@ -1095,12 +1140,12 @@ do_query(int argc, char **argv) if (err == 0) break; - printf("%s\n",dent->d_name); + printf("%s\n", dent->d_name); } - err = sys_close_query(true,-1,"/myfs/.",cookie); + err = sys_close_query(true, -1, "/myfs/.", cookie); if (err < 0) { - printf("could not close query: %s\n",strerror(err)); + printf("could not close query: %s\n", strerror(err)); return; } } @@ -1307,6 +1352,8 @@ cmd_entry fsh_cmds[] = { "create", do_create, "create N files. default is 100" }, { "delete", do_delete, "delete N files. default is 100" }, { "query", do_query, "run a query on the file system" }, + { "startquery", do_startquery, "run a live query on the file system" }, + { "stopquery", do_stopquery, "stops the live query" }, { "ioctl", do_ioctl, "execute ioctl() without an inode (okay, with the root node)" }, { "fcntl", do_fcntl, "execute ioctl() with the active inode" }, { "cptest", do_copytest, "copies all files from the given path" }, diff --git a/src/tests/add-ons/kernel/file_systems/fs_shell/kernel.c b/src/tests/add-ons/kernel/file_systems/fs_shell/kernel.c index 2fd28e1424..621f800893 100644 --- a/src/tests/add-ons/kernel/file_systems/fs_shell/kernel.c +++ b/src/tests/add-ons/kernel/file_systems/fs_shell/kernel.c @@ -215,9 +215,15 @@ static int free_fds(fdarray *fds); #include static void -PANIC(char *s) +PANIC(char *s, ...) { - printf(s); + va_list list; + + va_start(list, s); + vfprintf(stdout, s, list); + va_end(list); + + exit(-1); } @@ -1821,7 +1827,7 @@ error1: int -sys_open_query(bool kernel, int fd, const char *path, const char *query, void **cookie) +sys_open_query(bool kernel, int fd, const char *path, const char *query, ulong flags, void **cookie) { int err; nspace *ns; @@ -1842,7 +1848,7 @@ sys_open_query(bool kernel, int fd, const char *path, const char *query, void ** dec_vnode(root, FALSE); return EPERM; } - err = (*fs->ops.open_query)(ns->data, query, 0, -1, 0, cookie); + err = (*fs->ops.open_query)(ns->data, query, flags, -1, 0, cookie); printf("sys_open_query() -- end: %d\n",err); dec_vnode(root, FALSE); @@ -2232,11 +2238,38 @@ put_vnode(nspace_id nsid, vnode_id vnid) int new_vnode(nspace_id nsid, vnode_id vnid, void *data) { - int err; - vnode *vn; + int retries = 20; + vnode *vn; + int err; - LOCK(vnlock); - vn = steal_vnode(FREE_LIST); + LOCK(vnlock); + +restart: + if ((vn = lookup_vnode(nsid, vnid)) != NULL) { + // oh, we requested a new vnode although there already + // exist one - compare the private node data and bail + // out if needed. + + if (vn->busy) { + printf("new_vnode(): vnode exists and is busy!\n"); + snooze(500); + if (retries-- >= 0) + goto restart; + + printf("new_vnode(): still busy, but continue to our doom!\n"); + } + + if (vn->data != data) + PANIC("new_vnode(): vnode already exists with different data (vnode id = %Ld)!\n", vnid); + else { + printf("new_vnode(): vnode already exists with the same data (vnode id = %Ld)\n", vnid); + vn->rcnt++; + return; + UNLOCK(vnlock); + } + } + + vn = steal_vnode(FREE_LIST); if (!vn) { vn = steal_vnode(USED_LIST); if (!vn) { diff --git a/src/tests/add-ons/kernel/file_systems/fs_shell/kprotos.h b/src/tests/add-ons/kernel/file_systems/fs_shell/kprotos.h index 9b5229d539..41a5c607e9 100644 --- a/src/tests/add-ons/kernel/file_systems/fs_shell/kprotos.h +++ b/src/tests/add-ons/kernel/file_systems/fs_shell/kprotos.h @@ -43,7 +43,7 @@ ssize_t sys_read_attr(bool kernel, int fd, const char *name, int type, void *buf ssize_t sys_write_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos); ssize_t sys_remove_attr(bool kernel, int fd, const char *name); -int sys_open_query(bool kernel, int fd, const char *path, const char *query, void **cookie); +int sys_open_query(bool kernel, int fd, const char *path, const char *query, ulong flags, void **cookie); int sys_close_query(bool kernel, int fd, const char *path, void *cookie); int sys_read_query(bool kernel, int fd, const char *path, void *cookie,struct dirent *dent,size_t bufferSize,long num);