/*===========================================================================* * fs_rdlink * *===========================================================================*/ int fs_rdlink() { block_t b; /* block containing link text */ struct buf *bp; /* buffer containing link text */ register struct inode *rip; /* target inode */ register int r; /* return value */ size_t copylen; copylen = min( (size_t) fs_m_in.REQ_MEM_SIZE, UMAX_FILE_POS); /* Temporarily open the file. */ if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); if(!S_ISLNK(rip->i_mode)) r = EACCES; else if ((b = read_map(rip, (off_t) 0)) == NO_BLOCK) r = EIO; else { /* Passed all checks */ /* We can safely cast to unsigned, because copylen is guaranteed to be below max file size */ copylen = min( copylen, (unsigned) rip->i_size); bp = get_block(rip->i_dev, b, NORMAL); r = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT, (vir_bytes) 0, (vir_bytes) b_data(bp), (size_t) copylen); put_block(bp, DIRECTORY_BLOCK); if (r == OK) fs_m_out.RES_NBYTES = copylen; } put_inode(rip); return(r); }
void parse_susp_rock_ridge_plcl(struct rrii_dir_record *dir, u32_t block) { struct inode *rep_inode; struct buf *bp; struct iso9660_dir_record *dir_rec; struct dir_extent extent; struct inode_dir_entry dummy_dir_entry; size_t dummy_offset = 0; /* Check if inode wasn't already parsed. */ rep_inode = inode_cache_get(block); if (rep_inode != NULL) { rep_inode->i_refcount++; dir->reparented_inode = rep_inode; return; } /* Peek ahead to build extent for read_inode. */ if (lmfs_get_block(&bp, fs_dev, block, NORMAL) != OK) return; dir_rec = (struct iso9660_dir_record*)b_data(bp); extent.location = block; extent.length = dir_rec->data_length_l / v_pri.logical_block_size_l; if (dir_rec->data_length_l % v_pri.logical_block_size_l) extent.length++; extent.next = NULL; lmfs_put_block(bp); memset(&dummy_dir_entry, 0, sizeof(struct inode_dir_entry)); read_inode(&dummy_dir_entry, &extent, &dummy_offset); free(dummy_dir_entry.r_name); dir->reparented_inode = dummy_dir_entry.i_node; }
/* Inserts <str> followed by "\r\n" at position <pos> relative to channel <c>'s * input head. The <len> argument informs about the length of string <str> so * that we don't have to measure it. <str> must be a valid pointer and must not * include the trailing "\r\n". * * The number of bytes added is returned on success. 0 is returned on failure. */ int ci_insert_line2(struct channel *c, int pos, const char *str, int len) { struct buffer *b = &c->buf; char *dst = c_ptr(c, pos); int delta; delta = len + 2; if (b_tail(b) + delta >= b_wrap(b)) return 0; /* no space left */ if (b_data(b) && b_tail(b) + delta > b_head(b) && b_head(b) >= b_tail(b)) return 0; /* no space left before wrapping data */ /* first, protect the end of the buffer */ memmove(dst + delta, dst, b_tail(b) - dst); /* now, copy str over dst */ memcpy(dst, str, len); dst[len] = '\r'; dst[len + 1] = '\n'; b_add(b, delta); return delta; }
static struct buf* fetch_inode(struct dir_extent *extent, size_t *offset) { struct iso9660_dir_record *dir_rec; struct buf *bp; /* * Directory entries aren't allowed to cross a logical block boundary in * ISO 9660, so we keep searching until we find something or reach the * end of the extent. */ bp = read_extent_block(extent, *offset / v_pri.logical_block_size_l); while (bp != NULL) { dir_rec = (struct iso9660_dir_record*)(b_data(bp) + *offset % v_pri.logical_block_size_l); if (dir_rec->length == 0) { *offset -= *offset % v_pri.logical_block_size_l; *offset += v_pri.logical_block_size_l; } else { break; } lmfs_put_block(bp, FULL_DATA_BLOCK); bp = read_extent_block(extent, *offset / v_pri.logical_block_size_l); } return bp; }
bool Support::compare_stage_data(pdal::Stage const& a, pdal::Stage const& b) { pdal::Schema const& a_schema = a.getSchema(); pdal::Schema const& b_schema = b.getSchema(); if (a_schema != b_schema) return false; boost::uint64_t a_num_points64 = a.getNumPoints(); boost::uint64_t b_num_points64 = b.getNumPoints(); if (a_num_points64 > std::numeric_limits<boost::uint32_t>::max() || b_num_points64 > std::numeric_limits<boost::uint32_t>::max()) throw pdal::pdal_error("unable to do compare_stage_data for > 2^32 points"); boost::uint32_t a_num_points = static_cast<boost::uint32_t>(a_num_points64); boost::uint32_t b_num_points = static_cast<boost::uint32_t>(b_num_points64); if (a_num_points != b_num_points) return false; // if we don't have any sizes here, we'll just use a small default if (a_num_points == 0) a_num_points = 1024; if (b_num_points == 0) b_num_points = 1024; pdal::PointBuffer a_data(a_schema, a_num_points); pdal::PointBuffer b_data(b_schema, b_num_points); pdal::StageSequentialIterator* a_itr = a.createSequentialIterator(a_data); pdal::StageSequentialIterator* b_itr = b.createSequentialIterator(b_data); if (!a_itr) throw pdal::pdal_error("unable to create sequential iterator for compare_stage_data for stage a"); if (!b_itr) throw pdal::pdal_error("unable to create sequential iterator for compare_stage_data for stage b"); { boost::uint32_t a_numRead = a_itr->read(a_data); boost::uint32_t b_numRead = b_itr->read(b_data); if (a_numRead != b_numRead) return false; boost::uint8_t const* a_bytes = a_data.getData(0); boost::uint8_t const* b_bytes = b_data.getData(0); boost::uint64_t a_length = a_data.getBufferByteLength(); // boost::uint64_t b_length = b_data.getBufferByteLength(); for (boost::uintmax_t i=0; i<a_length; i++) { if (*a_bytes != *b_bytes) { return false; } ++a_bytes; ++b_bytes; } } return true; }
void read_inode_susp(struct inode *i, const struct iso9660_dir_record *dir_rec, struct buf *bp, size_t offset) { int susp_offset, susp_size; struct rrii_dir_record rrii_data; susp_offset = 33 + dir_rec->length_file_id; /* Get rid of padding byte. */ if(dir_rec->length_file_id % 2 == 0) { susp_offset++; } if(dir_rec->length - susp_offset >= 4) { susp_size = dir_rec->length - susp_offset; /* Initialize record with known, sane data. */ memcpy(rrii_data.mtime, dir_rec->rec_date, ISO9660_SIZE_DATE7); memcpy(rrii_data.atime, dir_rec->rec_date, ISO9660_SIZE_DATE7); memcpy(rrii_data.ctime, dir_rec->rec_date, ISO9660_SIZE_DATE7); memcpy(rrii_data.birthtime, dir_rec->rec_date, ISO9660_SIZE_DATE7); rrii_data.d_mode = i->i_stat.st_mode; rrii_data.uid = 0; rrii_data.gid = 0; rrii_data.rdev = NO_DEV; rrii_data.file_id_rrip[0] = '\0'; rrii_data.slink_rrip[0] = '\0'; parse_susp_buffer(&rrii_data, b_data(bp)+offset+susp_offset, susp_size); /* Copy back data from rrii_dir_record structure. */ i->i_stat.st_atime = date7_to_time_t(rrii_data.atime); i->i_stat.st_ctime = date7_to_time_t(rrii_data.ctime); i->i_stat.st_mtime = date7_to_time_t(rrii_data.mtime); i->i_stat.st_birthtime = date7_to_time_t(rrii_data.birthtime); i->i_stat.st_mode = rrii_data.d_mode; i->i_stat.st_uid = rrii_data.uid; i->i_stat.st_gid = rrii_data.gid; i->i_stat.st_rdev = rrii_data.rdev; if (rrii_data.file_id_rrip[0] != '\0') strlcpy(i->i_name, rrii_data.file_id_rrip, sizeof(i->i_name)); if (rrii_data.slink_rrip[0] != '\0') strlcpy(i->s_link, rrii_data.slink_rrip, sizeof(i->s_link)); } }
virtual void init(Voxel& voxel) { voxel.fib_fa.clear(); voxel.fib_fa.resize(voxel.dim.size()); voxel.fib_dir.clear(); voxel.fib_dir.resize(voxel.dim.size()*3); md.clear(); md.resize(voxel.dim.size()); d0.clear(); d0.resize(voxel.dim.size()); d1.clear(); d1.resize(voxel.dim.size()); b_count = voxel.bvalues.size()-1; std::vector<image::vector<3> > b_data(b_count); //skip null std::copy(voxel.bvectors.begin()+1,voxel.bvectors.end(),b_data.begin()); for(unsigned int index = 0; index < b_count; ++index) b_data[index] *= std::sqrt(voxel.bvalues[index+1]); Kt.resize(6*b_count); { unsigned int qmap[6] = {0 ,4 ,8 ,1 ,2 ,5 }; double qweighting[6]= {1.0,1.0,1.0,2.0,2.0,2.0}; // bxx,byy,bzz,bxy,bxz,byz for (unsigned int i = 0,k = 0; i < b_data.size(); ++i,k+=6) { //qq = q qT std::vector<float> qq(3*3); image::matrix::product_transpose(b_data[i].begin(),b_data[i].begin(),qq.begin(), image::dyndim(3,1),image::dyndim(3,1)); /* q11 q15 q19 2*q12 2*q13 2*q16 q21 q25 q29 2*q22 2*q23 2*q26 K = | ... | */ for (unsigned int col = 0,index = i; col < 6; ++col,index+=b_count) Kt[index] = qq[qmap[col]]*qweighting[col]; } } iKtK.resize(6*6); iKtK_pivot.resize(6); image::matrix::product_transpose(Kt.begin(),Kt.begin(),iKtK.begin(), image::dyndim(6,b_count),image::dyndim(6,b_count)); image::matrix::lu_decomposition(iKtK.begin(),iKtK_pivot.begin(),image::dyndim(6,6)); }
/*===========================================================================* * fs_rdlink * *===========================================================================*/ int fs_rdlink() { struct buf *bp = NULL; /* buffer containing link text */ char* link_text; /* either bp->b_data or rip->i_block */ register struct inode *rip; /* target inode */ register int r; /* return value */ size_t copylen; copylen = min( (size_t) fs_m_in.REQ_MEM_SIZE, UMAX_FILE_POS); /* Temporarily open the file. */ if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); if (rip->i_size >= MAX_FAST_SYMLINK_LENGTH) { /* normal symlink */ if(!(bp = get_block_map(rip, 0))) { r = EIO; } else { link_text = b_data(bp); r = OK; } } else { /* fast symlink, stored in inode */ link_text = (char*) rip->i_block; r = OK; } if (r == OK) { /* Passed all checks */ /* We can safely cast to unsigned, because copylen is guaranteed to be below max file size */ copylen = min( copylen, (unsigned) rip->i_size); r = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT, (vir_bytes) 0, (vir_bytes) link_text, (size_t) copylen); put_block(bp, DIRECTORY_BLOCK); if (r == OK) fs_m_out.RES_NBYTES = copylen; } put_inode(rip); return(r); }
int read_inode(struct inode *i_node, struct dir_extent *extent, size_t offset, size_t *new_offset) { struct iso9660_dir_record *dir_rec; struct buf *bp; /* Find inode. */ bp = fetch_inode(extent, &offset); if (bp == NULL) return EOF; dir_rec = (struct iso9660_dir_record*)(b_data(bp) + offset % v_pri.logical_block_size_l); /* Parse basic ISO 9660 specs. */ if (check_dir_record(dir_rec, offset % v_pri.logical_block_size_l) != OK) { lmfs_put_block(bp, FULL_DATA_BLOCK); return EINVAL; } memset(&i_node->i_stat, 0, sizeof(struct stat)); i_node->i_stat.st_ino = get_extent_absolute_block_id(extent, offset / v_pri.logical_block_size_l) * v_pri.logical_block_size_l + offset % v_pri.logical_block_size_l; read_inode_iso9660(i_node, dir_rec); /* Parse extensions. */ read_inode_susp(i_node, dir_rec, bp, offset % v_pri.logical_block_size_l); offset += dir_rec->length; read_inode_extents(i_node, dir_rec, extent, &offset); lmfs_put_block(bp, FULL_DATA_BLOCK); if (new_offset != NULL) *new_offset = offset; return OK; }
/*===========================================================================* * fs_rdlink * *===========================================================================*/ ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes) { struct buf *bp = NULL; /* buffer containing link text */ char* link_text; /* either bp->b_data or rip->i_block */ register struct inode *rip; /* target inode */ register int r; /* return value */ /* Temporarily open the file. */ if( (rip = get_inode(fs_dev, ino_nr)) == NULL) return(EINVAL); if (rip->i_size >= MAX_FAST_SYMLINK_LENGTH) { /* normal symlink */ if(!(bp = get_block_map(rip, 0))) { r = EIO; } else { link_text = b_data(bp); r = OK; } } else { /* fast symlink, stored in inode */ link_text = (char*) rip->i_block; r = OK; } if (r == OK) { /* Passed all checks */ if (bytes > rip->i_size) bytes = rip->i_size; r = fsdriver_copyout(data, 0, link_text, bytes); put_block(bp, DIRECTORY_BLOCK); if (r == OK) r = bytes; } put_inode(rip); return(r); }
ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, off_t pos, int __unused call) { size_t off, chunk, block_size, cum_io; off_t f_size; struct inode *i_node; struct buf *bp; int r; /* Try to get inode according to its index. */ if ((i_node = find_inode(ino_nr)) == NULL) return EINVAL; /* No inode found. */ f_size = i_node->i_stat.st_size; if (pos >= f_size) return 0; /* EOF */ /* Limit the request to the remainder of the file size. */ if ((off_t)bytes > f_size - pos) bytes = (size_t)(f_size - pos); block_size = v_pri.logical_block_size_l; cum_io = 0; lmfs_reset_rdwt_err(); r = OK; /* Split the transfer into chunks that don't span two blocks. */ while (bytes > 0) { off = pos % block_size; chunk = block_size - off; if (chunk > bytes) chunk = bytes; /* Read 'chunk' bytes. */ bp = read_extent_block(i_node->extent, pos / block_size); if (bp == NULL) panic("bp not valid in rw_chunk; this can't happen"); r = fsdriver_copyout(data, cum_io, b_data(bp)+off, chunk); lmfs_put_block(bp, FULL_DATA_BLOCK); if (r != OK) break; /* EOF reached. */ if (lmfs_rdwt_err() < 0) break; /* Update counters and pointers. */ bytes -= chunk; /* Bytes yet to be read. */ cum_io += chunk; /* Bytes read so far. */ pos += chunk; /* Position within the file. */ } if (lmfs_rdwt_err() != OK) r = lmfs_rdwt_err(); /* Check for disk error. */ if (lmfs_rdwt_err() == END_OF_FILE) r = OK; return (r == OK) ? cum_io : r; }
/*===========================================================================* * fs_slink * *===========================================================================*/ int fs_slink() { phys_bytes len; struct inode *sip; /* inode containing symbolic link */ struct inode *ldirp; /* directory containing link */ register int r; /* error code */ char string[NAME_MAX]; /* last component of the new dir's path name */ char* link_target_buf = NULL; /* either sip->i_block or bp->b_data */ struct buf *bp = NULL; /* disk buffer for link */ caller_uid = (uid_t) fs_m_in.REQ_UID; caller_gid = (gid_t) fs_m_in.REQ_GID; /* Copy the link name's last component */ len = fs_m_in.REQ_PATH_LEN; if (len > NAME_MAX || len > EXT2_NAME_MAX) return(ENAMETOOLONG); r = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT, (vir_bytes) 0, (vir_bytes) string, (size_t) len); if (r != OK) return(r); NUL(string, len, sizeof(string)); /* Temporarily open the dir. */ if( (ldirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); /* Create the inode for the symlink. */ sip = new_node(ldirp, string, (mode_t) (I_SYMBOLIC_LINK | RWX_MODES), (block_t) 0); /* If we can then create fast symlink (store it in inode), * Otherwise allocate a disk block for the contents of the symlink and * copy contents of symlink (the name pointed to) into first disk block. */ if( (r = err_code) == OK) { if ( (fs_m_in.REQ_MEM_SIZE + 1) > sip->i_sp->s_block_size) { r = ENAMETOOLONG; } else if ((fs_m_in.REQ_MEM_SIZE + 1) <= MAX_FAST_SYMLINK_LENGTH) { r = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT3, (vir_bytes) 0, (vir_bytes) sip->i_block, (vir_bytes) fs_m_in.REQ_MEM_SIZE); sip->i_dirt = IN_DIRTY; link_target_buf = (char*) sip->i_block; } else { if ((bp = new_block(sip, (off_t) 0)) != NULL) { sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT3, (vir_bytes) 0, (vir_bytes) b_data(bp), (vir_bytes) fs_m_in.REQ_MEM_SIZE); lmfs_markdirty(bp); link_target_buf = b_data(bp); } else { r = err_code; } } if (r == OK) { assert(link_target_buf); link_target_buf[fs_m_in.REQ_MEM_SIZE] = '\0'; sip->i_size = (off_t) strlen(link_target_buf); if (sip->i_size != fs_m_in.REQ_MEM_SIZE) { /* This can happen if the user provides a buffer * with a \0 in it. This can cause a lot of trouble * when the symlink is used later. We could just use * the strlen() value, but we want to let the user * know he did something wrong. ENAMETOOLONG doesn't * exactly describe the error, but there is no * ENAMETOOWRONG. */ r = ENAMETOOLONG; } } put_block(bp, DIRECTORY_BLOCK); /* put_block() accepts NULL. */ if(r != OK) { sip->i_links_count = NO_LINK; if (search_dir(ldirp, string, NULL, DELETE, IGN_PERM, 0) != OK) panic("Symbolic link vanished"); } } /* put_inode() accepts NULL as a noop, so the below are safe. */ put_inode(sip); put_inode(ldirp); return(r); }
void read_inode_extents(struct inode *i, const struct iso9660_dir_record *dir_rec, struct dir_extent *extent, size_t *offset) { struct buf *bp; struct iso9660_dir_record *extent_rec; struct dir_extent *cur_extent = i->extent; int done = FALSE; /* * No need to search extents if file is empty or has final directory * record flag set. */ if (cur_extent == NULL || ((dir_rec->file_flags & D_NOT_LAST_EXTENT) == 0)) return; while (!done) { bp = fetch_inode(extent, offset); if (bp == NULL) return; bp = read_extent_block(extent, *offset / v_pri.logical_block_size_l); extent_rec = (struct iso9660_dir_record*)(b_data(bp) + *offset % v_pri.logical_block_size_l); if (check_dir_record(dir_rec, *offset % v_pri.logical_block_size_l) != OK) { lmfs_put_block(bp, FULL_DATA_BLOCK); return; } /* Extent entries should share the same name. */ if ((dir_rec->length_file_id == extent_rec->length_file_id) && (memcmp(dir_rec->file_id, extent_rec->file_id, dir_rec->length_file_id) == 0)) { /* Add the extent at the end of the linked list. */ assert(cur_extent->next == NULL); cur_extent->next = alloc_extent(); cur_extent->next->location = dir_rec->loc_extent_l + dir_rec->ext_attr_rec_length; cur_extent->next->length = dir_rec->data_length_l / v_pri.logical_block_size_l; if (dir_rec->data_length_l % v_pri.logical_block_size_l) cur_extent->next->length++; i->i_stat.st_size += dir_rec->data_length_l; i->i_stat.st_blocks += cur_extent->next->length; cur_extent = cur_extent->next; *offset += extent_rec->length; } else done = TRUE; /* Check if not last extent bit is not set. */ if ((dir_rec->file_flags & D_NOT_LAST_EXTENT) == 0) done = TRUE; lmfs_put_block(bp, FULL_DATA_BLOCK); } }
int parse_susp(struct rrii_dir_record *dir, char *buffer) { /* Parse fundamental SUSP entries */ char susp_signature[2]; u8_t susp_length; u8_t susp_version; u32_t ca_block_nr; u32_t ca_offset; u32_t ca_length; struct buf *ca_bp; susp_signature[0] = buffer[0]; susp_signature[1] = buffer[1]; susp_length = *((u8_t*)buffer + 2); susp_version = *((u8_t*)buffer + 3); if ((susp_signature[0] == 'C') && (susp_signature[1] == 'E') && (susp_length >= 28) && (susp_version >= 1)) { /* * Continuation area, perform a recursion. * * FIXME: Currently we're parsing only first logical block of a * continuation area, and infinite recursion is not checked. */ ca_block_nr = *((u32_t*)(buffer + 4)); ca_offset = *((u32_t*)(buffer + 12)); ca_length = *((u32_t*)(buffer + 20)); /* Truncate continuation area to fit one logical block. */ if (ca_offset >= v_pri.logical_block_size_l) { return EINVAL; } if (ca_offset + ca_length > v_pri.logical_block_size_l) { ca_length = v_pri.logical_block_size_l - ca_offset; } ca_bp = lmfs_get_block(fs_dev, ca_block_nr, NORMAL); if (ca_bp == NULL) { return EINVAL; } parse_susp_buffer(dir, b_data(ca_bp) + ca_offset, ca_length); lmfs_put_block(ca_bp, FULL_DATA_BLOCK); return OK; } else if ((susp_signature[0] == 'P') && (susp_signature[1] == 'D')) { /* Padding, skip. */ return OK; } else if ((susp_signature[0] == 'S') && (susp_signature[1] == 'P')) { /* Ignored, skip. */ return OK; } else if ((susp_signature[0] == 'S') && (susp_signature[1] == 'T')) { /* Terminator entry, stop processing. */ return(ECANCELED); } else if ((susp_signature[0] == 'E') && (susp_signature[1] == 'R')) { /* Ignored, skip. */ return OK; } else if ((susp_signature[0] == 'E') && (susp_signature[1] == 'S')) { /* Ignored, skip. */ return OK; } /* Not a SUSP fundamental entry. */ return EINVAL; }