Exemple #1
0
static int
vncopy_block_to_shadow(struct vn_softc * vn, vfs_context_t ctx,
		       u_int32_t file_block, u_int32_t shadow_block)
{
	int	error;
	char *	tmpbuf;

	tmpbuf = _MALLOC(vn->sc_secsize, M_TEMP, M_WAITOK);
	if (tmpbuf == NULL) {
	    return (ENOMEM);
	}
	/* read one block from file at file_block offset */
	error = file_io(vn->sc_vp, ctx, UIO_READ,
			tmpbuf, (off_t)file_block * vn->sc_secsize, 
			vn->sc_secsize, NULL);
	if (error) {
		goto done;
	}
	/* write one block to shadow file at shadow_block offset */
	error = file_io(vn->sc_shadow_vp, ctx, UIO_WRITE,
			tmpbuf, (off_t)shadow_block * vn->sc_secsize, 
			vn->sc_secsize, NULL);
 done:
	FREE(tmpbuf, M_TEMP);
	return (error);
}
Exemple #2
0
static int
vn_readwrite_io(struct vn_softc * vn, struct buf * bp, vfs_context_t ctx)
{
	int			error = 0;
	char *			iov_base;
	caddr_t 		vaddr;

	if (buf_map(bp, &vaddr)) 
	        panic("vn device: buf_map failed");
	iov_base = (char *)vaddr;

	if (vn->sc_shadow_vp == NULL) {
	        user_ssize_t		temp_resid;

		error = file_io(vn->sc_vp, ctx,
				buf_flags(bp) & B_READ ? UIO_READ : UIO_WRITE,
				iov_base,
				(off_t)buf_blkno(bp) * vn->sc_secsize,
				buf_resid(bp), &temp_resid);
		buf_setresid(bp, temp_resid);
	}
	else {
		if (buf_flags(bp) & B_READ)
			error = shadow_read(vn, bp, iov_base, ctx);
		else
			error = shadow_write(vn, bp, iov_base, ctx);
	}
	buf_unmap(bp);

	return (error);
}
Exemple #3
0
// Put the current process to sleep by "returning" to its parent process.
// Used both when a process calls the SYS_RET system call explicitly,
// and when a process causes an unhandled trap in user mode.
// The 'entry' parameter is as in proc_save().
void gcc_noreturn
proc_ret(trapframe *tf, int entry)
{
	proc *cp = proc_cur();
	proc *p = cp->parent;
	
	if (p == NULL){
		if (tf->trapno != T_SYSCALL){
			trap_print(tf);
			panic("no parent to reflect trap");
		}
		file_io(tf);
		cprintf("fileio done\n");
	}

	spinlock_acquire(&cp->lock);
	cp->state = PROC_STOP;
	cp->runcpu = NULL;
	proc_save(cp, tf, entry);
	spinlock_release(&cp->lock);
	
	spinlock_acquire(&p->lock);
	if (p->state == PROC_WAIT && p->waitchild == cp) {
		p->waitchild = NULL;
		proc_run(p);
	}
	spinlock_release(&p->lock);
	
	proc_sched();
}
Exemple #4
0
static int
shadow_write(struct vn_softc * vn, struct buf * bp, char * base, 
	     vfs_context_t ctx)
{
	u_int32_t		blocksize = vn->sc_secsize;
	int 		error = 0;
	u_int32_t		offset;
	boolean_t	shadow_grew;
	u_int32_t		resid;
	u_int32_t		start = 0;

	offset = buf_blkno(bp);
	resid =  buf_resid(bp) / blocksize;
	while (resid > 0) {
		user_ssize_t	temp_resid;
		u_int32_t		this_offset;
		u_int32_t		this_resid;

		shadow_grew = shadow_map_write(vn->sc_shadow_map, 
					       offset, resid, 
					       &this_offset, &this_resid);
		if (shadow_grew) {
#if 0
			off_t	size;
			/* truncate the file to its new length before write */
			size = (off_t)shadow_map_shadow_size(vn->sc_shadow_map) 
				* blocksize;
			vnode_setsize(vn->sc_shadow_vp, size, IO_SYNC, ctx);
#endif
		}
		error = file_io(vn->sc_shadow_vp, ctx, UIO_WRITE, 
				base + start,
				(off_t)this_offset * blocksize,
				(user_ssize_t)this_resid * blocksize, 
				&temp_resid);
		if (error) {
			break;
		}
		this_resid -= (temp_resid / blocksize);
		if (this_resid == 0) {
			printf("vn device: shadow_write zero length write\n");
			break;
		}
		resid -= this_resid;
		offset += this_resid;
		start += this_resid * blocksize;
	}
	buf_setresid(bp, resid * blocksize);
	return (error);
}
Exemple #5
0
static int
shadow_read(struct vn_softc * vn, struct buf * bp, char * base,
	vfs_context_t ctx)
{
	u_int32_t		blocksize = vn->sc_secsize;
	int 		error = 0;
	u_int32_t		offset;
	boolean_t	read_shadow;
	u_int32_t		resid;
	u_int32_t		start = 0;

	offset = buf_blkno(bp);
	resid =  buf_resid(bp) / blocksize;
	while (resid > 0) {
		user_ssize_t	temp_resid;
		u_int32_t		this_offset;
		u_int32_t		this_resid;
		struct vnode *	vp;

		read_shadow = shadow_map_read(vn->sc_shadow_map,
					      offset, resid,
					      &this_offset, &this_resid);
		if (read_shadow) {
			vp = vn->sc_shadow_vp;
		}
		else {
			vp = vn->sc_vp;
		}
		error = file_io(vp, ctx, UIO_READ, base + start,
				(off_t)this_offset * blocksize,
				(user_ssize_t)this_resid * blocksize, 
				&temp_resid);
		if (error) {
			break;
		}
		this_resid -= (temp_resid / blocksize);
		if (this_resid == 0) {
			printf("vn device: shadow_read zero length read\n");
			break;
		}
		resid -= this_resid;
		offset += this_resid;
		start += this_resid * blocksize;
	}
	buf_setresid(bp, resid * blocksize);
	return (error);
}
Exemple #6
0
/*
 * Duplicate the current processes' credentials.  Since we are called only
 * as the result of a SET ioctl and only root can do that, any future access
 * to this "disk" is essentially as root.  Note that credentials may change
 * if some other uid can write directly to the mapped file (NFS).
 */
static int
setcred(struct vnode * vp, kauth_cred_t cred)
{
	char *tmpbuf;
	int error = 0;
	struct vfs_context  context; 		

	/*
	 * Horrible kludge to establish credentials for NFS  XXX.
	 */
	context.vc_thread = current_thread();
	context.vc_ucred = cred;
	tmpbuf = _MALLOC(DEV_BSIZE, M_TEMP, M_WAITOK);
	error = file_io(vp, &context, UIO_READ, tmpbuf, 0, DEV_BSIZE, NULL);
	FREE(tmpbuf, M_TEMP);
	return (error);
}
Exemple #7
0
short main (short argc, char *argv[])
{
    unsigned short status=0;            /* TX and RX status                 */
    unsigned short tries;               /* Attempts to send a file          */
    unsigned short cmp_size;            /* Size after compression           */
    unsigned short data_written;        /* Data written to the file         */
    unsigned short data_read;           /* Data read from the file          */
    char *file_name;                    /* filename                         */
    char *function;                     /* Receive, Transmit                */
    char *com_port;                     /* Communications adapter port      */

    file_name = get_inp (argc, argv);   /* Get file name                    */
    if (file_name == NULL )
    {
        disp();                         /* Display usage message            */
        return JM_FNF;
    }
    function  = get_fun (argc, argv);   /* Get function 'R' or 'S'          */
    if (function == NULL)
    {
        disp();                         /* Display usage message            */
        return JM_CMD;
    }
    com_port  = get_prt (argc, argv);   /* Get port '1 to 4 '               */
    if (com_port == NULL)
    {
        disp();                         /* Display usage message            */
        return JM_CMD;
    }
    port = get_port(*com_port);         /* Convert port to an offset        */
/****************************************************************************/
/*                          Allocate buffers                                */
/****************************************************************************/
    in_buffer = allocate_memory(DAT_LEN);  /* Get some memory for input     */
    if (in_buffer == NULL)
        return JM_MEM;                     /* No memory available           */
    out_buffer = allocate_memory(DAT_LEN); /* Get some memory for output    */
    if (out_buffer == NULL)
        return JM_MEM;                     /* No memory available           */
    comp_buffer=allocate_memory(DAT_LEN);  /* Get memory for compression    */
    if (comp_buffer == NULL)
        return JM_MEM;                     /* No memory available           */
    file_buffer=allocate_memory(DAT_LEN);  /* Get memory for file buffer    */
    if (file_buffer == NULL)
        return JM_MEM;                     /* No memory available           */
    int_buffer =allocate_memory(DAT_LEN);  /* Memory for interrupt buffer   */
    if (int_buffer == NULL)
        return JM_MEM;                     /* No memory available           */
/****************************************************************************/

    screen (SCR_SGN,NULL,NULL);            /* Write signon screen           */
    syst.s_len = BLK_SIZ;
    syst.s_byt = 0;
    syst.s_blk = 0;
    syst.s_sta = okay;
    switch(*function)                     /* Functions are TX and RX       */
    {
/****************************************************************************/
/*                          Receive JMODEM file                             */
/****************************************************************************/
    case 'R':
        {
            if (!file_io(CREATE, &handle, &file_name, NULL) )
            {
                buff = (JBUF *) in_buffer;            /* Assign type JBUF   */
                open_chan(port);                      /* Open com channel   */
                screen (SCR_STA,NULL,NULL);           /* Write status block */
                status = rx_sync();                   /* Synchronize        */
                if (!status)
                    screen (SCR_SYR,NULL,NULL);
                data_written = 0xFFFF;
                tries = 10;			    /* Attempts to receive */
                while (    (data_written)             /* Write file okay   */
                        && (!user_abort )             /* No break key      */
                        && (!status     )             /* Recev block okay  */
                        && (tries--)    )             /* 10 retries        */
                {
                    time(&start);                     /* Get starting time */
		    screen (SCR_SYS,&syst,NULL);      /* Show status block */
                    status = recv_blk (               /* Receive data-block*/
                             &syst.s_len,             /* Block length      */
                             in_buffer);              /* Input buffer      */
                    if (status)                       /* If bad            */
                        break;                        /* Abort the WHILE   */
                    if( (!(calc_crc(GET_CRC,          /* Calculate CRC     */
                          syst.s_len,                 /* Amount to check   */
                          in_buffer) ))               /* Receiver buffer   */
		      && ( buff->blk_num ==           /* Check block also  */
                         (unsigned char)
                         (syst.s_blk +1)))            /* Block number      */
                    {
                        syst.s_sta = okay;            /* Text pointer      */
                        tries=10;                     /* Reset count       */
                        syst.s_len -= OVRHD;          /* Subtract overhead */
                        *out_buffer = ACK;            /* Good              */
                        write_chan(1,out_buffer);     /* Send the ACK      */

                        /* If data was compressed                          */
			if ( (buff->blk_typ & COMP) == COMP)
                        {
                             syst.s_len = decode (    /* Decode the data   */
                                      syst.s_len,     /* Data-block length */
				     &buff->blk_dat,  /* Where to start    */
                                     file_buffer);    /* Where to put data */
                        }
                        else
                        /* Data was normal (not compressed, just copy )    */
                        {
                            memcpy (file_buffer,&buff->blk_dat,syst.s_len);
                        }
                        /* Write to the file                                */
                        data_written = file_io( WRITE ,  /* Function        */
                                         &handle,        /* File handle     */
                                         &file_buffer ,  /* Where data is   */
                                         syst.s_len );   /* Amount to write */
                        syst.s_byt += data_written;      /* Total bytes     */
                        syst.s_blk++;                    /* Block number    */
                        time(&finish);                   /* Get end time    */
                        if (finish - start)              /* Check div/0     */
                            syst.s_cps = (short)         /* Calc Block CPS  */
                            (data_written / (finish - start) );

                            /* Check for end-of-file                        */
                        if ( (buff->blk_typ & EOF_) == EOF_)
                        {                       /* This was the end of file */
                            file_io(CLOSE,               /* Function        */
                                   &handle,              /* Open handle     */
                                   &file_name,           /* Name not used   */
                                   NULL);                /* Buffer not used */
                            close_chan(port);            /* Close the port  */
                            status = JM_NRM;             /* Set status      */
                            goto cleanup;                /* exit routine    */
                        }
                    }
                    else
                    {
                        *out_buffer = NAK;              /* Bad block        */
                        syst.s_sta = retry;             /* Char pointer     */
                        write_chan(1,out_buffer);       /* Send the NAK     */
                     }
                }
                close_chan(port);                        /* Aborted         */
                file_io(DELETE,                          /* Function        */
                        &handle,                         /* File handle     */
                        &file_name,                      /* Name            */
                        NULL);                           /* Buffer not used */
                status = JM_ABT;
		break;                                   /* Exit if() {}    */
            }
            else                                       /* Can't create file */
            {
                status = JM_CRE;
                break;                                   /* Exit while() {} */
            }
        break;                                           /* Exit case 'R'   */
        }
/****************************************************************************/
/*                          Send JMODEM file                                */
/****************************************************************************/
    case 'S':   /* Send JMODEM file */
        {
            if (!file_io(OPEN_READ, &handle, &file_name, NULL) )
            {
                buff = (JBUF *)out_buffer;            /* Assign type JBUF   */
                syst.s_byt = 0;                       /* Restore byte count */
                open_chan(port);                      /* Open COM port      */
                data_read = 0xFFFF;                   /* Initialize         */
                screen (SCR_STA,NULL,NULL);           /* Write status block */
                status = tx_sync();                   /* Synchronize        */
                if (!status)
                    screen (SCR_SYT,NULL,NULL);
                while  (  (!user_abort)               /* Ctrl - break       */
                       && (!status) )                 /* sent okay          */
                {
                    time(&start);                     /* Get starting time  */
                    data_read = file_io( READ       , /* Read a record      */
                                       &handle      , /* File pointer       */
                                       &file_buffer , /* Where to put       */
                                      syst.s_len );   /* Amount to read     */
                    if (!data_read)                   /* Past end of file   */
                        break;
                    syst.s_byt += (long) data_read;   /* Running count      */
		    screen (SCR_SYS,&syst,NULL);      /* Show status block  */
                    buff->blk_num = (unsigned char)
                                     ++syst.s_blk;    /* Block number       */
                    if (data_read != syst.s_len)      /* Byte request       */
                        buff->blk_typ = EOF_;         /* Into control-byte  */
                    else
                        buff->blk_typ = NORM;         /* Normal block       */
                    
                    cmp_size = encode (data_read,     /* Encode size        */
                                      file_buffer,    /* Source             */
                                      comp_buffer);   /* Destination        */

                    if ( cmp_size  < data_read  )     /* If compressed      */
                    {
			buff->len = (cmp_size+OVRHD); /* Length of block    */
                        buff->blk_typ |= COMP;        /* Show compressed    */
                        memcpy (&buff->blk_dat,       /* Start of data      */
                                   comp_buffer,       /* Copy from here     */
                                   cmp_size);         /* This much          */
                    }
                    else                              /* Not compressed     */
                    {
			buff->len = (data_read+OVRHD);/* Length of block    */
                        memcpy (&buff->blk_dat,       /* Copy to            */
                                   file_buffer,       /* Copy from          */
                                   data_read);        /* This amount        */
                    }
                    calc_crc(SET_CRC,                 /* Calculate CRC      */
                            buff->len ,               /* Length of block    */
                            out_buffer);              /* Where data is      */
                    status = send_blk(                /* Send the block     */
                             buff->len,               /* Block length       */
                             &syst,                   /* Read block ptr.    */
                             out_buffer);             /* Buffer pointer     */

                    time(&finish);                    /* Get end time       */
                    if (finish - start)               /* Guard div/zero     */
                        syst.s_cps = (short)          /* Calc Block CPS     */
                        (data_read / (finish - start) );
                    if ( buff->blk_typ == EOF_)       /* Last record        */
                        break;
                }
                close_chan(port);                     /* Close the port     */
                if (status)
                    syst.s_sta = abrt;                /* A text pointer     */
                else
                    syst.s_sta = done;                /* A text pointer     */

                file_io(CLOSE, &handle,
                        &file_name, NULL);            /* Close the file     */
                screen (SCR_SYS,&syst,NULL);          /* Show status block  */
            }
            else                                      /* File not found     */
            {
                status = JM_FNF;
            }
        break;  /* End of CASE 'S' */
        }
    }
    cleanup:
    free (in_buffer);                                  /* Free  buffers     */
    free (out_buffer);
    free (comp_buffer);
    free (file_buffer);
    /* Five-second timer to display error messages */
    if (status != JM_NRM)
    {
        time(&finish);
        start = 0;
        finish += 5;
        while ( finish > start )
            time(&start);
    }
    screen (SCR_END,NULL,NULL);                         /* Clear the screen */
    return status;                                      /* Normal exit      */
}