From: Ben Gras Date: Wed, 5 Oct 2005 15:38:15 +0000 (+0000) Subject: FS: X-Git-Tag: v3.1.2a~661 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=86ed54ee94b96df572c59ee8686b8bbfd928943e;p=minix.git FS: . unmap device drivers from dmap when PM signals they are dead . new null-io function (no_dev_io) to fill in for io functions of unmapped drivers . driver (process number) of unmapped drivers is NONE instead of 0 (a valid process number) IS: . print mutable flag of dmap table too FS changes require sync() to be done 'manually' (currently by reboot/shutdown) at shutdown time; could be caught by SIGTERM in the future. --- diff --git a/servers/fs/device.c b/servers/fs/device.c index 0af0d62e8..9909a8911 100644 --- a/servers/fs/device.c +++ b/servers/fs/device.c @@ -9,6 +9,7 @@ * gen_opcl: generic call to a task to perform an open/close * gen_io: generic call to a task to perform an I/O operation * no_dev: open/close processing for devices that don't exist + * no_dev_io: i/o processing for devices that don't exist * tty_opcl: perform tty-specific processing for open/close * ctty_opcl: perform controlling-tty-specific processing for open/close * ctty_io: perform controlling-tty-specific processing for I/O @@ -49,6 +50,8 @@ int flags; /* mode bits and flags */ dp = &dmap[major]; r = (*dp->dmap_opcl)(DEV_OPEN, dev, proc, flags); if (r == SUSPEND) panic(__FILE__,"suspend on open from", dp->dmap_driver); + if (r == OK && dp->dmap_driver == NONE) + panic(__FILE__, "no driver for dev %d", dev); return(r); } @@ -120,6 +123,10 @@ int flags; /* special flags, like O_NONBLOCK */ /* Determine task dmap. */ dp = &dmap[(dev >> MAJOR) & BYTE]; + /* See if driver is roughly valid. */ + if (dp->dmap_driver == NONE) + panic(__FILE__, "no driver for i/o on dev %d", dev); + /* Set up the message passed to task. */ dev_mess.m_type = op; dev_mess.DEVICE = (dev >> MINOR) & BYTE; @@ -347,7 +354,7 @@ message *mess_ptr; /* pointer to message for task */ */ for (;;) { if (r != OK) { - if (r == EDEADDST) return; /* give up */ + if (r == EDEADSRCDST) return; /* give up */ else panic(__FILE__,"call_task: can't send/receive", r); } @@ -404,10 +411,19 @@ int proc; /* process to open/close for */ int flags; /* mode bits and flags */ { /* Called when opening a nonexistent device. */ - return(ENODEV); } +/*===========================================================================* + * no_dev_io * + *===========================================================================*/ +PUBLIC void no_dev_io(int proc, message *m) +{ +/* Called when doing i/o on a nonexistent device. */ + printf("FS: I/O on unmapped device number\n"); + return; +} + /*===========================================================================* * clone_opcl * *===========================================================================*/ diff --git a/servers/fs/dmap.c b/servers/fs/dmap.c index 73a57fe87..526cac21d 100644 --- a/servers/fs/dmap.c +++ b/servers/fs/dmap.c @@ -97,18 +97,22 @@ int style; /* style of the device */ /* Get pointer to device entry in the dmap table. */ if (major < 0 || major >= NR_DEVICES) return(ENODEV); dp = &dmap[major]; - - /* See if updating the entry is allowed. */ - if (! (dp->dmap_flags & DMAP_MUTABLE)) return(EPERM); - if (dp->dmap_flags & DMAP_BUSY) return(EBUSY); - /* Check if we're supposed to unmap it. */ + /* Check if we're supposed to unmap it. If so, do it even + * if busy or unmutable, as unmap is called when driver has + * exited. + */ if(proc_nr == NONE) { dp->dmap_opcl = no_dev; - dp->dmap_io = 0; - dp->dmap_driver = 0; + dp->dmap_io = no_dev_io; + dp->dmap_driver = NONE; + dp->dmap_flags = DMAP_MUTABLE; /* When gone, not busy or reserved. */ return(OK); } + + /* See if updating the entry is allowed. */ + if (! (dp->dmap_flags & DMAP_MUTABLE)) return(EPERM); + if (dp->dmap_flags & DMAP_BUSY) return(EBUSY); /* Check process number of new driver. */ if (! isokprocnr(proc_nr)) return(EINVAL); @@ -125,6 +129,21 @@ int style; /* style of the device */ return(OK); } +/*===========================================================================* + * dmap_unmap_by_proc * + *===========================================================================*/ +PUBLIC void dmap_unmap_by_proc(int proc_nr) +{ + int i, r; + for (i=0; idmap_flags = init_dmap[i].dmap_flags; } else { /* no default */ dp->dmap_opcl = no_dev; - dp->dmap_io = 0; - dp->dmap_driver = 0; + dp->dmap_io = no_dev_io; + dp->dmap_driver = NONE; dp->dmap_flags = DMAP_MUTABLE; } } diff --git a/servers/fs/misc.c b/servers/fs/misc.c index b4abdb57f..5841a4d05 100644 --- a/servers/fs/misc.c +++ b/servers/fs/misc.c @@ -339,6 +339,9 @@ PUBLIC int do_exit() fp->fp_rootdir = NIL_INODE; fp->fp_workdir = NIL_INODE; + /* If a driver exits, unmap its entries in the dmap table. */ + dmap_unmap_by_proc(exitee); + /* If a session leader exits then revoke access to its controlling tty from * all other processes using it. */ @@ -369,6 +372,7 @@ PUBLIC int do_exit() /* Mark slot as free. */ fp->fp_pid = PID_FREE; + return(OK); } diff --git a/servers/fs/proto.h b/servers/fs/proto.h index 4cd791155..f41315cbb 100644 --- a/servers/fs/proto.h +++ b/servers/fs/proto.h @@ -35,6 +35,7 @@ _PROTOTYPE( int dev_io, (int op, Dev_t dev, int proc, void *buf, _PROTOTYPE( int gen_opcl, (int op, Dev_t dev, int proc, int flags) ); _PROTOTYPE( void gen_io, (int task_nr, message *mess_ptr) ); _PROTOTYPE( int no_dev, (int op, Dev_t dev, int proc, int flags) ); +_PROTOTYPE( void no_dev_io, (int, message *) ); _PROTOTYPE( int tty_opcl, (int op, Dev_t dev, int proc, int flags) ); _PROTOTYPE( int ctty_opcl, (int op, Dev_t dev, int proc, int flags) ); _PROTOTYPE( int clone_opcl, (int op, Dev_t dev, int proc, int flags) ); @@ -50,6 +51,7 @@ _PROTOTYPE( int do_fkey_pressed, (void) ); _PROTOTYPE( int do_devctl, (void) ); _PROTOTYPE( void build_dmap, (void) ); _PROTOTYPE( int map_driver, (int major, int proc_nr, int dev_style) ); +_PROTOTYPE( void dmap_unmap_by_proc, (int proc_nr) ); /* filedes.c */ _PROTOTYPE( struct filp *find_filp, (struct inode *rip, mode_t bits) ); diff --git a/servers/is/dmp_fs.c b/servers/is/dmp_fs.c index 35fe032d9..c6044d4d0 100644 --- a/servers/is/dmp_fs.c +++ b/servers/is/dmp_fs.c @@ -48,6 +48,18 @@ PUBLIC void fproc_dmp() prev_i = i; } +/*===========================================================================* + * dmap_flags * + *===========================================================================*/ +PRIVATE char * dmap_flags(int flags) +{ + static char fl[10]; + fl[0] = '-'; + if(flags & DMAP_MUTABLE) fl[0] = 'M'; + fl[1] = '\0'; + return fl; +} + /*===========================================================================* * dtab_dmp * *===========================================================================*/ @@ -58,12 +70,12 @@ PUBLIC void dtab_dmp() getsysinfo(FS_PROC_NR, SI_DMAP_TAB, dmap); printf("File System (FS) device <-> driver mappings\n"); - printf("Major Proc\n"); - printf("----- ----\n"); + printf("Major Proc Flags\n"); + printf("----- ---- -----\n"); for (i=0; i