If re-open fails, mark fd as unusable but not-reusable either (until
close()d).
This commit is contained in:
parent
1353798747
commit
6746ee10f5
|
@ -596,10 +596,23 @@ PUBLIC void dev_up(int maj)
|
|||
|
||||
minor = ((in->i_zone[0] >> MINOR) & BYTE);
|
||||
|
||||
if((r = dev_open(in->i_dev, FS_PROC_NR,
|
||||
printf("FS: reopening special %d/%d..\n", maj, minor);
|
||||
|
||||
if((r = dev_open(in->i_zone[0], FS_PROC_NR,
|
||||
in->i_mode & (R_BIT|W_BIT))) != OK) {
|
||||
printf("FS: file on dev %d/%d re-open failed: %d.\n",
|
||||
maj, minor, r);
|
||||
int n;
|
||||
/* This function will set the fp_filp[]s of processes
|
||||
* holding that fp to NULL, but _not_ clear
|
||||
* fp_filp_inuse, so that fd can't be recycled until
|
||||
* it's close()d.
|
||||
*/
|
||||
n = inval_filp(fp);
|
||||
if(n != fp->filp_count)
|
||||
printf("FS: warning: invalidate/count "
|
||||
"discrepancy (%d, %d)\n", n, fp->filp_count);
|
||||
fp->filp_count = 0;
|
||||
printf("FS: file on dev %d/%d re-open failed: %d; "
|
||||
"invalidated %d fd's.\n", maj, minor, r, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
/* This file contains the procedures that manipulate file descriptors.
|
||||
*
|
||||
* The entry points into this file are
|
||||
* get_fd: look for free file descriptor and free filp slots
|
||||
* get_filp: look up the filp entry for a given file descriptor
|
||||
* find_filp: find a filp slot that points to a given inode
|
||||
* get_fd: look for free file descriptor and free filp slots
|
||||
* get_filp: look up the filp entry for a given file descriptor
|
||||
* find_filp: find a filp slot that points to a given inode
|
||||
* inval_filp: invalidate a filp and associated fd's, only let close()
|
||||
* happen on it
|
||||
*/
|
||||
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "fs.h"
|
||||
#include "file.h"
|
||||
#include "fproc.h"
|
||||
|
@ -28,7 +32,7 @@ PUBLIC int get_fd(int start, mode_t bits, int *k, struct filp **fpt)
|
|||
|
||||
/* Search the fproc fp_filp table for a free file descriptor. */
|
||||
for (i = start; i < OPEN_MAX; i++) {
|
||||
if (fp->fp_filp[i] == NIL_FILP) {
|
||||
if (fp->fp_filp[i] == NIL_FILP && !FD_ISSET(i, &fp->fp_filp_inuse)) {
|
||||
/* A file descriptor has been located. */
|
||||
*k = i;
|
||||
break;
|
||||
|
@ -92,3 +96,21 @@ PUBLIC struct filp *find_filp(register struct inode *rip, mode_t bits)
|
|||
/* If control passes here, the filp wasn't there. Report that back. */
|
||||
return(NIL_FILP);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* inval_filp *
|
||||
*===========================================================================*/
|
||||
PUBLIC int inval_filp(struct filp *fp)
|
||||
{
|
||||
int f, fd, n = 0;
|
||||
for(f = 0; f < NR_PROCS; f++) {
|
||||
if(fproc[f].fp_pid == PID_FREE) continue;
|
||||
for(fd = 0; fd < OPEN_MAX; fd++) {
|
||||
if(fproc[f].fp_filp[fd] && fproc[f].fp_filp[fd] == fp) {
|
||||
fproc[f].fp_filp[fd] = NIL_FILP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <sys/select.h>
|
||||
|
||||
/* This is the per-process information. A slot is reserved for each potential
|
||||
* process. Thus NR_PROCS must be the same as in the kernel. It is not
|
||||
* possible or even necessary to tell when a slot is free here.
|
||||
|
@ -7,6 +9,7 @@ EXTERN struct fproc {
|
|||
struct inode *fp_workdir; /* pointer to working directory's inode */
|
||||
struct inode *fp_rootdir; /* pointer to current root dir (see chroot) */
|
||||
struct filp *fp_filp[OPEN_MAX];/* the file descriptor table */
|
||||
fd_set fp_filp_inuse; /* which fd's are in use? */
|
||||
uid_t fp_realuid; /* real user id */
|
||||
uid_t fp_effuid; /* effective user id */
|
||||
gid_t fp_realgid; /* real group id */
|
||||
|
|
|
@ -18,6 +18,7 @@ struct super_block; /* proto.h needs to know this */
|
|||
#include <stdlib.h>
|
||||
#include <sys/ioc_memory.h>
|
||||
#include <sys/svrctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/keymap.h>
|
||||
|
@ -251,6 +252,7 @@ PRIVATE void fs_init()
|
|||
|
||||
/* The root device can now be accessed; set process directories. */
|
||||
for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
|
||||
FD_ZERO(&(rfp->fp_filp_inuse));
|
||||
if (rfp->fp_pid != PID_FREE) {
|
||||
rip = get_inode(root_dev, ROOT_INODE);
|
||||
dup_inode(rip);
|
||||
|
|
|
@ -101,6 +101,7 @@ PUBLIC int do_dup()
|
|||
/* Success. Set up new file descriptors. */
|
||||
f->filp_count++;
|
||||
fp->fp_filp[m_in.fd2] = f;
|
||||
FD_SET(m_in.fd2, &fp->fp_filp_inuse);
|
||||
return(m_in.fd2);
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ PRIVATE int common_open(register int oflags, mode_t omode)
|
|||
|
||||
/* Claim the file descriptor and filp slot and fill them in. */
|
||||
fp->fp_filp[m_in.fd] = fil_ptr;
|
||||
FD_SET(m_in.fd, &fp->fp_filp_inuse);
|
||||
fil_ptr->filp_count = 1;
|
||||
fil_ptr->filp_ino = rip;
|
||||
fil_ptr->filp_flags = oflags;
|
||||
|
@ -187,6 +188,7 @@ PRIVATE int common_open(register int oflags, mode_t omode)
|
|||
if (r != OK) {
|
||||
if (r == SUSPEND) return(r); /* Oops, just suspended */
|
||||
fp->fp_filp[m_in.fd] = NIL_FILP;
|
||||
FD_CLR(m_in.fd, &fp->fp_filp_inuse);
|
||||
fil_ptr->filp_count= 0;
|
||||
put_inode(rip);
|
||||
return(r);
|
||||
|
@ -434,6 +436,7 @@ PUBLIC int do_close()
|
|||
|
||||
fp->fp_cloexec &= ~(1L << m_in.fd); /* turn off close-on-exec bit */
|
||||
fp->fp_filp[m_in.fd] = NIL_FILP;
|
||||
FD_CLR(m_in.fd, &fp->fp_filp_inuse);
|
||||
|
||||
/* Check to see if the file is locked. If so, release all locks. */
|
||||
if (nr_locks == 0) return(OK);
|
||||
|
|
|
@ -47,20 +47,25 @@ PUBLIC int do_pipe()
|
|||
rfp = fp;
|
||||
if ( (r = get_fd(0, R_BIT, &fil_des[0], &fil_ptr0)) != OK) return(r);
|
||||
rfp->fp_filp[fil_des[0]] = fil_ptr0;
|
||||
FD_SET(fil_des[0], &rfp->fp_filp_inuse);
|
||||
fil_ptr0->filp_count = 1;
|
||||
if ( (r = get_fd(0, W_BIT, &fil_des[1], &fil_ptr1)) != OK) {
|
||||
rfp->fp_filp[fil_des[0]] = NIL_FILP;
|
||||
FD_CLR(fil_des[0], &rfp->fp_filp_inuse);
|
||||
fil_ptr0->filp_count = 0;
|
||||
return(r);
|
||||
}
|
||||
rfp->fp_filp[fil_des[1]] = fil_ptr1;
|
||||
FD_SET(fil_des[1], &rfp->fp_filp_inuse);
|
||||
fil_ptr1->filp_count = 1;
|
||||
|
||||
/* Make the inode on the pipe device. */
|
||||
if ( (rip = alloc_inode(root_dev, I_REGULAR) ) == NIL_INODE) {
|
||||
rfp->fp_filp[fil_des[0]] = NIL_FILP;
|
||||
FD_CLR(fil_des[0], &rfp->fp_filp_inuse);
|
||||
fil_ptr0->filp_count = 0;
|
||||
rfp->fp_filp[fil_des[1]] = NIL_FILP;
|
||||
FD_CLR(fil_des[1], &rfp->fp_filp_inuse);
|
||||
fil_ptr1->filp_count = 0;
|
||||
return(err_code);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ _PROTOTYPE( void dmap_endpt_up, (int proc_nr) );
|
|||
_PROTOTYPE( struct filp *find_filp, (struct inode *rip, mode_t bits) );
|
||||
_PROTOTYPE( int get_fd, (int start, mode_t bits, int *k, struct filp **fpt) );
|
||||
_PROTOTYPE( struct filp *get_filp, (int fild) );
|
||||
_PROTOTYPE( int inval_filp, (struct filp *) );
|
||||
|
||||
/* inode.c */
|
||||
_PROTOTYPE( struct inode *alloc_inode, (dev_t dev, mode_t bits) );
|
||||
|
|
Loading…
Reference in a new issue