summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--console/ChangeLog17
-rw-r--r--console/Makefile4
-rw-r--r--console/console.c79
-rw-r--r--console/display.c29
-rw-r--r--hurd/ChangeLog9
-rw-r--r--hurd/fs_notify.defs21
-rw-r--r--hurd/hurd_types.defs13
-rw-r--r--hurd/hurd_types.h1
-rw-r--r--libdiskfs/ChangeLog20
-rw-r--r--libdiskfs/Makefile3
-rw-r--r--libdiskfs/dir-chg.c12
-rw-r--r--libdiskfs/diskfs.h2
-rw-r--r--libdiskfs/file-chg.c14
-rw-r--r--libdiskfs/node-make.c2
-rw-r--r--libdiskfs/ourfs_notify.defs5
15 files changed, 199 insertions, 32 deletions
diff --git a/console/ChangeLog b/console/ChangeLog
index 2432860b..b9d85c97 100644
--- a/console/ChangeLog
+++ b/console/ChangeLog
@@ -1,3 +1,20 @@
+2002-06-27 Marcus Brinkmann <marcus@gnu.org>
+
+ * Makefile (MIGSTUBS): Add fs_notifyUser.o.
+ (MIGSFLAGS): New variable.
+ * console.c: Include "fs_notify_U.h".
+ (struct modreq): New structure.
+ (struct cons): New members DIRMOD_REQS and DIRMOD_TICK.
+ (cons_notice_dirchange): New function.
+ (vcons_lookup): Call cons_notice_dirchange.
+ (netfs_S_dir_notice_changes): New function.
+ (main): Initialize new members in CONS.
+ * display.c (nowait_file_changed): Update to new interface (new
+ argument TICKNO).
+ (do_mach_notify_msg_accepted): Call nowait_file_changed with new argument.
+ (display_notice_changes): Likewise.
+ (display_notice_filechange): Likewise.
+
2002-06-25 Marcus Brinkmann <marcus@gnu.org>
* Makefile (HURDLIBS): Add pager, reported by Alfred M. Szmidt.
diff --git a/console/Makefile b/console/Makefile
index a9a15e8c..434d80e6 100644
--- a/console/Makefile
+++ b/console/Makefile
@@ -26,11 +26,13 @@ target = console
SRCS = console.c display.c input.c
LCLHDRS = console.h display.h input.h priv.h mutations.h
-MIGSTUBS = notifyServer.o tioctlServer.o
+MIGSTUBS = notifyServer.o tioctlServer.o fs_notifyUser.o
HURDLIBS = netfs fshelp iohelp pager threads ports ihash shouldbeinlibc
OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS))
+MIGSFLAGS += -imacros $(srcdir)/mutations.h
+
# This is the old monolithic version of the console server.
#SRCS = main.c vcons.c focus.c vga-display.c vga.c dynafont.c bdf.c
#LCLHDRS = focus.h input-drv.h vcons.h display-drv.h vga.h vga-hw.h \
diff --git a/console/console.c b/console/console.c
index d75cf9c7..d25a3cf3 100644
--- a/console/console.c
+++ b/console/console.c
@@ -43,6 +43,8 @@
/* We include console.h for the color numbers. */
#include "console.h"
+#include "fs_notify_U.h"
+
const char *argp_program_version = STANDARD_HURD_VERSION (console);
char *netfs_server_name = "console";
@@ -91,6 +93,13 @@ struct vcons
struct node *inpt_node;
};
+/* Pending directory modification requests. */
+struct modreq
+{
+ mach_port_t port;
+ struct modreq *next;
+};
+
struct cons
{
/* The lock protects the console, all virtual consoles contained in
@@ -104,6 +113,10 @@ struct cons
int foreground;
int background;
+ /* Requester of directory modification notifications. */
+ struct modreq *dirmod_reqs;
+ unsigned int dirmod_tick;
+
struct node *node;
mach_port_t underlying;
/* A template for the stat information of all nodes. */
@@ -111,6 +124,32 @@ struct cons
};
+/* Requires CONS to be locked. */
+static void
+cons_notice_dirchange (cons_t cons, dir_changed_type_t type, char *name)
+{
+ error_t err;
+ struct modreq **preq = &cons->dirmod_reqs;
+
+ cons->dirmod_tick++;
+ while (*preq)
+ {
+ struct modreq *req = *preq;
+
+ err = dir_changed (req->port, cons->dirmod_tick, type, name);
+ if (err && err != MACH_SEND_TIMEOUT)
+ {
+ /* Remove notify port. */
+ *preq = req->next;
+ mach_port_deallocate (mach_task_self (), req->port);
+ free (req);
+ }
+ else
+ preq = &req->next;
+ }
+}
+
+
/* Lookup the virtual console with number ID in the console CONS,
acquire a reference for it, and return it in R_VCONS. If CREATE is
true, the virtual console will be created if it doesn't exist yet.
@@ -215,6 +254,8 @@ vcons_lookup (cons_t cons, int id, int create, vcons_t *r_vcons)
}
cons->vcons_list = vcons;
}
+ cons_notice_dirchange (cons, DIR_CHANGED_NEW, vcons->name);
+
mutex_unlock (&cons->lock);
*r_vcons = vcons;
return 0;
@@ -253,6 +294,8 @@ vcons_release (vcons_t vcons)
if (vcons->next)
vcons->next->prev = vcons->prev;
+ cons_notice_dirchange (cons, DIR_CHANGED_UNLINK, vcons->name);
+
/* XXX Destroy the state. */
display_destroy (vcons->display);
input_destroy (vcons->input);
@@ -1186,6 +1229,40 @@ netfs_S_io_map (struct protid *cred,
kern_return_t
+netfs_S_dir_notice_changes (struct protid *cred, mach_port_t notify)
+{
+ error_t err;
+ cons_t cons;
+ struct modreq *req;
+
+ if (!cred)
+ return EOPNOTSUPP;
+
+ cons = cred->po->np->nn->cons;
+ if (!cons)
+ return EOPNOTSUPP;
+
+ mutex_lock (&cons->lock);
+ err = dir_changed (notify, cons->dirmod_tick, DIR_CHANGED_NULL, "");
+ if (err)
+ {
+ mutex_unlock (&cons->lock);
+ return err;
+ }
+ req = malloc (sizeof (struct modreq));
+ if (!req)
+ {
+ mutex_unlock (&cons->lock);
+ return errno;
+ }
+ req->port = notify;
+ req->next = cons->dirmod_reqs;
+ cons->dirmod_reqs = req;
+ mutex_unlock (&cons->lock);
+ return 0;
+}
+
+kern_return_t
netfs_S_file_notice_changes (struct protid *cred, mach_port_t notify)
{
struct node *np;
@@ -1676,6 +1753,8 @@ main (int argc, char **argv)
cons->foreground = DEFAULT_FOREGROUND;
cons->background = DEFAULT_BACKGROUND;
cons->vcons_list = NULL;
+ cons->dirmod_reqs = NULL;
+ cons->dirmod_tick = 0;
root_nn.cons = cons;
/* Parse our command line arguments (all none of them). */
diff --git a/console/display.c b/console/display.c
index a418ca73..7765af8e 100644
--- a/console/display.c
+++ b/console/display.c
@@ -291,12 +291,15 @@ static struct port_class *notify_class;
/* SimpleRoutine file_changed */
kern_return_t
-nowait_file_changed (mach_port_t notify_port, file_changed_type_t change,
+nowait_file_changed (mach_port_t notify_port, natural_t tickno,
+ file_changed_type_t change,
off_t start, off_t end, mach_port_t notify)
{
typedef struct
{
mach_msg_header_t Head;
+ mach_msg_type_t ticknoType;
+ natural_t tickno;
mach_msg_type_t changeType;
file_changed_type_t change;
mach_msg_type_t startType;
@@ -309,7 +312,17 @@ nowait_file_changed (mach_port_t notify_port, file_changed_type_t change,
Request In;
} Mess;
register Request *InP = &Mess.In;
-
+
+ static const mach_msg_type_t ticknoType = {
+ /* msgt_name = */ 2,
+ /* msgt_size = */ 32,
+ /* msgt_number = */ 1,
+ /* msgt_inline = */ TRUE,
+ /* msgt_longform = */ FALSE,
+ /* msgt_deallocate = */ FALSE,
+ /* msgt_unused = */ 0
+ };
+
static const mach_msg_type_t changeType = {
/* msgt_name = */ 2,
/* msgt_size = */ 32,
@@ -340,6 +353,8 @@ nowait_file_changed (mach_port_t notify_port, file_changed_type_t change,
/* msgt_unused = */ 0
};
+ InP->ticknoType = ticknoType;
+ InP->tickno = tickno;
InP->changeType = changeType;
InP->change = change;
InP->startType = startType;
@@ -356,11 +371,11 @@ nowait_file_changed (mach_port_t notify_port, file_changed_type_t change,
if (notify == MACH_PORT_NULL)
return mach_msg (&InP->Head, MACH_SEND_MSG | MACH_MSG_OPTION_NONE,
- 48, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
+ 56, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL);
else
return mach_msg (&InP->Head, MACH_SEND_MSG | MACH_SEND_NOTIFY,
- 48, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
+ 56, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
notify);
}
@@ -435,7 +450,7 @@ do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t send)
/* A request was desired while we were blocking. Send it now
and stay in pending queue. */
req->pending = 0;
- err = nowait_file_changed (req->port, FILE_CHANGED_WRITE, -1, -1,
+ err = nowait_file_changed (req->port, 0, FILE_CHANGED_WRITE, -1, -1,
notify);
if (err && err != MACH_SEND_WILL_NOTIFY)
{
@@ -484,7 +499,7 @@ display_notice_changes (display_t display, mach_port_t notify)
struct modreq *req;
mutex_lock (&display->lock);
- err = nowait_file_changed (notify, FILE_CHANGED_NULL, 0, 0, MACH_PORT_NULL);
+ err = nowait_file_changed (notify, 0, FILE_CHANGED_NULL, 0, 0, MACH_PORT_NULL);
if (err)
{
mutex_unlock (&display->lock);
@@ -523,7 +538,7 @@ display_notice_filechange (display_t display)
{
req = *preq;
- err = nowait_file_changed (req->port, FILE_CHANGED_WRITE, -1, -1,
+ err = nowait_file_changed (req->port, 0, FILE_CHANGED_WRITE, -1, -1,
notify_port);
if (err)
{
diff --git a/hurd/ChangeLog b/hurd/ChangeLog
index 33eefc82..6d69acc8 100644
--- a/hurd/ChangeLog
+++ b/hurd/ChangeLog
@@ -1,3 +1,12 @@
+2002-06-26 Marcus Brinkmann <marcus@gnu.org>
+
+ * fs_notify.defs: Add MsgOption for send timeout.
+ (dir_changed): Changed to simpleroutine. Change type of first
+ argument to fs_notify_t. Add TICKNO argument.
+ (file_changed): Likewise.
+ * hurd_types.defs (fs_notify_t): New type.
+ * hurd_types.h (fs_notify_t): Likewise.
+
2002-06-14 Roland McGrath <roland@frob.com>
* paths.h (_SERVERS_DEFPAGER): New macro.
diff --git a/hurd/fs_notify.defs b/hurd/fs_notify.defs
index ce53eb44..3a30fe6d 100644
--- a/hurd/fs_notify.defs
+++ b/hurd/fs_notify.defs
@@ -25,22 +25,31 @@ subsystem fs_notify 20500;
FS_NOTIFY_IMPORTS
#endif
+/* For maximum robustness, the server must not wait for the client to
+ receive the notification message. This is achieved by setting a
+ send timeout (XXX which is implicitely 0 with MACH_MSG_TIMEOUT_NONE). */
+MsgOption MACH_SEND_TIMEOUT;
/* This is sent by a filesystem (after being requested with
dir_notice_changes) every time a directory is changed.
CHANGE identifies the sort of change that has occurred (see hurd_types.h);
- NAME is the name that was changed. */
-routine dir_changed (
- notify_port: mach_port_t;
+ NAME is the name that was changed. TICKNO is a sequential number
+ that allows the client to verify that it got all notifications. */
+simpleroutine dir_changed (
+ notify_port: fs_notify_t;
+ tickno: natural_t;
change: dir_changed_type_t;
name: string_t);
/* This is sent by a filesystem (after being requested with
file_notice_changes) every time a file or its stat info is changed.
CHANGE identifies the sort of change that has occurred (see hurd_types.h);
- START and END identify the affected regions of the file's data. */
-routine file_changed (
- notify_port: mach_port_t;
+ START and END identify the affected regions of the file's data.
+ TICKNO is a sequential number that allows the client to verify that
+ it got all notifications. */
+simpleroutine file_changed (
+ notify_port: fs_notify_t;
+ tickno: natural_t;
change: file_changed_type_t;
start: loff_t;
end: loff_t);
diff --git a/hurd/hurd_types.defs b/hurd/hurd_types.defs
index 3771c4a1..e8677375 100644
--- a/hurd/hurd_types.defs
+++ b/hurd/hurd_types.defs
@@ -144,6 +144,19 @@ destructor: STARTUP_DESTRUCTOR
#endif
;
+type fs_notify_t = mach_port_copy_send_t
+#ifdef FS_NOTIFY_INTRAN
+intran: FS_NOTIFY_INTRAN
+#endif
+#ifdef FS_NOTIFY_OUTTRAN
+outtran: FS_NOTIFY_OUTTRAN
+#endif
+#ifdef FS_NOTIFY_DESTRUCTOR
+destructor: FS_NOTIFY_DESTRUCTOR
+#endif
+;
+
+
type proccoll_t = mach_port_copy_send_t;
type sreply_port_t = MACH_MSG_TYPE_MAKE_SEND_ONCE | polymorphic
diff --git a/hurd/hurd_types.h b/hurd/hurd_types.h
index b957a0bf..86b9bcbe 100644
--- a/hurd/hurd_types.h
+++ b/hurd/hurd_types.h
@@ -44,6 +44,7 @@ typedef mach_port_t socket_t;
typedef mach_port_t pf_t; /* Protocol family */
typedef mach_port_t addr_port_t;
typedef mach_port_t startup_t;
+typedef mach_port_t fs_notify_t;
typedef mach_port_t proccoll_t;
#include <errno.h> /* Defines `error_t'. */
diff --git a/libdiskfs/ChangeLog b/libdiskfs/ChangeLog
index 6d30f75c..27879c7c 100644
--- a/libdiskfs/ChangeLog
+++ b/libdiskfs/ChangeLog
@@ -1,3 +1,23 @@
+2002-06-26 Marcus Brinkmann <marcus@gnu.org>
+
+ * Makefile (DIST_FILES): Variable removed.
+ (MIGSTUBS): Use fs_notifyUser.o, not ourfs_notifyUser.o.
+ * ourfs_notify.defs: File removed.
+ * diskfs.h (struct node): New members DIRMOD_TICK and
+ FILEMOD_TICK.
+ * node-make.c (diskfs_make_node): Initialize DIRMOD_TICK and
+ FILEMOD_TICK.
+ * dir-chg.c: Include "fs_notify_U.h" instead "ourfs_notify_U.h".
+ (diskfs_S_dir_notice_changes): Use new dir_changed invocation
+ instead nowait_dir_changed.
+ (diskfs_notice_dirchange): Likewise. Increase tick number.
+ Ignore send timeout error.
+ * file-chg.c: Include "fs_notify_U.h" instead "ourfs_notify_U.h".
+ (diskfs_S_file_notice_changes): Use new file_changed invocation
+ instead nowait_file_changed.
+ (diskfs_notice_filechange): Likewise. Increase tick number.
+ Ignore send timeout error.
+
2002-06-13 Roland McGrath <roland@frob.com>
* dir-readdir.c (diskfs_S_dir_readdir): Revert last change.
diff --git a/libdiskfs/Makefile b/libdiskfs/Makefile
index 9785c29e..526cab7f 100644
--- a/libdiskfs/Makefile
+++ b/libdiskfs/Makefile
@@ -55,10 +55,9 @@ OTHERSRCS = conch-fetch.c conch-set.c dir-clear.c dir-init.c dir-renamed.c \
SRCS = $(OTHERSRCS) $(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(IFSOCKSRCS)
LCLHDRS = diskfs.h priv.h lithp.h fsmutations.h diskfs-pager.h fhandle.h
installhdrs = diskfs.h diskfs-pager.h
-DIST_FILES = ourfs_notify.defs
MIGSTUBS = fsServer.o ioServer.o fsysServer.o exec_startupServer.o \
- fsys_replyUser.o ourfs_notifyUser.o ifsockServer.o \
+ fsys_replyUser.o fs_notifyUser.o ifsockServer.o \
startup_notifyServer.o
OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS))
diff --git a/libdiskfs/dir-chg.c b/libdiskfs/dir-chg.c
index 0e2f4c8a..7ca34447 100644
--- a/libdiskfs/dir-chg.c
+++ b/libdiskfs/dir-chg.c
@@ -17,7 +17,7 @@
#include "priv.h"
#include "fs_S.h"
-#include "ourfs_notify_U.h"
+#include "fs_notify_U.h"
kern_return_t
diskfs_S_dir_notice_changes (struct protid *cred,
@@ -37,7 +37,7 @@ diskfs_S_dir_notice_changes (struct protid *cred,
mutex_unlock (&np->lock);
return ENOTDIR;
}
- err = nowait_dir_changed (notify, DIR_CHANGED_NULL, "");
+ err = dir_changed (notify, np->dirmod_tick, DIR_CHANGED_NULL, "");
if (err)
{
mutex_unlock (&np->lock);
@@ -63,13 +63,15 @@ diskfs_notice_dirchange (struct node *dp, enum dir_changed_type type,
error_t err;
struct modreq **preq;
+ dp->dirmod_tick++;
preq = &dp->dirmod_reqs;
while (*preq)
{
struct modreq *req = *preq;
- err = nowait_dir_changed (req->port, type, name);
- if (err)
- { /* remove notify port */
+ err = dir_changed (req->port, dp->dirmod_tick, type, name);
+ if (err && err != MACH_SEND_TIMED_OUT)
+ {
+ /* Remove notify port. */
*preq = req->next;
mach_port_deallocate (mach_task_self (), req->port);
free (req);
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index c8c8b31a..70ce1e3f 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -101,8 +101,10 @@ struct node
struct conch conch;
struct modreq *dirmod_reqs;
+ unsigned int dirmod_tick;
struct modreq *filemod_reqs;
+ unsigned int filemod_tick;
loff_t allocsize;
diff --git a/libdiskfs/file-chg.c b/libdiskfs/file-chg.c
index e9535591..22edc69c 100644
--- a/libdiskfs/file-chg.c
+++ b/libdiskfs/file-chg.c
@@ -17,7 +17,7 @@
#include "priv.h"
#include "fs_S.h"
-#include "ourfs_notify_U.h"
+#include "fs_notify_U.h"
kern_return_t
diskfs_S_file_notice_changes (struct protid *cred, mach_port_t notify)
@@ -31,7 +31,7 @@ diskfs_S_file_notice_changes (struct protid *cred, mach_port_t notify)
np = cred->po->np;
mutex_lock (&np->lock);
- err = nowait_file_changed (notify, FILE_CHANGED_NULL, 0, 0);
+ err = file_changed (notify, np->filemod_tick, FILE_CHANGED_NULL, 0, 0);
if (err)
{
mutex_unlock (&np->lock);
@@ -51,14 +51,16 @@ diskfs_notice_filechange (struct node *dp, enum file_changed_type type,
{
error_t err;
struct modreq **preq;
-
+
+ dp->filemod_tick++;
preq = &dp->filemod_reqs;
while (*preq)
{
struct modreq *req = *preq;
- err = nowait_file_changed (req->port, type, start, end);
- if (err)
- { /* remove notify port */
+ err = file_changed (req->port, dp->filemod_tick, type, start, end);
+ if (err && err != MACH_SEND_TIMED_OUT)
+ {
+ /* Remove notify port. */
*preq = req->next;
mach_port_deallocate (mach_task_self (), req->port);
free (req);
diff --git a/libdiskfs/node-make.c b/libdiskfs/node-make.c
index 79c2890c..74fdda19 100644
--- a/libdiskfs/node-make.c
+++ b/libdiskfs/node-make.c
@@ -42,7 +42,9 @@ diskfs_make_node (struct disknode *dn)
np->sockaddr = MACH_PORT_NULL;
np->dirmod_reqs = 0;
+ np->dirmod_tick = 0;
np->filemod_reqs = 0;
+ np->filemod_tick = 0;
fshelp_transbox_init (&np->transbox, &np->lock, np);
iohelp_initialize_conch (&np->conch, &np->lock);
diff --git a/libdiskfs/ourfs_notify.defs b/libdiskfs/ourfs_notify.defs
deleted file mode 100644
index 64127fe6..00000000
--- a/libdiskfs/ourfs_notify.defs
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Private specialized presentation of fs_notify.defs for diskfs library. */
-
-#define routine simpleroutine
-#define USERPREFIX nowait_
-#include <hurd/fs_notify.defs>