diff options
-rw-r--r-- | console/ChangeLog | 17 | ||||
-rw-r--r-- | console/Makefile | 4 | ||||
-rw-r--r-- | console/console.c | 79 | ||||
-rw-r--r-- | console/display.c | 29 | ||||
-rw-r--r-- | hurd/ChangeLog | 9 | ||||
-rw-r--r-- | hurd/fs_notify.defs | 21 | ||||
-rw-r--r-- | hurd/hurd_types.defs | 13 | ||||
-rw-r--r-- | hurd/hurd_types.h | 1 | ||||
-rw-r--r-- | libdiskfs/ChangeLog | 20 | ||||
-rw-r--r-- | libdiskfs/Makefile | 3 | ||||
-rw-r--r-- | libdiskfs/dir-chg.c | 12 | ||||
-rw-r--r-- | libdiskfs/diskfs.h | 2 | ||||
-rw-r--r-- | libdiskfs/file-chg.c | 14 | ||||
-rw-r--r-- | libdiskfs/node-make.c | 2 | ||||
-rw-r--r-- | libdiskfs/ourfs_notify.defs | 5 |
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> |