ssize_t dc_writev(int fd, const struct iovec *vector, int count) { ssize_t n; struct vsp_node *node; char *iobuf; int i; ssize_t iobuf_len; off_t iobuf_pos = 0; #ifdef DC_CALL_TRACE showTraceBack(); #endif /* nothing wrong ... yet */ dc_errno = DEOK; if( (count < 0 ) || (count > IOV_MAX) ) { errno = EINVAL; return -1; } node = get_vsp_node(fd); if (node == NULL) { /* we have not such file descriptor, so lets give a try to system */ return system_writev(fd, vector, count); } iobuf_len = 0; for(i = 0; i < count; i++) { iobuf_len += vector[i].iov_len; } /* check for overflow */ if( iobuf_len < 0 ) { errno = EINVAL; return -1; } iobuf = (char *)malloc(iobuf_len); if(iobuf == NULL) { m_unlock(&node->mux); return -1; } for(i = 0; i < count; i++) { memcpy(iobuf + iobuf_pos, vector[i].iov_base, vector[i].iov_len); iobuf_pos += vector[i].iov_len; } n = dc_real_write(node, iobuf, iobuf_len); /* we do not need the lock any more */ m_unlock(&node->mux); free(iobuf); return n; }
off64_t dc_lseek64(int fd, off64_t offset, int whence) { off64_t n; struct vsp_node *node; #ifdef DC_CALL_TRACE showTraceBack(); #endif /* nothing wrong ... yet */ dc_errno = DEOK; node = get_vsp_node(fd); if (node == NULL) { /* we have not such file descriptor, so lets give a try to system */ return system_lseek64(fd, offset, whence); } n = dc_real_lseek(node, offset, whence); m_unlock(&node->mux); return n; }
static ssize_t monitor_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { ssize_t rc= 0; m_lock(&mutex); while (curr_pos <= *f_pos) { if (c_wait(&wait_queue, &mutex)) { printk("<1>read interrupted while waiting for data\n"); rc= -EINTR; goto epilog; } } if (count > curr_size) { count= curr_size; } printk("<1>read %d bytes at %d (%p)\n", (int)count, (int)*f_pos, filp); /* Transfering data to user space */ if (copy_to_user(buf, monitor_buffer, count)!=0) { rc= -EFAULT; goto epilog; } *f_pos= curr_pos - (curr_size-count); rc= count; epilog: m_unlock(&mutex); return rc; }
ssize_t syncread_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos) { int rc; loff_t last; m_lock(&mutex); last= *f_pos + count; if (last>MAX_SIZE) { count -= last-MAX_SIZE; } printk("<1>write %d bytes at %d\n", (int)count, (int)*f_pos); /* Transfiriendo datos desde el espacio del usuario */ if (copy_from_user(syncread_buffer+*f_pos, buf, count)!=0) { /* el valor de buf es una direccion invalida */ rc= -EFAULT; goto epilog; } *f_pos += count; curr_size= *f_pos; rc= count; c_broadcast(&cond); epilog: m_unlock(&mutex); return rc; }
size_t dc_fread(void *ptr, size_t size, size_t items, FILE *fp) { int rc ; struct vsp_node *node; node = get_vsp_node(FILE_NO(fp)); if( node == NULL ) { return system_fread( ptr, size, items, fp); } rc= dc_real_read(node,ptr,size*items) ; switch(rc) { case -1: case 0: #if defined(__linux__) || defined(__GNU__) || defined(__FreeBSD_kernel__) || defined(__CYGWIN__) ((FILE *)fp)->_flags |= _IO_EOF_SEEN; #else ((FILE *)fp)->_flag |= _IOEOF; #endif rc = 0; break ; default: rc= (rc+size-1)/size ; break ; } m_unlock(&node->mux); return rc ; }
static ssize_t monitor_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos) { ssize_t rc; m_lock(&mutex); if (count>MAX_SIZE) { count = MAX_SIZE; } printk("<1>write %d bytes at %d (%p)\n", (int)count, curr_pos, filp); /* Transfering data from user space */ if (copy_from_user(monitor_buffer, buf, count)!=0) { rc= -EFAULT; goto epilog; } curr_size = count; curr_pos += count; *f_pos= curr_pos; c_broadcast(&wait_queue); rc= count; epilog: m_unlock(&mutex); return rc; }
ssize_t dc_write(int fd,const void *buff, size_t buflen) { ssize_t n; struct vsp_node *node; #ifdef DC_CALL_TRACE showTraceBack(); #endif /* nothing wrong ... yet */ dc_errno = DEOK; node = get_vsp_node(fd); if (node == NULL) { /* we have not such file descriptor, so lets give a try to system */ return system_write(fd, buff, buflen); } n = dc_real_write(node, buff, buflen); m_unlock(&node->mux); return n; }
FILE *dc_fdopen(int fd, const char *mode) { FILE *fp; struct vsp_node *node; node = get_vsp_node(fd); if( node == NULL ) { return system_fdopen(fd, mode); } fp = (FILE *)malloc( sizeof(FILE) ); if( fp == NULL ) { return NULL; } /* break FILE chain */ #if defined(__linux__) || defined(__GNU__) || defined(__FreeBSD_kernel__) fp->_chain = NULL; fp->_IO_write_ptr = NULL; fp->_IO_write_base = NULL; fp->_flags = 0; #else fp->_flag = 0; #endif FILE_NO(fp) = fd; m_unlock(&node->mux); return fp; }
int dc_fstat64(int fd, struct stat64 *buf) #endif { struct vsp_node *node; int rc; char *path; off64_t size; #ifdef DC_CALL_TRACE showTraceBack(); #endif node = get_vsp_node( fd ); if( node == NULL ) { dc_debug(DC_INFO, "Using system native fstat64 for %d.", fd); return system_fstat64(fd, buf); } /* pnfs can not show file size if file opened for write and not closed */ if( node->flags & O_WRONLY ) { size = dc_real_lseek( node, 0, SEEK_CUR ); } path = getNodePath(node); m_unlock(&node->mux); rc = dc_stat64( (const char *) path , buf); free(path); if( node->flags & O_WRONLY ) { buf->st_size = size; } return rc; }
ssize_t dc_pwrite64(int fd, const void *buff, size_t buflen, off64_t offset) { ssize_t n = -1; struct vsp_node *node; #ifdef DC_CALL_TRACE showTraceBack(); #endif /* nothing wrong ... yet */ dc_errno = DEOK; node = get_vsp_node(fd); if (node == NULL) { /* we have not such file descriptor, so lets give a try to system */ return system_pwrite64(fd, buff, buflen, offset); } if( dc_real_lseek(node, offset, SEEK_SET) >=0 ) { n = dc_real_write(node, buff, buflen); } m_unlock(&node->mux); return n; }
char * dc_fgets(char *s, int size, FILE *fp) { struct vsp_node *node; int i; char c; int n=0; char *rs; node = get_vsp_node(FILE_NO(fp)); if( node == NULL ) { return system_fgets(s, size, fp); } for( i = 0; i < size; ){ n = dc_real_read(node, &c, 1); if( n <= 0 ) break; s[i++] = c; if( c == '\n' ) break; } s[i] = '\0'; if( (n < 0) || ( i == 0 ) ){ rs = NULL; }else{ rs = s; } m_unlock(&node->mux); return rs; }
ssize_t bano_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos) { int rc; int copyFromUserResult; int dv; loff_t last; m_lock(&mutex); dv = iminor(filp->f_inode); if (dv == 0) { last = damas_pos + count; if (last > MAX_SIZE) { count -= last-MAX_SIZE; } printk("<1>write %d bytes at (damas) %d\n", (int)count, (int)*f_pos); copyFromUserResult = copy_from_user(buffer_d+damas_pos, buf, count); /* Transfiriendo datos desde el espacio del usuario */ if (copyFromUserResult!=0) { /* el valor de buf es una direccion invalida */ rc= -EFAULT; goto epilog; } damas_pos += count; curr_size_d= damas_pos; } else { last = varones_pos + count; if (last > MAX_SIZE) { count -= last-MAX_SIZE; } printk("<1>write %d bytes at (varones) %d\n", (int)count, (int)*f_pos); copyFromUserResult = copy_from_user(buffer_v+varones_pos, buf, count); /* Transfiriendo datos desde el espacio del usuario */ if (copyFromUserResult!=0) { /* el valor de buf es una direccion invalida */ rc= -EFAULT; goto epilog; } varones_pos += count; curr_size_v = varones_pos; } rc= count; c_broadcast(&cond); epilog: m_unlock(&mutex); return rc; }
void a_switch_to(void) { static bool not_first; while (not_first); printf("%s: Received call from Receiver\n", get_instance_name()); /* OK, now let's proceed to try to trash our reply cap. You can more or * less read execution in a straight line from here as each function calls * the next. */ printf("%s: Acquiring mutex...\n", get_instance_name()); m_lock(); printf("%s: Acquiring semaphore...\n", get_instance_name()); s_wait(); /* Trigger some more calls on the original endpoint, just in case this is * not correctly handled. */ p1_emit(); p2_emit(); printf("%s: Taking first hop...\n", get_instance_name()); b1_switch_to(); printf("%s: Taking second hop...\n", get_instance_name()); c1_switch_to(); printf("%s: Taking third hop...\n", get_instance_name()); d1_switch_to(); printf("%s: Taking fourth (external) hop...\n", get_instance_name()); e_switch_to(); printf("%s: Releasing mutex...\n", get_instance_name()); m_unlock(); printf("%s: Releasing semaphore...\n", get_instance_name()); s_post(); printf("%s: Returning (moment of truth)...\n", get_instance_name()); /* Prevent future output that can confuse users. */ if (!not_first) { not_first = true; } }
int dc_ferror(FILE *fp) { struct vsp_node *node; node = get_vsp_node(FILE_NO(fp)); if( node == NULL ) { return system_ferror(fp); } m_unlock(&node->mux); return dc_errno; }
void dc_setBufferSize(int fd, size_t newSize) { struct vsp_node *node; node = get_vsp_node(fd); if( node == NULL ){ return; } dc_setNodeBufferSize(node, newSize); m_unlock(&node->mux); }
int dc_close2(int fd) { int res = 0; struct vsp_node *node; int32_t size; #ifdef DC_CALL_TRACE showTraceBack(); #endif /* nothing wrong ... yet */ dc_errno = DEOK; node = delete_vsp_node(fd); if (node == NULL) { /* we have not such file descriptor, so lets give a try to system */ return system_close(fd); } dc_real_fsync( node ); if(node->unsafeWrite) { size = htonl(-1); /* send end of data */ writen(node->dataFd, (char *) &size, sizeof(size), NULL); /* FIXME: error detection missing */ if (get_fin(node) < 0) { dc_debug(DC_ERROR, "dc_close: mover did not FIN the data blocks."); res = -1; } } close_data_socket(node->dataFd); deleteQueue(node->queueID); m_unlock(&node->mux); node_destroy(node); return res; }
int syncread_release(struct inode *inode, struct file *filp) { m_lock(&mutex); if (filp->f_mode & FMODE_WRITE) { writing= FALSE; c_broadcast(&cond); printk("<1>close for write successful\n"); } else if (filp->f_mode & FMODE_READ) { readers--; if (readers==0) c_broadcast(&cond); printk("<1>close for read (readers remaining=%d)\n", readers); } m_unlock(&mutex); return 0; }
int dc_fflush(FILE *fp) { struct vsp_node *node; if(fp == NULL ) { return system_fflush(fp); } node = get_vsp_node(FILE_NO(fp)); if( node == NULL ) { return system_fflush(fp); } m_unlock(&node->mux); return 0; }
int syncread_open(struct inode *inode, struct file *filp) { int rc= 0; m_lock(&mutex); if (filp->f_mode & FMODE_WRITE) { int rc; printk("<1>open request for write\n"); /* Se debe esperar hasta que no hayan otros lectores o escritores */ pend_open_write++; while (writing || readers>0) { if (c_wait(&cond, &mutex)) { pend_open_write--; c_broadcast(&cond); rc= -EINTR; goto epilog; } } writing= TRUE; pend_open_write--; curr_size= 0; c_broadcast(&cond); printk("<1>open for write successful\n"); } else if (filp->f_mode & FMODE_READ) { /* Para evitar la hambruna de los escritores, si nadie esta escribiendo * pero hay escritores pendientes (esperan porque readers>0), los * nuevos lectores deben esperar hasta que todos los lectores cierren * el dispositivo e ingrese un nuevo escritor. */ while (!writing && pend_open_write>0) { if (c_wait(&cond, &mutex)) { rc= -EINTR; goto epilog; } } readers++; printk("<1>open for read\n"); } epilog: m_unlock(&mutex); return rc; }
int dc_fclose(FILE *fp) { int status; struct vsp_node *node; node = get_vsp_node(FILE_NO(fp)); if( node == NULL ) { return system_fclose(fp); } /* FIXME */ m_unlock(&node->mux); status = dc_close(FILE_NO(fp)); free((char *)fp); return status ; }
void dc_noBuffering(int fd) { struct vsp_node *node; node = get_vsp_node(fd); if(node == NULL) return; if(node->ahead != NULL) { /* check for DCACHE_RAHEAD */ if(getenv("DCACHE_RAHEAD") != NULL ) { dc_debug(DC_INFO, "Read ahead disabling skipped for fd = %d.", fd); }else{ free(node->ahead); node->ahead=NULL; dc_debug(DC_INFO, "No Read ahead for fd = %d.", fd); } } m_unlock(&node->mux); }
struct sigaction * __old_sa_alarm() { struct sigaction *sa; m_lock(&kLock); if(!saKeyOnce) { t_keycreate(&sa_alarmKey, NULL); ++saKeyOnce; } m_unlock(&kLock); t_getspecific(sa_alarmKey, &sa); if( sa == NULL ) { sa = calloc(1, sizeof(struct sigaction)); t_setspecific(sa_alarmKey, (void *)sa); } return sa; }
int dc_fseeko64(FILE *fp, off64_t offset, int whence) { off64_t rc; struct vsp_node *node; node = get_vsp_node(FILE_NO(fp)); if( node == NULL ) { return system_fseeko64( fp, offset, whence); } if (fp == NULL) { return -1; } rc = dc_real_lseek(node,offset,whence); m_unlock(&node->mux); return rc < 0 ? -1 : 0; }
int * __isAlarm() { int *al; m_lock(&kLock); if(!alarmKeyOnce) { t_keycreate(&isAlarmKey, NULL); ++alarmKeyOnce; } m_unlock(&kLock); t_getspecific(isAlarmKey, &al); if( al == NULL ) { al = calloc(1, sizeof(int)); t_setspecific(isAlarmKey, (void *)al); } return al; }
int * __isIOFailed() { int *io; m_lock(&kLock); if(!ioKeyOnce) { t_keycreate(&ioFailedKey, NULL); ++ioKeyOnce; } m_unlock(&kLock); t_getspecific(ioFailedKey, &io); if( io == NULL ) { io = calloc(1, sizeof(int)); t_setspecific(ioFailedKey, (void *)io); } return io; }
int dc_fgetc(FILE *fp) { struct vsp_node *node; unsigned char c; int n; node = get_vsp_node(FILE_NO(fp)); if( node == NULL ) { return system_fgetc(fp); } n = dc_real_read(node, &c, sizeof(unsigned char)); #ifndef WIN32 /* in MSDOS & Co. new line is \n+\r */ if( c == '\r' ) c = '\n'; #endif /* WIN32 */ m_unlock(&node->mux); return n <=0 ? EOF : (int)c; }
int bano_release(struct inode *inode, struct file *filp) { m_lock(&mutex); if (filp->f_mode & FMODE_WRITE) { int dv = iminor(filp->f_inode); if (dv == 0) { // Esta saliendo una dama printk("<1>close for write successful dama\n"); damas--; } else { // Esta saliendo un varon printk("<1>close for write successful varon\n"); varones--; } c_broadcast(&cond); } else if (filp->f_mode & FMODE_READ) { printk("<1>close for read \n"); } m_unlock(&mutex); return 0; }
off64_t dc_ftello64(FILE *fp) { off64_t rc; struct vsp_node *node; node = get_vsp_node(FILE_NO(fp)); if( node == NULL ) { return system_ftello64(fp); } if (fp == NULL) { return -1; } rc = dc_real_lseek( node, (off64_t)0, SEEK_CUR); m_unlock(&node->mux); return rc; }
int dc_fsync(int fd) { struct vsp_node *node; int rc; #ifdef DC_CALL_TRACE showTraceBack(); #endif node = get_vsp_node(fd); if( node == NULL ) { #ifdef WIN32 return _commit(fd); #else return system_fsync(fd); #endif /* WIN32 */ } rc = dc_real_fsync(node); m_unlock(&node->mux); return rc; }
ssize_t syncread_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { ssize_t rc; m_lock(&mutex); while (curr_size <= *f_pos && writing) { /* si el lector esta en el final del archivo pero hay un proceso * escribiendo todavia en el archivo, el lector espera. */ if (c_wait(&cond, &mutex)) { printk("<1>read interrupted\n"); rc= -EINTR; goto epilog; } } if (count > curr_size-*f_pos) { count= curr_size-*f_pos; } printk("<1>read %d bytes at %d\n", (int)count, (int)*f_pos); /* Transfiriendo datos hacia el espacio del usuario */ if (copy_to_user(buf, syncread_buffer+*f_pos, count)!=0) { /* el valor de buf es una direccion invalida */ rc= -EFAULT; goto epilog; } *f_pos+= count; rc= count; epilog: m_unlock(&mutex); return rc; }