Added a sys_open_entry_ref() call to the VFS layer.

Implemented the beginnings of a Tracker like mode in the fs_shell - started
and stopped using the new "tracker" command; it will get all notifications
the file system sends.
Right now it's very simple, it just opens the file, does a stat(), and closes
the file again, and guess what, I could reproduce our favourite problem with
it!! So it will be finally fixed in the next few days.
Some cleanups.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3559 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2003-06-17 22:02:23 +00:00
parent 57ec89d1b5
commit 55288b8eda
4 changed files with 214 additions and 18 deletions

View File

@ -13,6 +13,7 @@
Dominic Giampaolo
dbg@be.com
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
@ -22,6 +23,7 @@
#include "myfs.h"
#include "kprotos.h"
#include "argv.h"
#include "tracker.h"
#include <fs_attr.h>
#include <fs_query.h>
@ -798,7 +800,7 @@ copydir(char *fromPath,char *toPath)
from = opendir(fromPath);
if (from == NULL) {
printf("could not open %s\n",fromPath);
printf("could not open %s\n", fromPath);
return;
}
@ -813,27 +815,27 @@ copydir(char *fromPath,char *toPath)
dirent_t *attr;
struct stat st;
if (!strcmp(dirent->d_name,".") || !strcmp(dirent->d_name,".."))
if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
continue;
strcpy(from_name, fromPath);
if (from_name[strlen(from_name) - 1] != '/')
strcat(from_name,"/");
strcat(from_name, "/");
strcat(from_name, dirent->d_name);
if (stat(from_name,&st) != 0)
if (stat(from_name, &st) != 0)
continue;
if (st.st_mode & S_IFDIR) {
char path[1024];
strcpy(path,toPath);
strcat(path,"/");
strcat(path,dirent->d_name);
strcpy(path, toPath);
strcat(path, "/");
strcat(path, dirent->d_name);
if ((err = sys_mkdir(1, -1, path, MY_S_IRWXU)) == B_OK)
copydir(from_name,path);
copydir(from_name, path);
else
printf("Could not create directory %s: (%s)\n",path,strerror(err));
printf("Could not create directory %s: (%s)\n", path, strerror(err));
} else {
fd = open(from_name, O_RDONLY);
if (fd < 0) {
@ -841,7 +843,7 @@ copydir(char *fromPath,char *toPath)
return;
}
sprintf(myfs_name, "%s/%s", toPath,dirent->d_name);
sprintf(myfs_name, "%s/%s", toPath, dirent->d_name);
if ((bfd = sys_open(1, -1, myfs_name, O_RDWR|O_CREAT,
MY_S_IFREG|MY_S_IRWXU, 0)) < 0) {
close(fd);
@ -855,7 +857,7 @@ copydir(char *fromPath,char *toPath)
struct attr_info attrInfo;
int32 size = bufferSize, bytesRead;
if (fs_stat_attr(fd,attr->d_name,&attrInfo) != 0)
if (fs_stat_attr(fd, attr->d_name, &attrInfo) != 0)
continue;
if (attrInfo.size <= size)
@ -872,7 +874,8 @@ copydir(char *fromPath,char *toPath)
err = sys_write_attr(1, bfd, attr->d_name, attrInfo.type, buff, size, 0);
if (err < B_OK) {
printf("write attr failed: %s\n",strerror(err));
printf("write attr (\"%s\", type = %p, %p, %ld bytes) failed: %s\n",
attr->d_name, (void *)attrInfo.type, buff, size, strerror(err));
continue;
}
}
@ -978,6 +981,86 @@ do_threadfiletest(int argc, char **argv)
}
port_id gTrackerPort;
static void
tracker_query_file(dev_t device, ino_t parent, char *name)
{
struct stat stat;
int status;
int fd = sys_open_entry_ref(1, device, parent, name, O_RDONLY, 0);
if (fd < 0) {
printf("tracker: could not open file: %s\n", name);
return;
}
status = sys_rstat(true, fd, NULL, &stat, 1);
if (status < 0) {
printf("tracker: could not stat file: %s\n", name);
}
sys_close(true, fd);
}
static int32
tracker_loop(void *data)
{
// create global messaging port
gTrackerPort = create_port(128, "fsh tracker port");
if (gTrackerPort < B_OK)
return gTrackerPort;
while (true) {
update_message message;
uint32 code;
status_t status = read_port(gTrackerPort, &code, &message, sizeof(message));
if (status < B_OK)
continue;
if (code == FSH_KILL_TRACKER)
break;
if (code == FSH_NOTIFY_LISTENER) {
printf("tracker: notify listener received\n");
tracker_query_file(message.device, message.parentNode, message.name);
} else if (code == B_QUERY_UPDATE) {
printf("tracker: query update received\n");
tracker_query_file(message.device, message.parentNode, message.name);
} else {
printf("tracker: unknown code received: 0x%lx\n", code);
}
}
delete_port(gTrackerPort);
}
static void
do_tracker(int argc, char **argv)
{
static thread_id thread = -1;
if (thread < B_OK) {
puts("starting tracker...");
thread = spawn_thread(tracker_loop, "tracker", B_NORMAL_PRIORITY, NULL);
resume_thread(thread);
} else {
status_t status;
puts("stopping tracker.");
write_port(gTrackerPort, FSH_KILL_TRACKER, NULL, 0);
wait_for_thread(thread, &status);
thread = -1;
}
}
static void
do_attrtest(int argc, char **argv)
{
@ -1412,6 +1495,7 @@ cmd_entry fsh_cmds[] =
{ "cptest", do_copytest, "copies all files from the given path" },
{ "threads", do_threadtest, "copies several files, and does a lat_fs simulaneously" },
{ "mfile", do_threadfiletest, "copies several big files simulaneously" },
{ "tracker", do_tracker, "starts a Tracker like background thread that will listen to fs updates" },
{ "cio", do_cio, "does a I/O speed test" },
// additional commands from the file system will be included here

View File

@ -20,6 +20,7 @@
#include "lock.h"
#include "fsproto.h"
#include "kprotos.h"
#include "tracker.h"
#include <sys/stat.h>
@ -1059,6 +1060,74 @@ errorA:
}
int
sys_open_entry_ref(bool kernel, nspace_id device, vnode_id parent, const char *name,
int openMode, bool coe)
{
int err;
vnode *vn;
vnode_id vnid;
void *cookie;
ofile *f;
int nfd;
fdarray *fds;
op_create *opc;
op_open *opo;
op_free_cookie *opf;
err = get_file_vn(device, parent, name, TRUE, &vn);
if (err)
return err;
opo = vn->ns->fs->ops.open;
if (!opo) {
err = EINVAL;
goto error1;
}
err = (*opo)(vn->ns->data, vn->data, openMode, &cookie);
if (err)
goto error1;
/*
* find a file descriptor
*/
f = (ofile *)calloc(sizeof(ofile), 1);
if (!f) {
err = ENOMEM;
goto error2;
}
f->type = FD_FILE;
f->vn = vn;
f->cookie = cookie;
f->ocnt = 0;
f->rcnt = 0;
f->pos = 0;
f->omode = openMode;
nfd = new_fd(kernel, -1, f, -1, coe);
if (nfd < 0) {
err = EMFILE;
goto error3;
}
return nfd;
error3:
free(f);
error2:
(*vn->ns->fs->ops.close)(vn->ns->data, vn->data, cookie);
opf = vn->ns->fs->ops.free_cookie;
if (opf)
(*opf)(vn->ns->data, vn->data, cookie);
error1:
dec_vnode(vn, FALSE);
return err;
}
/*
* sys_close
*/
@ -3205,7 +3274,8 @@ notify_listener(int op, nspace_id nsid, vnode_id vnida, vnode_id vnidb, vnode_id
}
printf("notify_listener: %s\n", text);
#endif
return 0;
return send_notification(0, 0, FSH_NOTIFY_LISTENER, op, nsid, -1, vnida, vnidb, vnidc, name);
}
@ -3214,11 +3284,27 @@ send_notification(port_id port, long token, ulong what, long op, nspace_id nsida
nspace_id nsidb, vnode_id vnida, vnode_id vnidb, vnode_id vnidc,
const char *name)
{
update_message message;
#ifdef DEBUG
printf("send_notification... op = %s, name = %s, port = %ld, token = %ld\n",
op == B_ENTRY_CREATED ? "B_ENTRY_CREATED" : "B_ENTRY_REMOVED", name, port, token);
#endif
return 0;
message.op = op;
message.device = nsida;
message.toDevice = nsidb;
message.parentNode = vnida;
message.targetNode = vnidb;
message.node = vnidc;
if (name != NULL) {
strcpy(message.name, name);
// name is 256 character at maximum
} else
message.name[0] = '\0';
return write_port(gTrackerPort, what, &message, sizeof(message));
}

View File

@ -2,17 +2,18 @@
#define my_dirent dirent
int sys_symlink(bool kernel, const char *oldpath, int nfd,
const char *newpath);
const char *newpath);
ssize_t sys_readlink(bool kernel, int fd, const char *path, char *buf,
size_t bufsize);
size_t bufsize);
int sys_mkdir(bool kernel, int fd, const char *path, int perms);
int sys_open(bool kernel, int fd, const char *path, int omode,
int perms, bool coe);
int perms, bool coe);
int sys_open_entry_ref(bool kernel, nspace_id device, vnode_id parent,
const char *name, int openMode, bool coe);
int sys_close(bool kernel, int fd);
fs_off_t sys_lseek(bool kernel, int fd, fs_off_t pos, int whence);
ssize_t sys_read(bool kernel, int fd, void *buf, size_t len);
ssize_t sys_write(bool kernel, int fd, void *buf, size_t len);
int sys_ioctl(bool kernel, int fd, int cmd, void *arg, size_t sz);
int sys_unlink(bool kernel, int fd, const char *path);
int sys_link(bool kernel, int ofd, const char *oldpath, int nfd,
const char *newpath);

View File

@ -0,0 +1,25 @@
#ifndef TRACKER_H
#define TRACKER_H
#include <SupportDefs.h>
#include <AppDefs.h>
#include <sys/types.h>
#define FSH_KILL_TRACKER 'kill'
#define FSH_NOTIFY_LISTENER 'notl'
typedef struct update_message {
int32 op;
dev_t device;
dev_t toDevice;
ino_t parentNode;
ino_t targetNode;
ino_t node;
char name[B_FILE_NAME_LENGTH];
} update_message;
extern port_id gTrackerPort;
#endif /* TRACKER_H */