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); }
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); }
// 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(); }
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); }
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); }
/* * 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); }
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 */ }